Cleanup code using RegisterSymbol

This CL goes through and converts things which call RegisterSymbol to
use the helper builders. Several variables are also updated to use the
helper as it will need RegisterSymbol in the near future.

Change-Id: Ib5a8e8be54c1eaad123384fab09f6625421d9fcd
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/35880
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Commit-Queue: David Neto <dneto@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
Auto-Submit: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
dan sinclair 2020-12-16 21:38:40 +00:00 committed by Commit Bot service account
parent e5d288be5e
commit b5839939e1
66 changed files with 1912 additions and 4889 deletions

View File

@ -33,12 +33,14 @@
#include "src/ast/struct.h" #include "src/ast/struct.h"
#include "src/ast/struct_member.h" #include "src/ast/struct_member.h"
#include "src/ast/struct_member_offset_decoration.h" #include "src/ast/struct_member_offset_decoration.h"
#include "src/ast/type/alias_type.h"
#include "src/ast/type/array_type.h" #include "src/ast/type/array_type.h"
#include "src/ast/type/bool_type.h" #include "src/ast/type/bool_type.h"
#include "src/ast/type/f32_type.h" #include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h" #include "src/ast/type/i32_type.h"
#include "src/ast/type/matrix_type.h" #include "src/ast/type/matrix_type.h"
#include "src/ast/type/pointer_type.h" #include "src/ast/type/pointer_type.h"
#include "src/ast/type/struct_type.h"
#include "src/ast/type/u32_type.h" #include "src/ast/type/u32_type.h"
#include "src/ast/type/vector_type.h" #include "src/ast/type/vector_type.h"
#include "src/ast/type/void_type.h" #include "src/ast/type/void_type.h"
@ -159,6 +161,14 @@ class TypesBuilder {
return array(Of<T>(), N); return array(Of<T>(), N);
} }
/// Creates an alias type
/// @param name the alias name
/// @param type the alias type
/// @returns the alias pointer
type::Alias* alias(const std::string& name, type::Type* type) const {
return mod_->create<type::Alias>(mod_->RegisterSymbol(name), name, type);
}
/// @return the tint AST pointer to type `T` with the given StorageClass. /// @return the tint AST pointer to type `T` with the given StorageClass.
/// @param storage_class the storage class of the pointer /// @param storage_class the storage class of the pointer
template <typename T> template <typename T>
@ -166,6 +176,13 @@ class TypesBuilder {
return mod_->create<type::Pointer>(Of<T>(), storage_class); return mod_->create<type::Pointer>(Of<T>(), storage_class);
} }
/// @param name the struct name
/// @param impl the struct implementation
/// @returns a struct pointer
type::Struct* struct_(const std::string& name, ast::Struct* impl) const {
return mod_->create<type::Struct>(mod_->RegisterSymbol(name), name, impl);
}
private: private:
/// CToAST<T> is specialized for various `T` types and each specialization /// CToAST<T> is specialized for various `T` types and each specialization
/// contains a single static `get()` method for obtaining the corresponding /// contains a single static `get()` method for obtaining the corresponding
@ -213,6 +230,14 @@ class Builder {
return create<IdentifierExpression>(mod->RegisterSymbol(name), name); return create<IdentifierExpression>(mod->RegisterSymbol(name), name);
} }
/// @param source the source information
/// @param name the identifier name
/// @return an IdentifierExpression with the given name
IdentifierExpression* Expr(const Source& source, const std::string& name) {
return create<IdentifierExpression>(source, mod->RegisterSymbol(name),
name);
}
/// @param name the identifier name /// @param name the identifier name
/// @return an IdentifierExpression with the given name /// @return an IdentifierExpression with the given name
IdentifierExpression* Expr(const char* name) { IdentifierExpression* Expr(const char* name) {
@ -617,6 +642,18 @@ class Builder {
decorations); decorations);
} }
/// Creates a StructMember
/// @param source the source information
/// @param name the struct member name
/// @param type the struct member type
/// @returns the struct member pointer
StructMember* Member(const Source& source,
const std::string& name,
type::Type* type) {
return mod->create<StructMember>(source, mod->RegisterSymbol(name), name,
type, StructMemberDecorationList{});
}
/// Creates a StructMember /// Creates a StructMember
/// @param name the struct member name /// @param name the struct member name
/// @param type the struct member type /// @param type the struct member type

View File

@ -41,11 +41,11 @@ TEST_F(ExpressionTest, set_result_type) {
} }
TEST_F(ExpressionTest, set_result_type_alias) { TEST_F(ExpressionTest, set_result_type_alias) {
type::Alias a(mod->RegisterSymbol("a"), "a", ty.i32); auto* a = ty.alias("a", ty.i32);
type::Alias b(mod->RegisterSymbol("b"), "b", &a); auto* b = ty.alias("b", a);
FakeExpr e; FakeExpr e;
e.set_result_type(&b); e.set_result_type(b);
ASSERT_NE(e.result_type(), nullptr); ASSERT_NE(e.result_type(), nullptr);
EXPECT_TRUE(e.result_type()->Is<type::I32>()); EXPECT_TRUE(e.result_type()->Is<type::I32>());
} }

View File

@ -29,16 +29,13 @@ namespace {
using FunctionTest = TestHelper; using FunctionTest = TestHelper;
TEST_F(FunctionTest, Creation) { TEST_F(FunctionTest, Creation) {
auto func_sym = mod->RegisterSymbol("func");
VariableList params; VariableList params;
params.push_back(Var("var", StorageClass::kNone, ty.i32)); params.push_back(Var("var", StorageClass::kNone, ty.i32));
auto* var = params[0]; auto* var = params[0];
auto* f = create<Function>(func_sym, "func", params, ty.void_, auto* f =
create<BlockStatement>(StatementList{}), Func("func", params, ty.void_, StatementList{}, FunctionDecorationList{});
FunctionDecorationList{}); EXPECT_EQ(f->symbol(), mod->RegisterSymbol("func"));
EXPECT_EQ(f->symbol(), func_sym);
EXPECT_EQ(f->name(), "func"); EXPECT_EQ(f->name(), "func");
ASSERT_EQ(f->params().size(), 1u); ASSERT_EQ(f->params().size(), 1u);
EXPECT_EQ(f->return_type(), ty.void_); EXPECT_EQ(f->return_type(), ty.void_);
@ -46,25 +43,19 @@ TEST_F(FunctionTest, Creation) {
} }
TEST_F(FunctionTest, Creation_WithSource) { TEST_F(FunctionTest, Creation_WithSource) {
auto func_sym = mod->RegisterSymbol("func");
VariableList params; VariableList params;
params.push_back(Var("var", StorageClass::kNone, ty.i32)); params.push_back(Var("var", StorageClass::kNone, ty.i32));
auto* f = create<Function>( auto* f = Func(Source{Source::Location{20, 2}}, "func", params, ty.void_,
Source{Source::Location{20, 2}}, func_sym, "func", params, ty.void_, StatementList{}, FunctionDecorationList{});
create<BlockStatement>(StatementList{}), FunctionDecorationList{});
auto src = f->source(); auto src = f->source();
EXPECT_EQ(src.range.begin.line, 20u); EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u); EXPECT_EQ(src.range.begin.column, 2u);
} }
TEST_F(FunctionTest, AddDuplicateReferencedVariables) { TEST_F(FunctionTest, AddDuplicateReferencedVariables) {
auto func_sym = mod->RegisterSymbol("func");
auto* v = Var("var", StorageClass::kInput, ty.i32); auto* v = Var("var", StorageClass::kInput, ty.i32);
auto* f = create<Function>(func_sym, "func", VariableList{}, ty.void_, auto* f = Func("func", VariableList{}, ty.void_, StatementList{},
create<BlockStatement>(StatementList{}),
FunctionDecorationList{}); FunctionDecorationList{});
f->add_referenced_module_variable(v); f->add_referenced_module_variable(v);
@ -81,8 +72,6 @@ TEST_F(FunctionTest, AddDuplicateReferencedVariables) {
} }
TEST_F(FunctionTest, GetReferenceLocations) { TEST_F(FunctionTest, GetReferenceLocations) {
auto func_sym = mod->RegisterSymbol("func");
auto* loc1 = Var("loc1", StorageClass::kInput, ty.i32, nullptr, auto* loc1 = Var("loc1", StorageClass::kInput, ty.i32, nullptr,
ast::VariableDecorationList{ ast::VariableDecorationList{
create<LocationDecoration>(0), create<LocationDecoration>(0),
@ -103,8 +92,7 @@ TEST_F(FunctionTest, GetReferenceLocations) {
create<BuiltinDecoration>(Builtin::kFragDepth), create<BuiltinDecoration>(Builtin::kFragDepth),
}); });
auto* f = create<Function>(func_sym, "func", VariableList{}, ty.void_, auto* f = Func("func", VariableList{}, ty.void_, StatementList{},
create<BlockStatement>(StatementList{}),
FunctionDecorationList{}); FunctionDecorationList{});
f->add_referenced_module_variable(loc1); f->add_referenced_module_variable(loc1);
@ -122,8 +110,6 @@ TEST_F(FunctionTest, GetReferenceLocations) {
} }
TEST_F(FunctionTest, GetReferenceBuiltins) { TEST_F(FunctionTest, GetReferenceBuiltins) {
auto func_sym = mod->RegisterSymbol("func");
auto* loc1 = Var("loc1", StorageClass::kInput, ty.i32, nullptr, auto* loc1 = Var("loc1", StorageClass::kInput, ty.i32, nullptr,
ast::VariableDecorationList{ ast::VariableDecorationList{
create<LocationDecoration>(0), create<LocationDecoration>(0),
@ -144,8 +130,7 @@ TEST_F(FunctionTest, GetReferenceBuiltins) {
create<BuiltinDecoration>(Builtin::kFragDepth), create<BuiltinDecoration>(Builtin::kFragDepth),
}); });
auto* f = create<Function>(func_sym, "func", VariableList{}, ty.void_, auto* f = Func("func", VariableList{}, ty.void_, StatementList{},
create<BlockStatement>(StatementList{}),
FunctionDecorationList{}); FunctionDecorationList{});
f->add_referenced_module_variable(loc1); f->add_referenced_module_variable(loc1);
@ -163,13 +148,10 @@ TEST_F(FunctionTest, GetReferenceBuiltins) {
} }
TEST_F(FunctionTest, AddDuplicateEntryPoints) { TEST_F(FunctionTest, AddDuplicateEntryPoints) {
auto func_sym = mod->RegisterSymbol("func"); auto* f = Func("func", VariableList{}, ty.void_, StatementList{},
auto main_sym = mod->RegisterSymbol("main");
auto* f = create<Function>(func_sym, "func", VariableList{}, ty.void_,
create<BlockStatement>(StatementList{}),
FunctionDecorationList{}); FunctionDecorationList{});
auto main_sym = mod->RegisterSymbol("main");
f->add_ancestor_entry_point(main_sym); f->add_ancestor_entry_point(main_sym);
ASSERT_EQ(1u, f->ancestor_entry_points().size()); ASSERT_EQ(1u, f->ancestor_entry_points().size());
EXPECT_EQ(main_sym, f->ancestor_entry_points()[0]); EXPECT_EQ(main_sym, f->ancestor_entry_points()[0]);
@ -180,110 +162,86 @@ TEST_F(FunctionTest, AddDuplicateEntryPoints) {
} }
TEST_F(FunctionTest, IsValid) { TEST_F(FunctionTest, IsValid) {
auto func_sym = mod->RegisterSymbol("func");
VariableList params; VariableList params;
params.push_back(Var("var", StorageClass::kNone, ty.i32)); params.push_back(Var("var", StorageClass::kNone, ty.i32));
auto* body = create<BlockStatement>(StatementList{ auto* f = Func("func", params, ty.void_,
StatementList{
create<DiscardStatement>(), create<DiscardStatement>(),
}); },
auto* f = create<Function>(func_sym, "func", params, ty.void_, body,
FunctionDecorationList{}); FunctionDecorationList{});
EXPECT_TRUE(f->IsValid()); EXPECT_TRUE(f->IsValid());
} }
TEST_F(FunctionTest, IsValid_InvalidName) { TEST_F(FunctionTest, IsValid_InvalidName) {
auto func_sym = mod->RegisterSymbol("");
VariableList params; VariableList params;
params.push_back(Var("var", StorageClass::kNone, ty.i32)); params.push_back(Var("var", StorageClass::kNone, ty.i32));
auto* f = create<Function>(func_sym, "", params, ty.void_, auto* f =
create<BlockStatement>(StatementList{}), Func("", params, ty.void_, StatementList{}, FunctionDecorationList{});
FunctionDecorationList{});
EXPECT_FALSE(f->IsValid()); EXPECT_FALSE(f->IsValid());
} }
TEST_F(FunctionTest, IsValid_MissingReturnType) { TEST_F(FunctionTest, IsValid_MissingReturnType) {
auto func_sym = mod->RegisterSymbol("func");
VariableList params; VariableList params;
params.push_back(Var("var", StorageClass::kNone, ty.i32)); params.push_back(Var("var", StorageClass::kNone, ty.i32));
auto* f = create<Function>(func_sym, "func", params, nullptr, auto* f =
create<BlockStatement>(StatementList{}), Func("func", params, nullptr, StatementList{}, FunctionDecorationList{});
FunctionDecorationList{});
EXPECT_FALSE(f->IsValid()); EXPECT_FALSE(f->IsValid());
} }
TEST_F(FunctionTest, IsValid_NullParam) { TEST_F(FunctionTest, IsValid_NullParam) {
auto func_sym = mod->RegisterSymbol("func");
VariableList params; VariableList params;
params.push_back(Var("var", StorageClass::kNone, ty.i32)); params.push_back(Var("var", StorageClass::kNone, ty.i32));
params.push_back(nullptr); params.push_back(nullptr);
auto* f = create<Function>(func_sym, "func", params, ty.void_, auto* f =
create<BlockStatement>(StatementList{}), Func("func", params, ty.void_, StatementList{}, FunctionDecorationList{});
FunctionDecorationList{});
EXPECT_FALSE(f->IsValid()); EXPECT_FALSE(f->IsValid());
} }
TEST_F(FunctionTest, IsValid_InvalidParam) { TEST_F(FunctionTest, IsValid_InvalidParam) {
auto func_sym = mod->RegisterSymbol("func");
VariableList params; VariableList params;
params.push_back(Var("var", StorageClass::kNone, nullptr)); params.push_back(Var("var", StorageClass::kNone, nullptr));
auto* f = create<Function>(func_sym, "func", params, ty.void_, auto* f =
create<BlockStatement>(StatementList{}), Func("func", params, ty.void_, StatementList{}, FunctionDecorationList{});
FunctionDecorationList{});
EXPECT_FALSE(f->IsValid()); EXPECT_FALSE(f->IsValid());
} }
TEST_F(FunctionTest, IsValid_NullBodyStatement) { TEST_F(FunctionTest, IsValid_NullBodyStatement) {
auto func_sym = mod->RegisterSymbol("func");
VariableList params; VariableList params;
params.push_back(Var("var", StorageClass::kNone, ty.i32)); params.push_back(Var("var", StorageClass::kNone, ty.i32));
auto* body = create<BlockStatement>(StatementList{ auto* f = Func("func", params, ty.void_,
StatementList{
create<DiscardStatement>(), create<DiscardStatement>(),
nullptr, nullptr,
}); },
auto* f = create<Function>(func_sym, "func", params, ty.void_, body,
FunctionDecorationList{}); FunctionDecorationList{});
EXPECT_FALSE(f->IsValid()); EXPECT_FALSE(f->IsValid());
} }
TEST_F(FunctionTest, IsValid_InvalidBodyStatement) { TEST_F(FunctionTest, IsValid_InvalidBodyStatement) {
auto func_sym = mod->RegisterSymbol("func");
VariableList params; VariableList params;
params.push_back(Var("var", StorageClass::kNone, ty.i32)); params.push_back(Var("var", StorageClass::kNone, ty.i32));
auto* body = create<BlockStatement>(StatementList{ auto* f = Func("func", params, ty.void_,
StatementList{
create<DiscardStatement>(), create<DiscardStatement>(),
nullptr, nullptr,
}); },
auto* f = create<Function>(func_sym, "func", params, ty.void_, body,
FunctionDecorationList{}); FunctionDecorationList{});
EXPECT_FALSE(f->IsValid()); EXPECT_FALSE(f->IsValid());
} }
TEST_F(FunctionTest, ToStr) { TEST_F(FunctionTest, ToStr) {
auto func_sym = mod->RegisterSymbol("func"); auto* f = Func("func", VariableList{}, ty.void_,
StatementList{
auto* body = create<BlockStatement>(StatementList{
create<DiscardStatement>(), create<DiscardStatement>(),
}); },
auto* f = create<Function>(func_sym, "func", VariableList{}, ty.void_, body,
FunctionDecorationList{}); FunctionDecorationList{});
std::ostringstream out; std::ostringstream out;
@ -297,13 +255,10 @@ TEST_F(FunctionTest, ToStr) {
} }
TEST_F(FunctionTest, ToStr_WithDecoration) { TEST_F(FunctionTest, ToStr_WithDecoration) {
auto func_sym = mod->RegisterSymbol("func"); auto* f = Func("func", VariableList{}, ty.void_,
StatementList{
auto* body = create<BlockStatement>(StatementList{
create<DiscardStatement>(), create<DiscardStatement>(),
}); },
auto* f = create<Function>(
func_sym, "func", VariableList{}, ty.void_, body,
FunctionDecorationList{create<WorkgroupDecoration>(2, 4, 6)}); FunctionDecorationList{create<WorkgroupDecoration>(2, 4, 6)});
std::ostringstream out; std::ostringstream out;
@ -318,15 +273,13 @@ TEST_F(FunctionTest, ToStr_WithDecoration) {
} }
TEST_F(FunctionTest, ToStr_WithParams) { TEST_F(FunctionTest, ToStr_WithParams) {
auto func_sym = mod->RegisterSymbol("func");
VariableList params; VariableList params;
params.push_back(Var("var", StorageClass::kNone, ty.i32)); params.push_back(Var("var", StorageClass::kNone, ty.i32));
auto* body = create<BlockStatement>(StatementList{ auto* f = Func("func", params, ty.void_,
StatementList{
create<DiscardStatement>(), create<DiscardStatement>(),
}); },
auto* f = create<Function>(func_sym, "func", params, ty.void_, body,
FunctionDecorationList{}); FunctionDecorationList{});
std::ostringstream out; std::ostringstream out;
@ -346,55 +299,40 @@ TEST_F(FunctionTest, ToStr_WithParams) {
} }
TEST_F(FunctionTest, TypeName) { TEST_F(FunctionTest, TypeName) {
auto func_sym = mod->RegisterSymbol("func"); auto* f = Func("func", VariableList{}, ty.void_, StatementList{},
auto* f = create<Function>(func_sym, "func", VariableList{}, ty.void_,
create<BlockStatement>(StatementList{}),
FunctionDecorationList{}); FunctionDecorationList{});
EXPECT_EQ(f->type_name(), "__func__void"); EXPECT_EQ(f->type_name(), "__func__void");
} }
TEST_F(FunctionTest, TypeName_WithParams) { TEST_F(FunctionTest, TypeName_WithParams) {
auto func_sym = mod->RegisterSymbol("func");
VariableList params; VariableList params;
params.push_back(Var("var1", StorageClass::kNone, ty.i32)); params.push_back(Var("var1", StorageClass::kNone, ty.i32));
params.push_back(Var("var2", StorageClass::kNone, ty.f32)); params.push_back(Var("var2", StorageClass::kNone, ty.f32));
auto* f = create<Function>(func_sym, "func", params, ty.void_, auto* f =
create<BlockStatement>(StatementList{}), Func("func", params, ty.void_, StatementList{}, FunctionDecorationList{});
FunctionDecorationList{});
EXPECT_EQ(f->type_name(), "__func__void__i32__f32"); EXPECT_EQ(f->type_name(), "__func__void__i32__f32");
} }
TEST_F(FunctionTest, GetLastStatement) { TEST_F(FunctionTest, GetLastStatement) {
auto func_sym = mod->RegisterSymbol("func");
VariableList params; VariableList params;
auto* stmt = create<DiscardStatement>(); auto* stmt = create<DiscardStatement>();
auto* body = create<BlockStatement>(StatementList{stmt}); auto* f = Func("func", params, ty.void_, StatementList{stmt},
auto* f = create<Function>(func_sym, "func", params, ty.void_, body,
FunctionDecorationList{}); FunctionDecorationList{});
EXPECT_EQ(f->get_last_statement(), stmt); EXPECT_EQ(f->get_last_statement(), stmt);
} }
TEST_F(FunctionTest, GetLastStatement_nullptr) { TEST_F(FunctionTest, GetLastStatement_nullptr) {
auto func_sym = mod->RegisterSymbol("func");
VariableList params; VariableList params;
auto* body = create<BlockStatement>(StatementList{}); auto* f =
auto* f = create<Function>(func_sym, "func", params, ty.void_, body, Func("func", params, ty.void_, StatementList{}, FunctionDecorationList{});
FunctionDecorationList{});
EXPECT_EQ(f->get_last_statement(), nullptr); EXPECT_EQ(f->get_last_statement(), nullptr);
} }
TEST_F(FunctionTest, WorkgroupSize_NoneSet) { TEST_F(FunctionTest, WorkgroupSize_NoneSet) {
auto func_sym = mod->RegisterSymbol("func"); auto* f = Func("func", VariableList{}, ty.void_, StatementList{},
auto* f = create<Function>(func_sym, "func", VariableList{}, ty.void_,
create<BlockStatement>(StatementList{}),
FunctionDecorationList{}); FunctionDecorationList{});
uint32_t x = 0; uint32_t x = 0;
uint32_t y = 0; uint32_t y = 0;
@ -406,11 +344,8 @@ TEST_F(FunctionTest, WorkgroupSize_NoneSet) {
} }
TEST_F(FunctionTest, WorkgroupSize) { TEST_F(FunctionTest, WorkgroupSize) {
auto func_sym = mod->RegisterSymbol("func"); auto* f =
Func("func", VariableList{}, ty.void_, StatementList{},
auto* f = create<Function>(
func_sym, "func", VariableList{}, ty.void_,
create<BlockStatement>(StatementList{}),
FunctionDecorationList{create<WorkgroupDecoration>(2u, 4u, 6u)}); FunctionDecorationList{create<WorkgroupDecoration>(2u, 4u, 6u)});
uint32_t x = 0; uint32_t x = 0;

View File

@ -29,8 +29,7 @@ TEST_F(IdentifierExpressionTest, Creation) {
} }
TEST_F(IdentifierExpressionTest, Creation_WithSource) { TEST_F(IdentifierExpressionTest, Creation_WithSource) {
auto* i = create<IdentifierExpression>(Source{Source::Location{20, 2}}, auto* i = Expr(Source{Source::Location{20, 2}}, "ident");
mod->RegisterSymbol("ident"), "ident");
EXPECT_EQ(i->symbol(), Symbol(1)); EXPECT_EQ(i->symbol(), Symbol(1));
EXPECT_EQ(i->name(), "ident"); EXPECT_EQ(i->name(), "ident");

View File

@ -56,8 +56,7 @@ TEST_F(IfStatementTest, IsValid_WithElseStatements) {
auto* stmt = create<IfStatement>( auto* stmt = create<IfStatement>(
cond, body, cond, body,
ElseStatementList{ ElseStatementList{
create<ElseStatement>(create<IdentifierExpression>( create<ElseStatement>(Expr("Ident"),
mod->RegisterSymbol("Ident"), "Ident"),
create<BlockStatement>(StatementList{})), create<BlockStatement>(StatementList{})),
create<ElseStatement>(nullptr, create<ElseStatement>(nullptr,
create<BlockStatement>(StatementList{})), create<BlockStatement>(StatementList{})),
@ -110,8 +109,7 @@ TEST_F(IfStatementTest, IsValid_NullElseStatement) {
auto* stmt = create<IfStatement>( auto* stmt = create<IfStatement>(
cond, body, cond, body,
ElseStatementList{ ElseStatementList{
create<ElseStatement>(create<IdentifierExpression>( create<ElseStatement>(Expr("Ident"),
mod->RegisterSymbol("Ident"), "Ident"),
create<BlockStatement>(StatementList{})), create<BlockStatement>(StatementList{})),
create<ElseStatement>(nullptr, create<ElseStatement>(nullptr,
create<BlockStatement>(StatementList{})), create<BlockStatement>(StatementList{})),
@ -157,8 +155,7 @@ TEST_F(IfStatementTest, IsValid_ElseNotLast) {
ElseStatementList{ ElseStatementList{
create<ElseStatement>(nullptr, create<ElseStatement>(nullptr,
create<BlockStatement>(StatementList{})), create<BlockStatement>(StatementList{})),
create<ElseStatement>(create<IdentifierExpression>( create<ElseStatement>(Expr("Ident"),
mod->RegisterSymbol("Ident"), "Ident"),
create<BlockStatement>(StatementList{})), create<BlockStatement>(StatementList{})),
}); });
EXPECT_FALSE(stmt->IsValid()); EXPECT_FALSE(stmt->IsValid());
@ -194,9 +191,7 @@ TEST_F(IfStatementTest, ToStr_WithElseStatements) {
auto* stmt = create<IfStatement>( auto* stmt = create<IfStatement>(
cond, body, cond, body,
ElseStatementList{ ElseStatementList{
create<ElseStatement>(create<IdentifierExpression>( create<ElseStatement>(Expr("ident"), else_if_body),
mod->RegisterSymbol("ident"), "ident"),
else_if_body),
create<ElseStatement>(nullptr, else_body), create<ElseStatement>(nullptr, else_body),
}); });

View File

@ -26,8 +26,7 @@ namespace {
using MemberAccessorExpressionTest = TestHelper; using MemberAccessorExpressionTest = TestHelper;
TEST_F(MemberAccessorExpressionTest, Creation) { TEST_F(MemberAccessorExpressionTest, Creation) {
auto* str = create<IdentifierExpression>(mod->RegisterSymbol("structure"), auto* str = Expr("structure");
"structure");
auto* mem = Expr("member"); auto* mem = Expr("member");
auto* stmt = create<MemberAccessorExpression>(str, mem); auto* stmt = create<MemberAccessorExpression>(str, mem);
@ -36,73 +35,48 @@ TEST_F(MemberAccessorExpressionTest, Creation) {
} }
TEST_F(MemberAccessorExpressionTest, Creation_WithSource) { TEST_F(MemberAccessorExpressionTest, Creation_WithSource) {
auto* str = create<IdentifierExpression>(mod->RegisterSymbol("structure"), auto* stmt = create<MemberAccessorExpression>(
"structure"); Source{Source::Location{20, 2}}, Expr("structure"), Expr("member"));
auto* mem = Expr("member");
auto* stmt = create<MemberAccessorExpression>(Source{Source::Location{20, 2}},
str, mem);
auto src = stmt->source(); auto src = stmt->source();
EXPECT_EQ(src.range.begin.line, 20u); EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u); EXPECT_EQ(src.range.begin.column, 2u);
} }
TEST_F(MemberAccessorExpressionTest, IsMemberAccessor) { TEST_F(MemberAccessorExpressionTest, IsMemberAccessor) {
auto* str = create<IdentifierExpression>(mod->RegisterSymbol("structure"), auto* stmt =
"structure"); create<MemberAccessorExpression>(Expr("structure"), Expr("member"));
auto* mem = Expr("member");
auto* stmt = create<MemberAccessorExpression>(str, mem);
EXPECT_TRUE(stmt->Is<MemberAccessorExpression>()); EXPECT_TRUE(stmt->Is<MemberAccessorExpression>());
} }
TEST_F(MemberAccessorExpressionTest, IsValid) { TEST_F(MemberAccessorExpressionTest, IsValid) {
auto* str = create<IdentifierExpression>(mod->RegisterSymbol("structure"), auto* stmt =
"structure"); create<MemberAccessorExpression>(Expr("structure"), Expr("member"));
auto* mem = Expr("member");
auto* stmt = create<MemberAccessorExpression>(str, mem);
EXPECT_TRUE(stmt->IsValid()); EXPECT_TRUE(stmt->IsValid());
} }
TEST_F(MemberAccessorExpressionTest, IsValid_NullStruct) { TEST_F(MemberAccessorExpressionTest, IsValid_NullStruct) {
auto* mem = Expr("member"); auto* stmt = create<MemberAccessorExpression>(nullptr, Expr("member"));
auto* stmt = create<MemberAccessorExpression>(nullptr, mem);
EXPECT_FALSE(stmt->IsValid()); EXPECT_FALSE(stmt->IsValid());
} }
TEST_F(MemberAccessorExpressionTest, IsValid_InvalidStruct) { TEST_F(MemberAccessorExpressionTest, IsValid_InvalidStruct) {
auto* str = Expr(""); auto* stmt = create<MemberAccessorExpression>(Expr(""), Expr("member"));
auto* mem = Expr("member");
auto* stmt = create<MemberAccessorExpression>(str, mem);
EXPECT_FALSE(stmt->IsValid()); EXPECT_FALSE(stmt->IsValid());
} }
TEST_F(MemberAccessorExpressionTest, IsValid_NullMember) { TEST_F(MemberAccessorExpressionTest, IsValid_NullMember) {
auto* str = create<IdentifierExpression>(mod->RegisterSymbol("structure"), auto* stmt = create<MemberAccessorExpression>(Expr("structure"), nullptr);
"structure");
auto* stmt = create<MemberAccessorExpression>(str, nullptr);
EXPECT_FALSE(stmt->IsValid()); EXPECT_FALSE(stmt->IsValid());
} }
TEST_F(MemberAccessorExpressionTest, IsValid_InvalidMember) { TEST_F(MemberAccessorExpressionTest, IsValid_InvalidMember) {
auto* str = create<IdentifierExpression>(mod->RegisterSymbol("structure"), auto* stmt = create<MemberAccessorExpression>(Expr("structure"), Expr(""));
"structure");
auto* mem = Expr("");
auto* stmt = create<MemberAccessorExpression>(str, mem);
EXPECT_FALSE(stmt->IsValid()); EXPECT_FALSE(stmt->IsValid());
} }
TEST_F(MemberAccessorExpressionTest, ToStr) { TEST_F(MemberAccessorExpressionTest, ToStr) {
auto* str = create<IdentifierExpression>(mod->RegisterSymbol("structure"), auto* stmt =
"structure"); create<MemberAccessorExpression>(Expr("structure"), Expr("member"));
auto* mem = Expr("member");
auto* stmt = create<MemberAccessorExpression>(str, mem);
std::ostringstream out; std::ostringstream out;
stmt->to_str(out, 2); stmt->to_str(out, 2);
EXPECT_EQ(demangle(out.str()), R"( MemberAccessor[not set]{ EXPECT_EQ(demangle(out.str()), R"( MemberAccessor[not set]{

View File

@ -32,122 +32,91 @@ namespace {
using ModuleTest = TestHelper; using ModuleTest = TestHelper;
TEST_F(ModuleTest, Creation) { TEST_F(ModuleTest, Creation) {
Module m; EXPECT_EQ(mod->functions().size(), 0u);
EXPECT_EQ(m.functions().size(), 0u);
} }
TEST_F(ModuleTest, ToStrEmitsPreambleAndPostamble) { TEST_F(ModuleTest, ToStrEmitsPreambleAndPostamble) {
Module m; const auto str = mod->to_str();
const auto str = m.to_str();
auto* const expected = "Module{\n}\n"; auto* const expected = "Module{\n}\n";
EXPECT_EQ(str, expected); EXPECT_EQ(str, expected);
} }
TEST_F(ModuleTest, LookupFunction) { TEST_F(ModuleTest, LookupFunction) {
Module m; auto* func = Func("main", VariableList{}, ty.f32, StatementList{},
auto func_sym = m.RegisterSymbol("main");
auto* func = create<Function>(func_sym, "main", VariableList{}, ty.f32,
create<BlockStatement>(StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
m.AddFunction(func); mod->AddFunction(func);
EXPECT_EQ(func, m.FindFunctionBySymbol(func_sym)); EXPECT_EQ(func, mod->FindFunctionBySymbol(mod->RegisterSymbol("main")));
} }
TEST_F(ModuleTest, LookupFunctionMissing) { TEST_F(ModuleTest, LookupFunctionMissing) {
Module m; EXPECT_EQ(nullptr, mod->FindFunctionBySymbol(mod->RegisterSymbol("Missing")));
EXPECT_EQ(nullptr, m.FindFunctionBySymbol(m.RegisterSymbol("Missing")));
} }
TEST_F(ModuleTest, IsValid_Empty) { TEST_F(ModuleTest, IsValid_Empty) {
Module m; EXPECT_TRUE(mod->IsValid());
EXPECT_TRUE(m.IsValid());
} }
TEST_F(ModuleTest, IsValid_GlobalVariable) { TEST_F(ModuleTest, IsValid_GlobalVariable) {
auto* var = create<Variable>("var", StorageClass::kInput, ty.f32, false, auto* var = Var("var", StorageClass::kInput, ty.f32);
nullptr, ast::VariableDecorationList{}); mod->AddGlobalVariable(var);
EXPECT_TRUE(mod->IsValid());
Module m;
m.AddGlobalVariable(var);
EXPECT_TRUE(m.IsValid());
} }
TEST_F(ModuleTest, IsValid_Null_GlobalVariable) { TEST_F(ModuleTest, IsValid_Null_GlobalVariable) {
Module m; mod->AddGlobalVariable(nullptr);
m.AddGlobalVariable(nullptr); EXPECT_FALSE(mod->IsValid());
EXPECT_FALSE(m.IsValid());
} }
TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) { TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) {
auto* var = create<Variable>("var", StorageClass::kInput, nullptr, false, auto* var = Var("var", StorageClass::kInput, nullptr);
nullptr, ast::VariableDecorationList{}); mod->AddGlobalVariable(var);
EXPECT_FALSE(mod->IsValid());
Module m;
m.AddGlobalVariable(var);
EXPECT_FALSE(m.IsValid());
} }
TEST_F(ModuleTest, IsValid_Alias) { TEST_F(ModuleTest, IsValid_Alias) {
type::Alias alias(mod->RegisterSymbol("alias"), "alias", ty.f32); auto* alias = ty.alias("alias", ty.f32);
mod->AddConstructedType(alias);
Module m; EXPECT_TRUE(mod->IsValid());
m.AddConstructedType(&alias);
EXPECT_TRUE(m.IsValid());
} }
TEST_F(ModuleTest, IsValid_Null_Alias) { TEST_F(ModuleTest, IsValid_Null_Alias) {
Module m; mod->AddConstructedType(nullptr);
m.AddConstructedType(nullptr); EXPECT_FALSE(mod->IsValid());
EXPECT_FALSE(m.IsValid());
} }
TEST_F(ModuleTest, IsValid_Struct) { TEST_F(ModuleTest, IsValid_Struct) {
type::Struct st(mod->RegisterSymbol("name"), "name", {}); auto* st = ty.struct_("name", {});
type::Alias alias(mod->RegisterSymbol("name"), "name", &st); auto* alias = ty.alias("name", st);
mod->AddConstructedType(alias);
Module m; EXPECT_TRUE(mod->IsValid());
m.AddConstructedType(&alias);
EXPECT_TRUE(m.IsValid());
} }
TEST_F(ModuleTest, IsValid_Struct_EmptyName) { TEST_F(ModuleTest, IsValid_Struct_EmptyName) {
type::Struct st(mod->RegisterSymbol(""), "", {}); auto* st = ty.struct_("", {});
type::Alias alias(mod->RegisterSymbol("name"), "name", &st); auto* alias = ty.alias("name", st);
mod->AddConstructedType(alias);
Module m; EXPECT_FALSE(mod->IsValid());
m.AddConstructedType(&alias);
EXPECT_FALSE(m.IsValid());
} }
TEST_F(ModuleTest, IsValid_Function) { TEST_F(ModuleTest, IsValid_Function) {
Module m; auto* func = Func("main", VariableList(), ty.f32, StatementList{},
ast::FunctionDecorationList{});
auto* func = create<Function>( mod->AddFunction(func);
m.RegisterSymbol("main"), "main", VariableList(), ty.f32, EXPECT_TRUE(mod->IsValid());
create<BlockStatement>(StatementList{}), ast::FunctionDecorationList{});
m.AddFunction(func);
EXPECT_TRUE(m.IsValid());
} }
TEST_F(ModuleTest, IsValid_Null_Function) { TEST_F(ModuleTest, IsValid_Null_Function) {
Module m; mod->AddFunction(nullptr);
m.AddFunction(nullptr); EXPECT_FALSE(mod->IsValid());
EXPECT_FALSE(m.IsValid());
} }
TEST_F(ModuleTest, IsValid_Invalid_Function) { TEST_F(ModuleTest, IsValid_Invalid_Function) {
VariableList p; auto* func = Func("main", VariableList{}, nullptr, StatementList{},
ast::FunctionDecorationList{});
Module m; mod->AddFunction(func);
EXPECT_FALSE(mod->IsValid());
auto* func = create<Function>(m.RegisterSymbol("main"), "main", p, nullptr,
nullptr, ast::FunctionDecorationList{});
m.AddFunction(func);
EXPECT_FALSE(m.IsValid());
} }
} // namespace } // namespace

View File

@ -28,11 +28,7 @@ namespace {
using StructMemberTest = TestHelper; using StructMemberTest = TestHelper;
TEST_F(StructMemberTest, Creation) { TEST_F(StructMemberTest, Creation) {
StructMemberDecorationList decorations; auto* st = Member("a", ty.i32, {MemberOffset(4)});
decorations.emplace_back(create<StructMemberOffsetDecoration>(4));
auto* st =
create<StructMember>(mod->RegisterSymbol("a"), "a", ty.i32, decorations);
EXPECT_EQ(st->symbol(), Symbol(1)); EXPECT_EQ(st->symbol(), Symbol(1));
EXPECT_EQ(st->name(), "a"); EXPECT_EQ(st->name(), "a");
EXPECT_EQ(st->type(), ty.i32); EXPECT_EQ(st->type(), ty.i32);
@ -45,9 +41,9 @@ TEST_F(StructMemberTest, Creation) {
} }
TEST_F(StructMemberTest, CreationWithSource) { TEST_F(StructMemberTest, CreationWithSource) {
auto* st = create<StructMember>( auto* st = Member(
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}}, Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}},
mod->RegisterSymbol("a"), "a", ty.i32, StructMemberDecorationList{}); "a", ty.i32);
EXPECT_EQ(st->symbol(), Symbol(1)); EXPECT_EQ(st->symbol(), Symbol(1));
EXPECT_EQ(st->name(), "a"); EXPECT_EQ(st->name(), "a");
EXPECT_EQ(st->type(), ty.i32); EXPECT_EQ(st->type(), ty.i32);
@ -59,47 +55,34 @@ TEST_F(StructMemberTest, CreationWithSource) {
} }
TEST_F(StructMemberTest, IsValid) { TEST_F(StructMemberTest, IsValid) {
auto* st = create<StructMember>(mod->RegisterSymbol("a"), "a", ty.i32, auto* st = Member("a", ty.i32);
StructMemberDecorationList{});
EXPECT_TRUE(st->IsValid()); EXPECT_TRUE(st->IsValid());
} }
TEST_F(StructMemberTest, IsValid_EmptySymbol) { TEST_F(StructMemberTest, IsValid_EmptySymbol) {
auto* st = create<StructMember>(mod->RegisterSymbol(""), "", ty.i32, auto* st = Member("", ty.i32);
StructMemberDecorationList{});
EXPECT_FALSE(st->IsValid()); EXPECT_FALSE(st->IsValid());
} }
TEST_F(StructMemberTest, IsValid_NullType) { TEST_F(StructMemberTest, IsValid_NullType) {
auto* st = create<StructMember>(mod->RegisterSymbol("a"), "a", nullptr, auto* st = Member("a", nullptr);
StructMemberDecorationList{});
EXPECT_FALSE(st->IsValid()); EXPECT_FALSE(st->IsValid());
} }
TEST_F(StructMemberTest, IsValid_Null_Decoration) { TEST_F(StructMemberTest, IsValid_Null_Decoration) {
StructMemberDecorationList decorations; auto* st = Member("a", ty.i32, {MemberOffset(4), nullptr});
decorations.emplace_back(create<StructMemberOffsetDecoration>(4));
decorations.push_back(nullptr);
auto* st =
create<StructMember>(mod->RegisterSymbol("a"), "a", ty.i32, decorations);
EXPECT_FALSE(st->IsValid()); EXPECT_FALSE(st->IsValid());
} }
TEST_F(StructMemberTest, ToStr) { TEST_F(StructMemberTest, ToStr) {
StructMemberDecorationList decorations; auto* st = Member("a", ty.i32, {MemberOffset(4)});
decorations.emplace_back(create<StructMemberOffsetDecoration>(4));
auto* st =
create<StructMember>(mod->RegisterSymbol("a"), "a", ty.i32, decorations);
std::ostringstream out; std::ostringstream out;
st->to_str(out, 2); st->to_str(out, 2);
EXPECT_EQ(demangle(out.str()), " StructMember{[[ offset 4 ]] a: __i32}\n"); EXPECT_EQ(demangle(out.str()), " StructMember{[[ offset 4 ]] a: __i32}\n");
} }
TEST_F(StructMemberTest, ToStrNoDecorations) { TEST_F(StructMemberTest, ToStrNoDecorations) {
auto* st = create<StructMember>(mod->RegisterSymbol("a"), "a", ty.i32, auto* st = Member("a", ty.i32);
StructMemberDecorationList{});
std::ostringstream out; std::ostringstream out;
st->to_str(out, 2); st->to_str(out, 2);
EXPECT_EQ(demangle(out.str()), " StructMember{a: __i32}\n"); EXPECT_EQ(demangle(out.str()), " StructMember{a: __i32}\n");

View File

@ -30,28 +30,21 @@ namespace {
using StructTest = TestHelper; using StructTest = TestHelper;
TEST_F(StructTest, Creation) { TEST_F(StructTest, Creation) {
StructMemberList members; auto* s = create<Struct>(StructMemberList{Member("a", ty.i32)},
members.push_back(create<StructMember>(mod->RegisterSymbol("a"), "a", ty.i32, StructDecorationList{});
StructMemberDecorationList{}));
auto* s = create<Struct>(members, ast::StructDecorationList{});
EXPECT_EQ(s->members().size(), 1u); EXPECT_EQ(s->members().size(), 1u);
EXPECT_TRUE(s->decorations().empty()); EXPECT_TRUE(s->decorations().empty());
EXPECT_EQ(s->source().range.begin.line, 0u); EXPECT_EQ(s->source().range.begin.line, 0u);
EXPECT_EQ(s->source().range.begin.column, 0u); EXPECT_EQ(s->source().range.begin.column, 0u);
EXPECT_EQ(s->source().range.end.line, 0u); EXPECT_EQ(s->source().range.end.line, 0u);
EXPECT_EQ(s->source().range.end.column, 0u); EXPECT_EQ(s->source().range.end.column, 0u);
} // namespace }
TEST_F(StructTest, Creation_WithDecorations) { TEST_F(StructTest, Creation_WithDecorations) {
StructMemberList members;
members.push_back(create<StructMember>(mod->RegisterSymbol("a"), "a", ty.i32,
StructMemberDecorationList{}));
StructDecorationList decos; StructDecorationList decos;
decos.push_back(create<StructBlockDecoration>()); decos.push_back(create<StructBlockDecoration>());
auto* s = create<Struct>(members, decos); auto* s = create<Struct>(StructMemberList{Member("a", ty.i32)}, decos);
EXPECT_EQ(s->members().size(), 1u); EXPECT_EQ(s->members().size(), 1u);
ASSERT_EQ(s->decorations().size(), 1u); ASSERT_EQ(s->decorations().size(), 1u);
EXPECT_TRUE(s->decorations()[0]->Is<StructBlockDecoration>()); EXPECT_TRUE(s->decorations()[0]->Is<StructBlockDecoration>());
@ -62,16 +55,12 @@ TEST_F(StructTest, Creation_WithDecorations) {
} }
TEST_F(StructTest, CreationWithSourceAndDecorations) { TEST_F(StructTest, CreationWithSourceAndDecorations) {
StructMemberList members;
members.emplace_back(create<StructMember>(
mod->RegisterSymbol("a"), "a", ty.i32, StructMemberDecorationList{}));
StructDecorationList decos; StructDecorationList decos;
decos.push_back(create<StructBlockDecoration>()); decos.push_back(create<StructBlockDecoration>());
auto* s = create<Struct>( auto* s = create<Struct>(
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}}, Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}},
members, decos); StructMemberList{Member("a", ty.i32)}, decos);
EXPECT_EQ(s->members().size(), 1u); EXPECT_EQ(s->members().size(), 1u);
ASSERT_EQ(s->decorations().size(), 1u); ASSERT_EQ(s->decorations().size(), 1u);
EXPECT_TRUE(s->decorations()[0]->Is<StructBlockDecoration>()); EXPECT_TRUE(s->decorations()[0]->Is<StructBlockDecoration>());
@ -87,33 +76,21 @@ TEST_F(StructTest, IsValid) {
} }
TEST_F(StructTest, IsValid_Null_StructMember) { TEST_F(StructTest, IsValid_Null_StructMember) {
StructMemberList members; auto* s = create<Struct>(StructMemberList{Member("a", ty.i32), nullptr},
members.push_back(create<StructMember>(mod->RegisterSymbol("a"), "a", ty.i32, StructDecorationList{});
StructMemberDecorationList{}));
members.push_back(nullptr);
auto* s = create<Struct>(members, ast::StructDecorationList{});
EXPECT_FALSE(s->IsValid()); EXPECT_FALSE(s->IsValid());
} // namespace ast }
TEST_F(StructTest, IsValid_Invalid_StructMember) { TEST_F(StructTest, IsValid_Invalid_StructMember) {
StructMemberList members; auto* s = create<Struct>(StructMemberList{Member("", ty.i32)},
members.push_back(create<StructMember>(mod->RegisterSymbol(""), "", ty.i32, ast::StructDecorationList{});
StructMemberDecorationList{}));
auto* s = create<Struct>(members, ast::StructDecorationList{});
EXPECT_FALSE(s->IsValid()); EXPECT_FALSE(s->IsValid());
} // namespace tint }
TEST_F(StructTest, ToStr) { TEST_F(StructTest, ToStr) {
StructMemberList members;
members.emplace_back(create<StructMember>(
mod->RegisterSymbol("a"), "a", ty.i32, StructMemberDecorationList{}));
StructDecorationList decos; StructDecorationList decos;
decos.push_back(create<StructBlockDecoration>()); decos.push_back(create<StructBlockDecoration>());
auto* s = create<Struct>(StructMemberList{Member("a", ty.i32)}, decos);
auto* s = create<Struct>(members, decos);
std::ostringstream out; std::ostringstream out;
s->to_str(out, 2); s->to_str(out, 2);

View File

@ -119,24 +119,13 @@ TEST_F(AccessControlTest, MinBufferBindingSizeRuntimeArray) {
} }
TEST_F(AccessControlTest, MinBufferBindingSizeStruct) { TEST_F(AccessControlTest, MinBufferBindingSizeStruct) {
U32 u32; auto* str = create<ast::Struct>(
StructMemberList members; StructMemberList{Member("foo", ty.u32, {MemberOffset(0)}),
Member("bar", ty.u32, {MemberOffset(4)})},
StructDecorationList{});
StructMemberDecorationList deco; auto* struct_type = ty.struct_("struct_type", str);
deco.push_back(create<StructMemberOffsetDecoration>(0)); AccessControl at{ast::AccessControl::kReadOnly, struct_type};
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &u32, deco));
deco = StructMemberDecorationList();
deco.push_back(create<StructMemberOffsetDecoration>(4));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &u32, deco));
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
AccessControl at{ast::AccessControl::kReadOnly, &struct_type};
EXPECT_EQ(16u, at.MinBufferBindingSize(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, at.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
EXPECT_EQ(8u, at.MinBufferBindingSize(MemoryLayout::kStorageBuffer)); EXPECT_EQ(8u, at.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
} }
@ -162,26 +151,13 @@ TEST_F(AccessControlTest, BaseAlignmentRuntimeArray) {
} }
TEST_F(AccessControlTest, BaseAlignmentStruct) { TEST_F(AccessControlTest, BaseAlignmentStruct) {
U32 u32; auto* str = create<ast::Struct>(
StructMemberList members; StructMemberList{Member("foo", ty.u32, {MemberOffset(0)}),
Member("bar", ty.u32, {MemberOffset(4)})},
StructDecorationList{});
auto* struct_type = ty.struct_("struct_type", str);
{ AccessControl at{ast::AccessControl::kReadOnly, struct_type};
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &u32, deco));
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(4));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &u32, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
AccessControl at{ast::AccessControl::kReadOnly, &struct_type};
EXPECT_EQ(16u, at.BaseAlignment(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, at.BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(4u, at.BaseAlignment(MemoryLayout::kStorageBuffer)); EXPECT_EQ(4u, at.BaseAlignment(MemoryLayout::kStorageBuffer));
} }

View File

@ -32,7 +32,6 @@
#include "src/ast/type/pointer_type.h" #include "src/ast/type/pointer_type.h"
#include "src/ast/type/struct_type.h" #include "src/ast/type/struct_type.h"
#include "src/ast/type/texture_type.h" #include "src/ast/type/texture_type.h"
#include "src/ast/type/u32_type.h"
#include "src/ast/type/vector_type.h" #include "src/ast/type/vector_type.h"
namespace tint { namespace tint {
@ -43,18 +42,14 @@ namespace {
using AliasTest = TestHelper; using AliasTest = TestHelper;
TEST_F(AliasTest, Create) { TEST_F(AliasTest, Create) {
U32 u32; auto* a = ty.alias("a_type", ty.u32);
Alias a{mod->RegisterSymbol("a_type"), "a_type", &u32}; EXPECT_EQ(a->symbol(), Symbol(1));
EXPECT_EQ(a.symbol(), Symbol(1)); EXPECT_EQ(a->type(), ty.u32);
// EXPECT_EQ(a.name(), "a_type");
EXPECT_EQ(a.type(), &u32);
} }
TEST_F(AliasTest, Is) { TEST_F(AliasTest, Is) {
I32 i32; auto* at = ty.alias("a", ty.i32);
type::Type* ty = at;
Alias at{mod->RegisterSymbol("a"), "a", &i32};
Type* ty = &at;
EXPECT_FALSE(ty->Is<AccessControl>()); EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_TRUE(ty->Is<Alias>()); EXPECT_TRUE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>()); EXPECT_FALSE(ty->Is<Array>());
@ -71,200 +66,159 @@ TEST_F(AliasTest, Is) {
} }
TEST_F(AliasTest, TypeName) { TEST_F(AliasTest, TypeName) {
I32 i32; auto* at = ty.alias("Particle", ty.i32);
Alias at{mod->RegisterSymbol("Particle"), "Particle", &i32}; EXPECT_EQ(at->type_name(), "__alias_tint_symbol_1__i32");
EXPECT_EQ(at.type_name(), "__alias_tint_symbol_1__i32");
} }
TEST_F(AliasTest, UnwrapIfNeeded_Alias) { TEST_F(AliasTest, UnwrapIfNeeded_Alias) {
U32 u32; auto* a = ty.alias("a_type", ty.u32);
Alias a{mod->RegisterSymbol("a_type"), "a_type", &u32}; EXPECT_EQ(a->symbol(), Symbol(1));
EXPECT_EQ(a.symbol(), Symbol(1)); EXPECT_EQ(a->type(), ty.u32);
// EXPECT_EQ(a.name(), "a_type"); EXPECT_EQ(a->UnwrapIfNeeded(), ty.u32);
EXPECT_EQ(a.type(), &u32); EXPECT_EQ(ty.u32->UnwrapIfNeeded(), ty.u32);
EXPECT_EQ(a.UnwrapIfNeeded(), &u32);
EXPECT_EQ(u32.UnwrapIfNeeded(), &u32);
} }
TEST_F(AliasTest, UnwrapIfNeeded_AccessControl) { TEST_F(AliasTest, UnwrapIfNeeded_AccessControl) {
U32 u32; AccessControl a{ast::AccessControl::kReadOnly, ty.u32};
AccessControl a{ast::AccessControl::kReadOnly, &u32}; EXPECT_EQ(a.type(), ty.u32);
EXPECT_EQ(a.type(), &u32); EXPECT_EQ(a.UnwrapIfNeeded(), ty.u32);
EXPECT_EQ(a.UnwrapIfNeeded(), &u32);
} }
TEST_F(AliasTest, UnwrapIfNeeded_MultiLevel) { TEST_F(AliasTest, UnwrapIfNeeded_MultiLevel) {
U32 u32; auto* a = ty.alias("a_type", ty.u32);
Alias a{mod->RegisterSymbol("a_type"), "a_type", &u32}; auto* aa = ty.alias("aa_type", a);
Alias aa{mod->RegisterSymbol("aa_type"), "aa_type", &a};
EXPECT_EQ(aa.symbol(), Symbol(2)); EXPECT_EQ(aa->symbol(), Symbol(2));
// EXPECT_EQ(aa.name(), "aa_type"); EXPECT_EQ(aa->type(), a);
EXPECT_EQ(aa.type(), &a); EXPECT_EQ(aa->UnwrapIfNeeded(), ty.u32);
EXPECT_EQ(aa.UnwrapIfNeeded(), &u32);
} }
TEST_F(AliasTest, UnwrapIfNeeded_MultiLevel_AliasAccessControl) { TEST_F(AliasTest, UnwrapIfNeeded_MultiLevel_AliasAccessControl) {
U32 u32; auto* a = ty.alias("a_type", ty.u32);
Alias a{mod->RegisterSymbol("a_type"), "a_type", &u32};
AccessControl aa{ast::AccessControl::kReadWrite, &a}; AccessControl aa{ast::AccessControl::kReadWrite, a};
EXPECT_EQ(aa.type(), &a); EXPECT_EQ(aa.type(), a);
EXPECT_EQ(aa.UnwrapIfNeeded(), &u32); EXPECT_EQ(aa.UnwrapIfNeeded(), ty.u32);
} }
TEST_F(AliasTest, UnwrapAll_TwiceAliasPointerTwiceAlias) { TEST_F(AliasTest, UnwrapAll_TwiceAliasPointerTwiceAlias) {
U32 u32; auto* a = ty.alias("a_type", ty.u32);
Alias a{mod->RegisterSymbol("a_type"), "a_type", &u32}; auto* aa = ty.alias("aa_type", a);
Alias aa{mod->RegisterSymbol("aa_type"), "aa_type", &a}; Pointer paa{aa, StorageClass::kUniform};
Pointer paa{&aa, StorageClass::kUniform}; auto* apaa = ty.alias("paa_type", &paa);
Alias apaa{mod->RegisterSymbol("paa_type"), "paa_type", &paa}; auto* aapaa = ty.alias("aapaa_type", apaa);
Alias aapaa{mod->RegisterSymbol("aapaa_type"), "aapaa_type", &apaa};
EXPECT_EQ(aapaa.symbol(), Symbol(4)); EXPECT_EQ(aapaa->symbol(), Symbol(4));
// EXPECT_EQ(aapaa.name(), "aapaa_type"); EXPECT_EQ(aapaa->type(), apaa);
EXPECT_EQ(aapaa.type(), &apaa); EXPECT_EQ(aapaa->UnwrapAll(), ty.u32);
EXPECT_EQ(aapaa.UnwrapAll(), &u32);
EXPECT_EQ(u32.UnwrapAll(), &u32);
} }
TEST_F(AliasTest, UnwrapAll_SecondConsecutivePointerBlocksUnrapping) { TEST_F(AliasTest, UnwrapAll_SecondConsecutivePointerBlocksUnrapping) {
U32 u32; auto* a = ty.alias("a_type", ty.u32);
Alias a{mod->RegisterSymbol("a_type"), "a_type", &u32}; auto* aa = ty.alias("aa_type", a);
Alias aa{mod->RegisterSymbol("aa_type"), "aa_type", &a};
Pointer paa{&aa, StorageClass::kUniform}; Pointer paa{aa, StorageClass::kUniform};
Pointer ppaa{&paa, StorageClass::kUniform}; Pointer ppaa{&paa, StorageClass::kUniform};
Alias appaa{mod->RegisterSymbol("appaa_type"), "appaa_type", &ppaa}; auto* appaa = ty.alias("appaa_type", &ppaa);
EXPECT_EQ(appaa.UnwrapAll(), &paa); EXPECT_EQ(appaa->UnwrapAll(), &paa);
} }
TEST_F(AliasTest, UnwrapAll_SecondNonConsecutivePointerBlocksUnrapping) { TEST_F(AliasTest, UnwrapAll_SecondNonConsecutivePointerBlocksUnrapping) {
U32 u32; auto* a = ty.alias("a_type", ty.u32);
Alias a{mod->RegisterSymbol("a_type"), "a_type", &u32}; auto* aa = ty.alias("aa_type", a);
Alias aa{mod->RegisterSymbol("aa_type"), "aa_type", &a}; Pointer paa{aa, StorageClass::kUniform};
Pointer paa{&aa, StorageClass::kUniform};
Alias apaa{mod->RegisterSymbol("apaa_type"), "apaa_type", &paa}; auto* apaa = ty.alias("apaa_type", &paa);
Alias aapaa{mod->RegisterSymbol("aapaa_type"), "aapaa_type", &apaa}; auto* aapaa = ty.alias("aapaa_type", apaa);
Pointer paapaa{&aapaa, StorageClass::kUniform}; Pointer paapaa{aapaa, StorageClass::kUniform};
Alias apaapaa{mod->RegisterSymbol("apaapaa_type"), "apaapaa_type", &paapaa}; auto* apaapaa = ty.alias("apaapaa_type", &paapaa);
EXPECT_EQ(apaapaa.UnwrapAll(), &paa);
EXPECT_EQ(apaapaa->UnwrapAll(), &paa);
} }
TEST_F(AliasTest, UnwrapAll_AccessControlPointer) { TEST_F(AliasTest, UnwrapAll_AccessControlPointer) {
U32 u32; AccessControl a{ast::AccessControl::kReadOnly, ty.u32};
AccessControl a{ast::AccessControl::kReadOnly, &u32};
Pointer pa{&a, StorageClass::kUniform}; Pointer pa{&a, StorageClass::kUniform};
EXPECT_EQ(pa.type(), &a); EXPECT_EQ(pa.type(), &a);
EXPECT_EQ(pa.UnwrapAll(), &u32); EXPECT_EQ(pa.UnwrapAll(), ty.u32);
EXPECT_EQ(u32.UnwrapAll(), &u32);
} }
TEST_F(AliasTest, UnwrapAll_PointerAccessControl) { TEST_F(AliasTest, UnwrapAll_PointerAccessControl) {
U32 u32; Pointer p{ty.u32, StorageClass::kUniform};
Pointer p{&u32, StorageClass::kUniform};
AccessControl a{ast::AccessControl::kReadOnly, &p}; AccessControl a{ast::AccessControl::kReadOnly, &p};
EXPECT_EQ(a.type(), &p); EXPECT_EQ(a.type(), &p);
EXPECT_EQ(a.UnwrapAll(), &u32); EXPECT_EQ(a.UnwrapAll(), ty.u32);
EXPECT_EQ(u32.UnwrapAll(), &u32);
} }
TEST_F(AliasTest, MinBufferBindingSizeU32) { TEST_F(AliasTest, MinBufferBindingSizeU32) {
U32 u32; auto* alias = ty.alias("alias", ty.u32);
Alias alias{mod->RegisterSymbol("alias"), "alias", &u32}; EXPECT_EQ(4u, alias->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
EXPECT_EQ(4u, alias.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
} }
TEST_F(AliasTest, MinBufferBindingSizeArray) { TEST_F(AliasTest, MinBufferBindingSizeArray) {
U32 u32; Array array(ty.u32, 4,
Array array(&u32, 4,
ArrayDecorationList{ ArrayDecorationList{
create<StrideDecoration>(4), create<StrideDecoration>(4),
}); });
Alias alias{mod->RegisterSymbol("alias"), "alias", &array}; auto* alias = ty.alias("alias", &array);
EXPECT_EQ(16u, alias.MinBufferBindingSize(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, alias->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
} }
TEST_F(AliasTest, MinBufferBindingSizeRuntimeArray) { TEST_F(AliasTest, MinBufferBindingSizeRuntimeArray) {
U32 u32; Array array(ty.u32, 0,
Array array(&u32, 0,
ArrayDecorationList{ ArrayDecorationList{
create<StrideDecoration>(4), create<StrideDecoration>(4),
}); });
Alias alias{mod->RegisterSymbol("alias"), "alias", &array}; auto* alias = ty.alias("alias", &array);
EXPECT_EQ(4u, alias.MinBufferBindingSize(MemoryLayout::kUniformBuffer)); EXPECT_EQ(4u, alias->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
} }
TEST_F(AliasTest, MinBufferBindingSizeStruct) { TEST_F(AliasTest, MinBufferBindingSizeStruct) {
U32 u32; auto* str = create<ast::Struct>(
StructMemberList members; StructMemberList{Member("foo", ty.u32, {MemberOffset(0)}),
Member("bar", ty.u32, {MemberOffset(4)})},
StructDecorationList{});
auto* struct_type = ty.struct_("struct_type", str);
auto* alias = ty.alias("alias", struct_type);
{ EXPECT_EQ(16u, alias->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
StructMemberDecorationList deco; EXPECT_EQ(8u, alias->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &u32, deco));
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(4));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &u32, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
Alias alias{mod->RegisterSymbol("alias"), "alias", &struct_type};
EXPECT_EQ(16u, alias.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
EXPECT_EQ(8u, alias.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
} }
TEST_F(AliasTest, BaseAlignmentU32) { TEST_F(AliasTest, BaseAlignmentU32) {
U32 u32; auto* alias = ty.alias("alias", ty.u32);
Alias alias{mod->RegisterSymbol("alias"), "alias", &u32}; EXPECT_EQ(4u, alias->BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(4u, alias.BaseAlignment(MemoryLayout::kUniformBuffer));
} }
TEST_F(AliasTest, BaseAlignmentArray) { TEST_F(AliasTest, BaseAlignmentArray) {
U32 u32; Array array(ty.u32, 4,
Array array(&u32, 4,
ArrayDecorationList{ ArrayDecorationList{
create<StrideDecoration>(4), create<StrideDecoration>(4),
}); });
Alias alias{mod->RegisterSymbol("alias"), "alias", &array}; auto* alias = ty.alias("alias", &array);
EXPECT_EQ(16u, alias.BaseAlignment(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, alias->BaseAlignment(MemoryLayout::kUniformBuffer));
} }
TEST_F(AliasTest, BaseAlignmentRuntimeArray) { TEST_F(AliasTest, BaseAlignmentRuntimeArray) {
U32 u32; Array array(ty.u32, 0,
Array array(&u32, 0,
ArrayDecorationList{ ArrayDecorationList{
create<StrideDecoration>(4), create<StrideDecoration>(4),
}); });
Alias alias{mod->RegisterSymbol("alias"), "alias", &array}; auto* alias = ty.alias("alias", &array);
EXPECT_EQ(16u, alias.BaseAlignment(MemoryLayout::kUniformBuffer)); EXPECT_EQ(16u, alias->BaseAlignment(MemoryLayout::kUniformBuffer));
} }
TEST_F(AliasTest, BaseAlignmentStruct) { TEST_F(AliasTest, BaseAlignmentStruct) {
U32 u32; auto* str = create<ast::Struct>(
StructMemberList members; StructMemberList{Member("foo", ty.u32, {MemberOffset(0)}),
Member("bar", ty.u32, {MemberOffset(4)})},
StructDecorationList{});
auto* struct_type = ty.struct_("struct_type", str);
auto* alias = ty.alias("alias", struct_type);
{ EXPECT_EQ(16u, alias->BaseAlignment(MemoryLayout::kUniformBuffer));
StructMemberDecorationList deco; EXPECT_EQ(4u, alias->BaseAlignment(MemoryLayout::kStorageBuffer));
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &u32, deco));
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(4));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &u32, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
Alias alias{mod->RegisterSymbol("alias"), "alias", &struct_type};
EXPECT_EQ(16u, alias.BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(4u, alias.BaseAlignment(MemoryLayout::kStorageBuffer));
} }
} // namespace } // namespace

View File

@ -40,18 +40,16 @@ namespace {
using StructTest = TestHelper; using StructTest = TestHelper;
TEST_F(StructTest, Creation) { TEST_F(StructTest, Creation) {
StructMemberList members; auto* impl = create<ast::Struct>(StructMemberList{}, StructDecorationList{});
auto* impl = create<ast::Struct>(members, ast::StructDecorationList{});
auto* ptr = impl; auto* ptr = impl;
Struct s{mod->RegisterSymbol("S"), "S", impl}; auto* s = ty.struct_("S", impl);
EXPECT_EQ(s.impl(), ptr); EXPECT_EQ(s->impl(), ptr);
} }
TEST_F(StructTest, Is) { TEST_F(StructTest, Is) {
StructMemberList members; auto* impl = create<ast::Struct>(StructMemberList{}, StructDecorationList{});
auto* impl = create<ast::Struct>(members, ast::StructDecorationList{}); auto* s = ty.struct_("S", impl);
Struct s{mod->RegisterSymbol("S"), "S", impl}; type::Type* ty = s;
Type* ty = &s;
EXPECT_FALSE(ty->Is<AccessControl>()); EXPECT_FALSE(ty->Is<AccessControl>());
EXPECT_FALSE(ty->Is<Alias>()); EXPECT_FALSE(ty->Is<Alias>());
EXPECT_FALSE(ty->Is<Array>()); EXPECT_FALSE(ty->Is<Array>());
@ -68,303 +66,143 @@ TEST_F(StructTest, Is) {
} }
TEST_F(StructTest, TypeName) { TEST_F(StructTest, TypeName) {
StructMemberList members; auto* impl = create<ast::Struct>(StructMemberList{}, StructDecorationList{});
auto* impl = create<ast::Struct>(members, ast::StructDecorationList{}); auto* s = ty.struct_("my_struct", impl);
Struct s{mod->RegisterSymbol("my_struct"), "my_struct", impl}; EXPECT_EQ(s->type_name(), "__struct_tint_symbol_1");
EXPECT_EQ(s.type_name(), "__struct_tint_symbol_1");
} }
TEST_F(StructTest, MinBufferBindingSize) { TEST_F(StructTest, MinBufferBindingSize) {
U32 u32; auto* str = create<ast::Struct>(
StructMemberList members; StructMemberList{Member("foo", ty.u32, {MemberOffset(0)}),
Member("bar", ty.u32, {MemberOffset(4)})},
StructDecorationList{});
auto* s_ty = ty.struct_("s_ty", str);
{ EXPECT_EQ(16u, s_ty->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
StructMemberDecorationList deco; EXPECT_EQ(8u, s_ty->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &u32, deco));
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(4));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &u32, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
EXPECT_EQ(16u,
struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
EXPECT_EQ(8u, struct_type.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
} }
TEST_F(StructTest, MinBufferBindingSizeArray) { TEST_F(StructTest, MinBufferBindingSizeArray) {
U32 u32; Array arr(ty.u32, 4, ArrayDecorationList{create<StrideDecoration>(4)});
Array arr(&u32, 4, ArrayDecorationList{create<StrideDecoration>(4)});
StructMemberList members; auto* str = create<ast::Struct>(
{ StructMemberList{Member("foo", ty.u32, {MemberOffset(0)}),
StructMemberDecorationList deco; Member("bar", ty.u32, {MemberOffset(4)}),
deco.push_back(create<StructMemberOffsetDecoration>(0)); Member("bar", &arr, {MemberOffset(8)})},
members.push_back( StructDecorationList{});
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &u32, deco)); auto* s_ty = ty.struct_("s_ty", str);
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(4));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &u32, deco));
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(8));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &arr, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos); EXPECT_EQ(32u, s_ty->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str); EXPECT_EQ(24u, s_ty->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
EXPECT_EQ(32u,
struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
EXPECT_EQ(24u,
struct_type.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
} }
TEST_F(StructTest, MinBufferBindingSizeRuntimeArray) { TEST_F(StructTest, MinBufferBindingSizeRuntimeArray) {
U32 u32; Array arr(ty.u32, 0, ArrayDecorationList{create<StrideDecoration>(4)});
Array arr(&u32, 0, ArrayDecorationList{create<StrideDecoration>(4)});
StructMemberList members; auto* str = create<ast::Struct>(
{ StructMemberList{Member("foo", ty.u32, {MemberOffset(0)}),
StructMemberDecorationList deco; Member("bar", ty.u32, {MemberOffset(4)}),
deco.push_back(create<StructMemberOffsetDecoration>(0)); Member("bar", ty.u32, {MemberOffset(8)})},
members.push_back( StructDecorationList{});
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &u32, deco)); auto* s_ty = ty.struct_("s_ty", str);
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(4));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &u32, deco));
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(8));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &u32, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos); EXPECT_EQ(12u, s_ty->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
EXPECT_EQ(12u,
struct_type.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
} }
TEST_F(StructTest, MinBufferBindingSizeVec2) { TEST_F(StructTest, MinBufferBindingSizeVec2) {
U32 u32; auto* str = create<ast::Struct>(
Vector vec2(&u32, 2); StructMemberList{Member("foo", ty.vec2<u32>(), {MemberOffset(0)})},
StructDecorationList{});
auto* s_ty = ty.struct_("s_ty", str);
StructMemberList members; EXPECT_EQ(16u, s_ty->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
{ EXPECT_EQ(8u, s_ty->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &vec2, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
EXPECT_EQ(16u,
struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
EXPECT_EQ(8u, struct_type.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
} }
TEST_F(StructTest, MinBufferBindingSizeVec3) { TEST_F(StructTest, MinBufferBindingSizeVec3) {
U32 u32; auto* str = create<ast::Struct>(
Vector vec3(&u32, 3); StructMemberList{Member("foo", ty.vec3<u32>(), {MemberOffset(0)})},
StructDecorationList{});
auto* s_ty = ty.struct_("s_ty", str);
StructMemberList members; EXPECT_EQ(16u, s_ty->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
{ EXPECT_EQ(16u, s_ty->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &vec3, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
EXPECT_EQ(16u,
struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
EXPECT_EQ(16u,
struct_type.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
} }
TEST_F(StructTest, MinBufferBindingSizeVec4) { TEST_F(StructTest, MinBufferBindingSizeVec4) {
U32 u32; auto* str = create<ast::Struct>(
Vector vec4(&u32, 4); StructMemberList{Member("foo", ty.vec4<u32>(), {MemberOffset(0)})},
StructDecorationList{});
auto* s_ty = ty.struct_("s_ty", str);
StructMemberList members; EXPECT_EQ(16u, s_ty->MinBufferBindingSize(MemoryLayout::kUniformBuffer));
{ EXPECT_EQ(16u, s_ty->MinBufferBindingSize(MemoryLayout::kStorageBuffer));
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &vec4, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
EXPECT_EQ(16u,
struct_type.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
EXPECT_EQ(16u,
struct_type.MinBufferBindingSize(MemoryLayout::kStorageBuffer));
} }
TEST_F(StructTest, BaseAlignment) { TEST_F(StructTest, BaseAlignment) {
U32 u32; auto* str = create<ast::Struct>(
StructMemberList members; StructMemberList{Member("foo", ty.u32, {MemberOffset(0)}),
Member("bar", ty.u32, {MemberOffset(8)})},
StructDecorationList{});
auto* s_ty = ty.struct_("s_ty", str);
{ EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kUniformBuffer));
StructMemberDecorationList deco; EXPECT_EQ(4u, s_ty->BaseAlignment(MemoryLayout::kStorageBuffer));
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &u32, deco));
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(4));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &u32, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(4u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
} }
TEST_F(StructTest, BaseAlignmentArray) { TEST_F(StructTest, BaseAlignmentArray) {
U32 u32; Array arr(ty.u32, 4, ArrayDecorationList{create<StrideDecoration>(4)});
Array arr(&u32, 4, ArrayDecorationList{create<StrideDecoration>(4)}); auto* str = create<ast::Struct>(
StructMemberList{Member("foo", ty.u32, {MemberOffset(0)}),
Member("bar", ty.u32, {MemberOffset(4)}),
Member("bar", &arr, {MemberOffset(8)})},
StructDecorationList{});
auto* s_ty = ty.struct_("s_ty", str);
StructMemberList members; EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kUniformBuffer));
{ EXPECT_EQ(4u, s_ty->BaseAlignment(MemoryLayout::kStorageBuffer));
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &u32, deco));
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(4));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &u32, deco));
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(8));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &arr, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(4u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
} }
TEST_F(StructTest, BaseAlignmentRuntimeArray) { TEST_F(StructTest, BaseAlignmentRuntimeArray) {
U32 u32; Array arr(ty.u32, 0, ArrayDecorationList{create<StrideDecoration>(4)});
Array arr(&u32, 0, ArrayDecorationList{create<StrideDecoration>(4)}); auto* str = create<ast::Struct>(
StructMemberList{Member("foo", ty.u32, {MemberOffset(0)}),
Member("bar", ty.u32, {MemberOffset(4)}),
Member("bar", ty.u32, {MemberOffset(8)})},
StructDecorationList{});
auto* s_ty = ty.struct_("s_ty", str);
StructMemberList members; EXPECT_EQ(4u, s_ty->BaseAlignment(MemoryLayout::kStorageBuffer));
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &u32, deco));
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(4));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &u32, deco));
}
{
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(8));
members.push_back(
create<StructMember>(mod->RegisterSymbol("bar"), "bar", &u32, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
EXPECT_EQ(4u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
} }
TEST_F(StructTest, BaseAlignmentVec2) { TEST_F(StructTest, BaseAlignmentVec2) {
U32 u32; auto* str = create<ast::Struct>(
Vector vec2(&u32, 2); StructMemberList{Member("foo", ty.vec2<u32>(), {MemberOffset(0)})},
StructDecorationList{});
auto* s_ty = ty.struct_("s_ty", str);
StructMemberList members; EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kUniformBuffer));
{ EXPECT_EQ(8u, s_ty->BaseAlignment(MemoryLayout::kStorageBuffer));
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &vec2, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(8u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
} }
TEST_F(StructTest, BaseAlignmentVec3) { TEST_F(StructTest, BaseAlignmentVec3) {
U32 u32; auto* str = create<ast::Struct>(
Vector vec3(&u32, 3); StructMemberList{Member("foo", ty.vec3<u32>(), {MemberOffset(0)})},
StructDecorationList{});
auto* s_ty = ty.struct_("s_ty", str);
StructMemberList members; EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kUniformBuffer));
{ EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kStorageBuffer));
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &vec3, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
} }
TEST_F(StructTest, BaseAlignmentVec4) { TEST_F(StructTest, BaseAlignmentVec4) {
U32 u32; auto* str = create<ast::Struct>(
Vector vec4(&u32, 4); StructMemberList{Member("foo", ty.vec4<u32>(), {MemberOffset(0)})},
StructDecorationList{});
auto* s_ty = ty.struct_("s_ty", str);
StructMemberList members; EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kUniformBuffer));
{ EXPECT_EQ(16u, s_ty->BaseAlignment(MemoryLayout::kStorageBuffer));
StructMemberDecorationList deco;
deco.push_back(create<StructMemberOffsetDecoration>(0));
members.push_back(
create<StructMember>(mod->RegisterSymbol("foo"), "foo", &vec4, deco));
}
StructDecorationList decos;
auto* str = create<ast::Struct>(members, decos);
Struct struct_type(mod->RegisterSymbol("struct_type"), "struct_type", str);
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kUniformBuffer));
EXPECT_EQ(16u, struct_type.BaseAlignment(MemoryLayout::kStorageBuffer));
} }
} // namespace } // namespace

File diff suppressed because it is too large Load Diff

View File

@ -71,12 +71,7 @@ TEST_F(FirstIndexOffsetTest, Error_AlreadyTransformed) {
struct Builder : public ModuleBuilder { struct Builder : public ModuleBuilder {
void Build() override { void Build() override {
AddBuiltinInput("vert_idx", ast::Builtin::kVertexIdx); AddBuiltinInput("vert_idx", ast::Builtin::kVertexIdx);
AddFunction( AddFunction("test", {create<ast::ReturnStatement>(Expr("vert_idx"))});
"test",
{
create<ast::ReturnStatement>(create<ast::IdentifierExpression>(
mod->RegisterSymbol("vert_idx"), "vert_idx")),
});
} }
}; };
@ -116,12 +111,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleVertexIndex) {
struct Builder : public ModuleBuilder { struct Builder : public ModuleBuilder {
void Build() override { void Build() override {
AddBuiltinInput("vert_idx", ast::Builtin::kVertexIdx); AddBuiltinInput("vert_idx", ast::Builtin::kVertexIdx);
AddFunction( AddFunction("test", {create<ast::ReturnStatement>(Expr("vert_idx"))});
"test",
{
create<ast::ReturnStatement>(create<ast::IdentifierExpression>(
mod->RegisterSymbol("vert_idx"), "vert_idx")),
});
} }
}; };
@ -196,12 +186,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleInstanceIndex) {
struct Builder : public ModuleBuilder { struct Builder : public ModuleBuilder {
void Build() override { void Build() override {
AddBuiltinInput("inst_idx", ast::Builtin::kInstanceIdx); AddBuiltinInput("inst_idx", ast::Builtin::kInstanceIdx);
AddFunction( AddFunction("test", {create<ast::ReturnStatement>(Expr("inst_idx"))});
"test",
{
create<ast::ReturnStatement>(create<ast::IdentifierExpression>(
mod->RegisterSymbol("inst_idx"), "inst_idx")),
});
} }
}; };
@ -353,19 +338,8 @@ TEST_F(FirstIndexOffsetTest, NestedCalls) {
struct Builder : public ModuleBuilder { struct Builder : public ModuleBuilder {
void Build() override { void Build() override {
AddBuiltinInput("vert_idx", ast::Builtin::kVertexIdx); AddBuiltinInput("vert_idx", ast::Builtin::kVertexIdx);
AddFunction( AddFunction("func1", {create<ast::ReturnStatement>(Expr("vert_idx"))});
"func1", AddFunction("func2", {create<ast::ReturnStatement>(Call("func1"))});
{
create<ast::ReturnStatement>(create<ast::IdentifierExpression>(
mod->RegisterSymbol("vert_idx"), "vert_idx")),
});
AddFunction("func2",
{
create<ast::ReturnStatement>(create<ast::CallExpression>(
create<ast::IdentifierExpression>(
mod->RegisterSymbol("func1"), "func1"),
ast::ExpressionList{})),
});
} }
}; };

View File

@ -384,10 +384,9 @@ TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Array) {
TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Alias_Array) { TEST_F(TypeDeterminerTest, Expr_ArrayAccessor_Alias_Array) {
ast::type::Array ary(ty.f32, 3, ast::ArrayDecorationList{}); ast::type::Array ary(ty.f32, 3, ast::ArrayDecorationList{});
ast::type::Alias aary(mod->RegisterSymbol("myarrty"), "myarrty", &ary); auto* aary = ty.alias("myarrty", &ary);
auto* var = Var("my_var", ast::StorageClass::kFunction, &aary); mod->AddGlobalVariable(Var("my_var", ast::StorageClass::kFunction, aary));
mod->AddGlobalVariable(var);
EXPECT_TRUE(td()->Determine()); EXPECT_TRUE(td()->Determine());
@ -770,9 +769,8 @@ TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct) {
Member("second_member", ty.f32)}, Member("second_member", ty.f32)},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct st(mod->RegisterSymbol("S"), "S", strct); auto* st = ty.struct_("S", strct);
auto* var = Var("my_struct", ast::StorageClass::kNone, st);
auto* var = Var("my_struct", ast::StorageClass::kNone, &st);
mod->AddGlobalVariable(var); mod->AddGlobalVariable(var);
@ -793,11 +791,9 @@ TEST_F(TypeDeterminerTest, Expr_MemberAccessor_Struct_Alias) {
Member("second_member", ty.f32)}, Member("second_member", ty.f32)},
ast::StructDecorationList{}); ast::StructDecorationList{});
auto st = std::make_unique<ast::type::Struct>(mod->RegisterSymbol("alias"), auto* st = ty.struct_("alias", strct);
"alias", strct); auto* alias = ty.alias("alias", st);
ast::type::Alias alias(mod->RegisterSymbol("alias"), "alias", st.get()); auto* var = Var("my_struct", ast::StorageClass::kNone, alias);
auto* var = Var("my_struct", ast::StorageClass::kNone, &alias);
mod->AddGlobalVariable(var); mod->AddGlobalVariable(var);
@ -873,18 +869,15 @@ TEST_F(TypeDeterminerTest, Expr_Accessor_MultiLevel) {
auto* strctB = auto* strctB =
create<ast::Struct>(ast::StructMemberList{Member("foo", ty.vec4<f32>())}, create<ast::Struct>(ast::StructMemberList{Member("foo", ty.vec4<f32>())},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct stB(mod->RegisterSymbol("B"), "B", strctB); auto* stB = ty.struct_("B", strctB);
ast::type::Vector vecB(&stB, 3); ast::type::Vector vecB(stB, 3);
auto* strctA = create<ast::Struct>( auto* strctA = create<ast::Struct>(
ast::StructMemberList{Member("mem", &vecB)}, ast::StructDecorationList{}); ast::StructMemberList{Member("mem", &vecB)}, ast::StructDecorationList{});
ast::type::Struct stA(mod->RegisterSymbol("A"), "A", strctA); auto* stA = ty.struct_("A", strctA);
auto* var = Var("c", ast::StorageClass::kNone, stA);
auto* var = Var("c", ast::StorageClass::kNone, &stA);
mod->AddGlobalVariable(var); mod->AddGlobalVariable(var);
EXPECT_TRUE(td()->Determine()); EXPECT_TRUE(td()->Determine());
auto* mem = MemberAccessor( auto* mem = MemberAccessor(

View File

@ -45,16 +45,15 @@ TEST_F(ValidateControlBlockTest, SwitchSelectorExpressionNoneIntegerType_Fail) {
auto* var = Var("a", ast::StorageClass::kNone, ty.f32, Expr(3.14f), auto* var = Var("a", ast::StorageClass::kNone, ty.f32, Expr(3.14f),
ast::VariableDecorationList{}); ast::VariableDecorationList{});
auto* cond = create<ast::IdentifierExpression>(
Source{Source::Location{12, 34}}, mod->RegisterSymbol("a"), "a");
ast::CaseSelectorList default_csl;
auto* block_default = create<ast::BlockStatement>(ast::StatementList{});
ast::CaseStatementList body; ast::CaseStatementList body;
body.push_back(create<ast::CaseStatement>(default_csl, block_default)); auto* block_default = create<ast::BlockStatement>(ast::StatementList{});
body.push_back(
create<ast::CaseStatement>(ast::CaseSelectorList{}, block_default));
auto* block = create<ast::BlockStatement>(ast::StatementList{ auto* block = create<ast::BlockStatement>(ast::StatementList{
create<ast::VariableDeclStatement>(var), create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(cond, body), create<ast::SwitchStatement>(Expr(Source{Source::Location{12, 34}}, "a"),
body),
}); });
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
@ -72,16 +71,16 @@ TEST_F(ValidateControlBlockTest, SwitchWithoutDefault_Fail) {
auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2),
ast::VariableDecorationList{}); ast::VariableDecorationList{});
auto* cond = Expr("a");
ast::CaseSelectorList csl; ast::CaseSelectorList csl;
csl.push_back(Literal(1)); csl.push_back(Literal(1));
ast::CaseStatementList body; ast::CaseStatementList body;
body.push_back(create<ast::CaseStatement>( body.push_back(create<ast::CaseStatement>(
csl, create<ast::BlockStatement>(ast::StatementList{}))); csl, create<ast::BlockStatement>(ast::StatementList{})));
auto* block = create<ast::BlockStatement>(ast::StatementList{ auto* block = create<ast::BlockStatement>(ast::StatementList{
create<ast::VariableDeclStatement>(var), create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(Source{Source::Location{12, 34}}, cond, create<ast::SwitchStatement>(Source{Source::Location{12, 34}}, Expr("a"),
body), body),
}); });
@ -103,8 +102,6 @@ TEST_F(ValidateControlBlockTest, SwitchWithTwoDefault_Fail) {
ast::VariableDecorationList{}); ast::VariableDecorationList{});
ast::CaseStatementList switch_body; ast::CaseStatementList switch_body;
auto* cond = Expr("a");
ast::CaseSelectorList default_csl_1; ast::CaseSelectorList default_csl_1;
auto* block_default_1 = create<ast::BlockStatement>(ast::StatementList{}); auto* block_default_1 = create<ast::BlockStatement>(ast::StatementList{});
switch_body.push_back( switch_body.push_back(
@ -122,7 +119,7 @@ TEST_F(ValidateControlBlockTest, SwitchWithTwoDefault_Fail) {
auto* block = create<ast::BlockStatement>(ast::StatementList{ auto* block = create<ast::BlockStatement>(ast::StatementList{
create<ast::VariableDeclStatement>(var), create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(Source{Source::Location{12, 34}}, cond, create<ast::SwitchStatement>(Source{Source::Location{12, 34}}, Expr("a"),
switch_body), switch_body),
}); });
@ -144,8 +141,6 @@ TEST_F(ValidateControlBlockTest,
ast::VariableDecorationList{}); ast::VariableDecorationList{});
ast::CaseStatementList switch_body; ast::CaseStatementList switch_body;
auto* cond = Expr("a");
ast::CaseSelectorList csl; ast::CaseSelectorList csl;
csl.push_back(create<ast::UintLiteral>(ty.u32, 1)); csl.push_back(create<ast::UintLiteral>(ty.u32, 1));
switch_body.push_back(create<ast::CaseStatement>( switch_body.push_back(create<ast::CaseStatement>(
@ -158,7 +153,7 @@ TEST_F(ValidateControlBlockTest,
auto* block = create<ast::BlockStatement>(ast::StatementList{ auto* block = create<ast::BlockStatement>(ast::StatementList{
create<ast::VariableDeclStatement>(var), create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(cond, switch_body), create<ast::SwitchStatement>(Expr("a"), switch_body),
}); });
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
EXPECT_FALSE(v()->ValidateStatements(block)); EXPECT_FALSE(v()->ValidateStatements(block));
@ -180,8 +175,6 @@ TEST_F(ValidateControlBlockTest,
ast::VariableDecorationList{}); ast::VariableDecorationList{});
ast::CaseStatementList switch_body; ast::CaseStatementList switch_body;
auto* cond = Expr("a");
ast::CaseSelectorList csl; ast::CaseSelectorList csl;
csl.push_back(Literal(-1)); csl.push_back(Literal(-1));
switch_body.push_back(create<ast::CaseStatement>( switch_body.push_back(create<ast::CaseStatement>(
@ -194,7 +187,7 @@ TEST_F(ValidateControlBlockTest,
auto* block = create<ast::BlockStatement>(ast::StatementList{ auto* block = create<ast::BlockStatement>(ast::StatementList{
create<ast::VariableDeclStatement>(var), create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(cond, switch_body), create<ast::SwitchStatement>(Expr("a"), switch_body),
}); });
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
EXPECT_FALSE(v()->ValidateStatements(block)); EXPECT_FALSE(v()->ValidateStatements(block));
@ -216,8 +209,6 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueUint_Fail) {
ast::VariableDecorationList{}); ast::VariableDecorationList{});
ast::CaseStatementList switch_body; ast::CaseStatementList switch_body;
auto* cond = Expr("a");
ast::CaseSelectorList csl_1; ast::CaseSelectorList csl_1;
csl_1.push_back(create<ast::UintLiteral>(ty.u32, 0)); csl_1.push_back(create<ast::UintLiteral>(ty.u32, 0));
switch_body.push_back(create<ast::CaseStatement>( switch_body.push_back(create<ast::CaseStatement>(
@ -236,7 +227,7 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueUint_Fail) {
auto* block = create<ast::BlockStatement>(ast::StatementList{ auto* block = create<ast::BlockStatement>(ast::StatementList{
create<ast::VariableDeclStatement>(var), create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(cond, switch_body), create<ast::SwitchStatement>(Expr("a"), switch_body),
}); });
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
EXPECT_FALSE(v()->ValidateStatements(block)); EXPECT_FALSE(v()->ValidateStatements(block));
@ -256,8 +247,6 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueSint_Fail) {
ast::VariableDecorationList{}); ast::VariableDecorationList{});
ast::CaseStatementList switch_body; ast::CaseStatementList switch_body;
auto* cond = Expr("a");
ast::CaseSelectorList csl_1; ast::CaseSelectorList csl_1;
csl_1.push_back(Literal(10)); csl_1.push_back(Literal(10));
switch_body.push_back(create<ast::CaseStatement>( switch_body.push_back(create<ast::CaseStatement>(
@ -278,7 +267,7 @@ TEST_F(ValidateControlBlockTest, NonUniqueCaseSelectorValueSint_Fail) {
auto* block = create<ast::BlockStatement>(ast::StatementList{ auto* block = create<ast::BlockStatement>(ast::StatementList{
create<ast::VariableDeclStatement>(var), create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(cond, switch_body), create<ast::SwitchStatement>(Expr("a"), switch_body),
}); });
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
EXPECT_FALSE(v()->ValidateStatements(block)); EXPECT_FALSE(v()->ValidateStatements(block));
@ -295,7 +284,6 @@ TEST_F(ValidateControlBlockTest, LastClauseLastStatementIsFallthrough_Fail) {
auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2),
ast::VariableDecorationList{}); ast::VariableDecorationList{});
auto* cond = Expr("a");
ast::CaseSelectorList default_csl; ast::CaseSelectorList default_csl;
auto* block_default = create<ast::BlockStatement>( auto* block_default = create<ast::BlockStatement>(
@ -307,7 +295,7 @@ TEST_F(ValidateControlBlockTest, LastClauseLastStatementIsFallthrough_Fail) {
auto* block = create<ast::BlockStatement>(ast::StatementList{ auto* block = create<ast::BlockStatement>(ast::StatementList{
create<ast::VariableDeclStatement>(var), create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(cond, body), create<ast::SwitchStatement>(Expr("a"), body),
}); });
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
EXPECT_FALSE(v()->ValidateStatements(block)); EXPECT_FALSE(v()->ValidateStatements(block));
@ -325,7 +313,6 @@ TEST_F(ValidateControlBlockTest, SwitchCase_Pass) {
auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2), auto* var = Var("a", ast::StorageClass::kNone, ty.i32, Expr(2),
ast::VariableDecorationList{}); ast::VariableDecorationList{});
auto* cond = Expr("a");
ast::CaseSelectorList default_csl; ast::CaseSelectorList default_csl;
auto* block_default = create<ast::BlockStatement>(ast::StatementList{}); auto* block_default = create<ast::BlockStatement>(ast::StatementList{});
ast::CaseStatementList body; ast::CaseStatementList body;
@ -338,7 +325,7 @@ TEST_F(ValidateControlBlockTest, SwitchCase_Pass) {
auto* block = create<ast::BlockStatement>(ast::StatementList{ auto* block = create<ast::BlockStatement>(ast::StatementList{
create<ast::VariableDeclStatement>(var), create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(cond, body), create<ast::SwitchStatement>(Expr("a"), body),
}); });
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
EXPECT_TRUE(v()->ValidateStatements(block)) << v()->error(); EXPECT_TRUE(v()->ValidateStatements(block)) << v()->error();
@ -351,12 +338,10 @@ TEST_F(ValidateControlBlockTest, SwitchCaseAlias_Pass) {
// default: {} // default: {}
// } // }
ast::type::Alias my_int{mod->RegisterSymbol("MyInt"), "MyInt", ty.u32}; auto* my_int = ty.alias("MyInt", ty.u32);
auto* var = Var("a", ast::StorageClass::kNone, my_int, Expr(2u),
auto* var = Var("a", ast::StorageClass::kNone, &my_int, Expr(2u),
ast::VariableDecorationList{}); ast::VariableDecorationList{});
auto* cond = Expr("a");
ast::CaseSelectorList default_csl; ast::CaseSelectorList default_csl;
auto* block_default = create<ast::BlockStatement>(ast::StatementList{}); auto* block_default = create<ast::BlockStatement>(ast::StatementList{});
ast::CaseStatementList body; ast::CaseStatementList body;
@ -365,9 +350,9 @@ TEST_F(ValidateControlBlockTest, SwitchCaseAlias_Pass) {
auto* block = create<ast::BlockStatement>(ast::StatementList{ auto* block = create<ast::BlockStatement>(ast::StatementList{
create<ast::VariableDeclStatement>(var), create<ast::VariableDeclStatement>(var),
create<ast::SwitchStatement>(cond, body), create<ast::SwitchStatement>(Expr("a"), body),
}); });
mod->AddConstructedType(&my_int); mod->AddConstructedType(my_int);
EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error(); EXPECT_TRUE(td()->DetermineStatements(block)) << td()->error();
EXPECT_TRUE(v()->ValidateStatements(block)) << v()->error(); EXPECT_TRUE(v()->ValidateStatements(block)) << v()->error();

View File

@ -277,15 +277,11 @@ TEST_F(ValidatorTest, UsingUndefinedVariableGlobalVariable_Pass) {
mod->AddGlobalVariable(Var("global_var", ast::StorageClass::kPrivate, ty.f32, mod->AddGlobalVariable(Var("global_var", ast::StorageClass::kPrivate, ty.f32,
Expr(2.1f), ast::VariableDecorationList{})); Expr(2.1f), ast::VariableDecorationList{}));
auto* lhs = create<ast::IdentifierExpression>( auto* func = Func(
mod->RegisterSymbol("global_var"), "global_var"); "my_func", ast::VariableList{}, ty.void_,
auto* rhs = Expr(3.14f);
auto* func =
Func("my_func", ast::VariableList{}, ty.void_,
ast::StatementList{ ast::StatementList{
create<ast::AssignmentStatement>( create<ast::AssignmentStatement>(Source{Source::Location{12, 34}},
Source{Source::Location{12, 34}}, lhs, rhs), Expr("global_var"), Expr(3.14f)),
create<ast::ReturnStatement>(), create<ast::ReturnStatement>(),
}, },
ast::FunctionDecorationList{ ast::FunctionDecorationList{

View File

@ -49,9 +49,9 @@ TEST_F(ValidatorTypeTest, RuntimeArrayIsLast_Pass) {
Member("rt", ty.array<f32>())}, Member("rt", ty.array<f32>())},
decos); decos);
ast::type::Struct struct_type(mod->RegisterSymbol("Foo"), "Foo", st); auto* struct_type = ty.struct_("Foo", st);
mod->AddConstructedType(&struct_type); mod->AddConstructedType(struct_type);
EXPECT_TRUE(v()->ValidateConstructedTypes(mod->constructed_types())); EXPECT_TRUE(v()->ValidateConstructedTypes(mod->constructed_types()));
} }
@ -67,9 +67,8 @@ TEST_F(ValidatorTypeTest, RuntimeArrayIsLastNoBlock_Fail) {
Member("rt", ty.array<f32>())}, Member("rt", ty.array<f32>())},
decos); decos);
ast::type::Struct struct_type(mod->RegisterSymbol("Foo"), "Foo", st); auto* struct_type = ty.struct_("Foo", st);
mod->AddConstructedType(struct_type);
mod->AddConstructedType(&struct_type);
EXPECT_FALSE(v()->ValidateConstructedTypes(mod->constructed_types())); EXPECT_FALSE(v()->ValidateConstructedTypes(mod->constructed_types()));
EXPECT_EQ(v()->error(), EXPECT_EQ(v()->error(),
"v-0031: a struct containing a runtime-sized array must be " "v-0031: a struct containing a runtime-sized array must be "
@ -90,9 +89,9 @@ TEST_F(ValidatorTypeTest, RuntimeArrayIsNotLast_Fail) {
Member("vf", ty.f32)}, Member("vf", ty.f32)},
decos); decos);
ast::type::Struct struct_type(mod->RegisterSymbol("Foo"), "Foo", st); auto* struct_type = ty.struct_("Foo", st);
mod->AddConstructedType(&struct_type); mod->AddConstructedType(struct_type);
EXPECT_FALSE(v()->ValidateConstructedTypes(mod->constructed_types())); EXPECT_FALSE(v()->ValidateConstructedTypes(mod->constructed_types()));
EXPECT_EQ(v()->error(), EXPECT_EQ(v()->error(),
"v-0015: runtime arrays may only appear as the last member " "v-0015: runtime arrays may only appear as the last member "
@ -107,16 +106,15 @@ TEST_F(ValidatorTypeTest, AliasRuntimeArrayIsNotLast_Fail) {
// a: u32; // a: u32;
//} //}
ast::type::Alias alias{mod->RegisterSymbol("RTArr"), "RTArr", auto* alias = ty.alias("RTArr", ty.array<u32>());
ty.array<u32>()};
ast::StructDecorationList decos; ast::StructDecorationList decos;
decos.push_back(create<ast::StructBlockDecoration>()); decos.push_back(create<ast::StructBlockDecoration>());
auto* st = create<ast::Struct>( auto* st = create<ast::Struct>(
ast::StructMemberList{Member("b", &alias), Member("a", ty.u32)}, decos); ast::StructMemberList{Member("b", alias), Member("a", ty.u32)}, decos);
ast::type::Struct struct_type(mod->RegisterSymbol("s"), "s", st); auto* struct_type = ty.struct_("s", st);
mod->AddConstructedType(&struct_type); mod->AddConstructedType(struct_type);
EXPECT_FALSE(v()->ValidateConstructedTypes(mod->constructed_types())); EXPECT_FALSE(v()->ValidateConstructedTypes(mod->constructed_types()));
EXPECT_EQ(v()->error(), EXPECT_EQ(v()->error(),
"v-0015: runtime arrays may only appear as the last member " "v-0015: runtime arrays may only appear as the last member "
@ -131,16 +129,15 @@ TEST_F(ValidatorTypeTest, AliasRuntimeArrayIsLast_Pass) {
// b: RTArr; // b: RTArr;
//} //}
ast::type::Alias alias{mod->RegisterSymbol("RTArr"), "RTArr", auto* alias = ty.alias("RTArr", ty.array<u32>());
ty.array<u32>()};
ast::StructDecorationList decos; ast::StructDecorationList decos;
decos.push_back(create<ast::StructBlockDecoration>()); decos.push_back(create<ast::StructBlockDecoration>());
auto* st = create<ast::Struct>( auto* st = create<ast::Struct>(
ast::StructMemberList{Member("a", ty.u32), Member("b", &alias)}, decos); ast::StructMemberList{Member("a", ty.u32), Member("b", alias)}, decos);
ast::type::Struct struct_type(mod->RegisterSymbol("s"), "s", st); auto* struct_type = ty.struct_("s", st);
mod->AddConstructedType(&struct_type); mod->AddConstructedType(struct_type);
EXPECT_TRUE(v()->ValidateConstructedTypes(mod->constructed_types())); EXPECT_TRUE(v()->ValidateConstructedTypes(mod->constructed_types()));
} }

View File

@ -27,17 +27,17 @@ namespace {
using HlslGeneratorImplTest_Alias = TestHelper; using HlslGeneratorImplTest_Alias = TestHelper;
TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_F32) { TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_F32) {
ast::type::Alias alias(mod->RegisterSymbol("a"), "a", ty.f32); auto* alias = ty.alias("a", ty.f32);
ASSERT_TRUE(gen.EmitConstructedType(out, &alias)) << gen.error(); ASSERT_TRUE(gen.EmitConstructedType(out, alias)) << gen.error();
EXPECT_EQ(result(), R"(typedef float a; EXPECT_EQ(result(), R"(typedef float a;
)"); )");
} }
TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_NameCollision) { TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_NameCollision) {
ast::type::Alias alias(mod->RegisterSymbol("float"), "float", ty.f32); auto* alias = ty.alias("float", ty.f32);
ASSERT_TRUE(gen.EmitConstructedType(out, &alias)) << gen.error(); ASSERT_TRUE(gen.EmitConstructedType(out, alias)) << gen.error();
EXPECT_EQ(result(), R"(typedef float float_tint_0; EXPECT_EQ(result(), R"(typedef float float_tint_0;
)"); )");
} }
@ -48,10 +48,10 @@ TEST_F(HlslGeneratorImplTest_Alias, EmitAlias_Struct) {
Member("b", ty.i32, {MemberOffset(4)})}, Member("b", ty.i32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("A"), "A", str); auto* s = ty.struct_("A", str);
ast::type::Alias alias(mod->RegisterSymbol("B"), "B", &s); auto* alias = ty.alias("B", s);
ASSERT_TRUE(gen.EmitConstructedType(out, &alias)) << gen.error(); ASSERT_TRUE(gen.EmitConstructedType(out, alias)) << gen.error();
EXPECT_EQ(result(), R"(struct B { EXPECT_EQ(result(), R"(struct B {
float a; float a;
int b; int b;

View File

@ -258,15 +258,15 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::StructMemberList{Member("coord", ty.vec4<f32>())}, ast::StructMemberList{Member("coord", ty.vec4<f32>())},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Uniforms"), "Uniforms", str); auto* s = ty.struct_("Uniforms", str);
auto* coord_var = Var("uniforms", ast::StorageClass::kUniform, &s, nullptr, auto* coord_var = Var("uniforms", ast::StorageClass::kUniform, s, nullptr,
ast::VariableDecorationList{ ast::VariableDecorationList{
create<ast::BindingDecoration>(0), create<ast::BindingDecoration>(0),
create<ast::SetDecoration>(1), create<ast::SetDecoration>(1),
}); });
mod->AddConstructedType(&s); mod->AddConstructedType(s);
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
mod->AddGlobalVariable(coord_var); mod->AddGlobalVariable(coord_var);
@ -311,8 +311,8 @@ TEST_F(HlslGeneratorImplTest_Function,
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s); ast::type::AccessControl ac(ast::AccessControl::kReadWrite, s);
auto* coord_var = auto* coord_var =
Var("coord", ast::StorageClass::kStorageBuffer, &ac, nullptr, Var("coord", ast::StorageClass::kStorageBuffer, &ac, nullptr,
@ -358,8 +358,8 @@ TEST_F(HlslGeneratorImplTest_Function,
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
ast::type::AccessControl ac(ast::AccessControl::kReadOnly, &s); ast::type::AccessControl ac(ast::AccessControl::kReadOnly, s);
auto* coord_var = auto* coord_var =
Var("coord", ast::StorageClass::kStorageBuffer, &ac, nullptr, Var("coord", ast::StorageClass::kStorageBuffer, &ac, nullptr,
@ -406,8 +406,8 @@ TEST_F(HlslGeneratorImplTest_Function,
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s); ast::type::AccessControl ac(ast::AccessControl::kReadWrite, s);
auto* coord_var = auto* coord_var =
Var("coord", ast::StorageClass::kStorageBuffer, &ac, nullptr, Var("coord", ast::StorageClass::kStorageBuffer, &ac, nullptr,
@ -917,8 +917,8 @@ TEST_F(HlslGeneratorImplTest_Function,
ast::StructMemberList{Member("d", ty.f32, {MemberOffset(0)})}, ast::StructMemberList{Member("d", ty.f32, {MemberOffset(0)})},
ast::StructDecorationList{create<ast::StructBlockDecoration>()}); ast::StructDecorationList{create<ast::StructBlockDecoration>()});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s); ast::type::AccessControl ac(ast::AccessControl::kReadWrite, s);
auto* data_var = Var("data", ast::StorageClass::kStorageBuffer, &ac, nullptr, auto* data_var = Var("data", ast::StorageClass::kStorageBuffer, &ac, nullptr,
ast::VariableDecorationList{ ast::VariableDecorationList{
@ -926,7 +926,7 @@ TEST_F(HlslGeneratorImplTest_Function,
create<ast::SetDecoration>(0), create<ast::SetDecoration>(0),
}); });
mod->AddConstructedType(&s); mod->AddConstructedType(s);
td.RegisterVariableForTesting(data_var); td.RegisterVariableForTesting(data_var);
mod->AddGlobalVariable(data_var); mod->AddGlobalVariable(data_var);

View File

@ -44,10 +44,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
ast::StructMemberList{Member("mem", ty.f32, {MemberOffset(0)})}, ast::StructMemberList{Member("mem", ty.f32, {MemberOffset(0)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Str"), "Str", strct); auto* s = ty.struct_("Str", strct);
auto* str_var = Var("str", ast::StorageClass::kPrivate, s);
auto* str_var = Var("str", ast::StorageClass::kPrivate, &s);
auto* expr = MemberAccessor("str", "mem"); auto* expr = MemberAccessor("str", "mem");
td.RegisterVariableForTesting(str_var); td.RegisterVariableForTesting(str_var);
@ -75,8 +73,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s); auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
auto* expr = MemberAccessor("data", "b"); auto* expr = MemberAccessor("data", "b");
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
@ -105,8 +103,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::StructMemberList{Member("a", ty.i32, {MemberOffset(0)}), ast::StructMemberList{Member("a", ty.i32, {MemberOffset(0)}),
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s); auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
auto* expr = MemberAccessor("data", "a"); auto* expr = MemberAccessor("data", "a");
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
@ -138,11 +136,9 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
Member("a", ty.mat2x3<f32>(), {MemberOffset(4)})}, Member("a", ty.mat2x3<f32>(), {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* b_var = Var("b", ast::StorageClass::kPrivate, ty.mat2x3<f32>()); auto* b_var = Var("b", ast::StorageClass::kPrivate, ty.mat2x3<f32>());
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s);
auto* lhs = MemberAccessor("data", "a"); auto* lhs = MemberAccessor("data", "a");
auto* rhs = Expr("b"); auto* rhs = Expr("b");
@ -185,9 +181,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
Member("a", ty.mat2x3<f32>(), {MemberOffset(4)})}, Member("a", ty.mat2x3<f32>(), {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s);
auto* lhs = MemberAccessor("data", "a"); auto* lhs = MemberAccessor("data", "a");
auto* rhs = Construct(ty.mat2x3<f32>(), ast::ExpressionList{}); auto* rhs = Construct(ty.mat2x3<f32>(), ast::ExpressionList{});
@ -227,9 +222,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
Member("a", ty.mat3x2<f32>(), {MemberOffset(4)})}, Member("a", ty.mat3x2<f32>(), {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s);
auto* expr = MemberAccessor("data", "a"); auto* expr = MemberAccessor("data", "a");
@ -268,8 +262,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
}, },
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s); auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
auto* expr = MemberAccessor("data", "a"); auto* expr = MemberAccessor("data", "a");
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
@ -300,8 +294,8 @@ TEST_F(
ast::StructMemberList{Member("a", ty.mat3x3<f32>(), {MemberOffset(0)})}, ast::StructMemberList{Member("a", ty.mat3x3<f32>(), {MemberOffset(0)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s); auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
auto* expr = MemberAccessor("data", "a"); auto* expr = MemberAccessor("data", "a");
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
@ -333,8 +327,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
Member("a", ty.mat4x3<f32>(), {MemberOffset(16)})}, Member("a", ty.mat4x3<f32>(), {MemberOffset(16)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s); auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
auto* expr = IndexAccessor( auto* expr = IndexAccessor(
IndexAccessor(MemberAccessor("data", "a"), Expr(2)), Expr(1)); IndexAccessor(MemberAccessor("data", "a"), Expr(2)), Expr(1));
@ -366,8 +360,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
auto* str = create<ast::Struct>( auto* str = create<ast::Struct>(
ast::StructMemberList{Member("a", &ary, {MemberOffset(0)})}, ast::StructMemberList{Member("a", &ary, {MemberOffset(0)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s); auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
auto* expr = IndexAccessor(MemberAccessor("data", "a"), Expr(2)); auto* expr = IndexAccessor(MemberAccessor("data", "a"), Expr(2));
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
@ -398,8 +392,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
auto* str = create<ast::Struct>( auto* str = create<ast::Struct>(
ast::StructMemberList{Member("a", &ary, {MemberOffset(0)})}, ast::StructMemberList{Member("a", &ary, {MemberOffset(0)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s); auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
auto* expr = IndexAccessor(MemberAccessor("data", "a"), auto* expr = IndexAccessor(MemberAccessor("data", "a"),
Sub(Add(Expr(2), Expr(4)), Expr(3))); Sub(Add(Expr(2), Expr(4)), Expr(3)));
@ -430,8 +424,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s); auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
gen.register_global(coord_var); gen.register_global(coord_var);
@ -468,9 +462,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::StructMemberList{Member("a", &ary, {MemberOffset(0)})}, ast::StructMemberList{Member("a", &ary, {MemberOffset(0)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s);
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
gen.register_global(coord_var); gen.register_global(coord_var);
@ -504,8 +497,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s); auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
gen.register_global(coord_var); gen.register_global(coord_var);
@ -539,8 +532,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
Member("b", ty.vec3<f32>(), {MemberOffset(16)})}, Member("b", ty.vec3<f32>(), {MemberOffset(16)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s); auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
gen.register_global(coord_var); gen.register_global(coord_var);
@ -571,9 +564,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
Member("b", ty.vec3<f32>(), {MemberOffset(16)})}, Member("b", ty.vec3<f32>(), {MemberOffset(16)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, s);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &s);
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
gen.register_global(coord_var); gen.register_global(coord_var);
@ -615,9 +607,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
}, },
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct data(mod->RegisterSymbol("Data"), "Data", data_str); auto* data = ty.struct_("Data", data_str);
ast::type::Array ary(data, 4,
ast::type::Array ary(&data, 4,
ast::ArrayDecorationList{ ast::ArrayDecorationList{
create<ast::StrideDecoration>(32), create<ast::StrideDecoration>(32),
}); });
@ -626,9 +617,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})}, ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct pre_struct(mod->RegisterSymbol("Pre"), "Pre", pre_str); auto* pre_struct = ty.struct_("Pre", pre_str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, pre_struct);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &pre_struct);
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
gen.register_global(coord_var); gen.register_global(coord_var);
@ -666,18 +656,16 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
}, },
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct data(mod->RegisterSymbol("Data"), "Data", data_str); auto* data = ty.struct_("Data", data_str);
ast::type::Array ary( ast::type::Array ary(
&data, 4, ast::ArrayDecorationList{create<ast::StrideDecoration>(32)}); data, 4, ast::ArrayDecorationList{create<ast::StrideDecoration>(32)});
auto* pre_str = create<ast::Struct>( auto* pre_str = create<ast::Struct>(
ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})}, ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct pre_struct(mod->RegisterSymbol("Pre"), "Pre", pre_str); auto* pre_struct = ty.struct_("Pre", pre_str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, pre_struct);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &pre_struct);
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
gen.register_global(coord_var); gen.register_global(coord_var);
@ -717,9 +705,8 @@ TEST_F(
}, },
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct data(mod->RegisterSymbol("Data"), "Data", data_str); auto* data = ty.struct_("Data", data_str);
ast::type::Array ary(data, 4,
ast::type::Array ary(&data, 4,
ast::ArrayDecorationList{ ast::ArrayDecorationList{
create<ast::StrideDecoration>(32), create<ast::StrideDecoration>(32),
}); });
@ -728,9 +715,8 @@ TEST_F(
ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})}, ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct pre_struct(mod->RegisterSymbol("Pre"), "Pre", pre_str); auto* pre_struct = ty.struct_("Pre", pre_str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, pre_struct);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &pre_struct);
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
gen.register_global(coord_var); gen.register_global(coord_var);
@ -769,9 +755,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
}, },
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct data(mod->RegisterSymbol("Data"), "Data", data_str); auto* data = ty.struct_("Data", data_str);
ast::type::Array ary(data, 4,
ast::type::Array ary(&data, 4,
ast::ArrayDecorationList{ ast::ArrayDecorationList{
create<ast::StrideDecoration>(32), create<ast::StrideDecoration>(32),
}); });
@ -780,9 +765,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})}, ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct pre_struct(mod->RegisterSymbol("Pre"), "Pre", pre_str); auto* pre_struct = ty.struct_("Pre", pre_str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, pre_struct);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &pre_struct);
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
gen.register_global(coord_var); gen.register_global(coord_var);
@ -821,9 +805,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
}, },
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct data(mod->RegisterSymbol("Data"), "Data", data_str); auto* data = ty.struct_("Data", data_str);
ast::type::Array ary(data, 4,
ast::type::Array ary(&data, 4,
ast::ArrayDecorationList{ ast::ArrayDecorationList{
create<ast::StrideDecoration>(32), create<ast::StrideDecoration>(32),
}); });
@ -832,9 +815,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})}, ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct pre_struct(mod->RegisterSymbol("Pre"), "Pre", pre_str); auto* pre_struct = ty.struct_("Pre", pre_str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, pre_struct);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &pre_struct);
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
gen.register_global(coord_var); gen.register_global(coord_var);
@ -877,9 +859,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
}, },
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct data(mod->RegisterSymbol("Data"), "Data", data_str); auto* data = ty.struct_("Data", data_str);
ast::type::Array ary(data, 4,
ast::type::Array ary(&data, 4,
ast::ArrayDecorationList{ ast::ArrayDecorationList{
create<ast::StrideDecoration>(32), create<ast::StrideDecoration>(32),
}); });
@ -888,9 +869,8 @@ TEST_F(HlslGeneratorImplTest_MemberAccessor,
ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})}, ast::StructMemberList{Member("c", &ary, {MemberOffset(0)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct pre_struct(mod->RegisterSymbol("Pre"), "Pre", pre_str); auto* pre_struct = ty.struct_("Pre", pre_str);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, pre_struct);
auto* coord_var = Var("data", ast::StorageClass::kStorageBuffer, &pre_struct);
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
gen.register_global(coord_var); gen.register_global(coord_var);

View File

@ -44,16 +44,16 @@ namespace {
using HlslGeneratorImplTest_Type = TestHelper; using HlslGeneratorImplTest_Type = TestHelper;
TEST_F(HlslGeneratorImplTest_Type, EmitType_Alias) { TEST_F(HlslGeneratorImplTest_Type, EmitType_Alias) {
ast::type::Alias alias(mod->RegisterSymbol("alias"), "alias", ty.f32); auto* alias = ty.alias("alias", ty.f32);
ASSERT_TRUE(gen.EmitType(out, &alias, "")) << gen.error(); ASSERT_TRUE(gen.EmitType(out, alias, "")) << gen.error();
EXPECT_EQ(result(), "alias"); EXPECT_EQ(result(), "alias");
} }
TEST_F(HlslGeneratorImplTest_Type, EmitType_Alias_NameCollision) { TEST_F(HlslGeneratorImplTest_Type, EmitType_Alias_NameCollision) {
ast::type::Alias alias(mod->RegisterSymbol("bool"), "bool", ty.f32); auto* alias = ty.alias("bool", ty.f32);
ASSERT_TRUE(gen.EmitType(out, &alias, "")) << gen.error(); ASSERT_TRUE(gen.EmitType(out, alias, "")) << gen.error();
EXPECT_EQ(result(), "bool_tint_0"); EXPECT_EQ(result(), "bool_tint_0");
} }
@ -137,9 +137,8 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_StructDecl) {
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitStructType(out, s, "S")) << gen.error();
ASSERT_TRUE(gen.EmitStructType(out, &s, "S")) << gen.error();
EXPECT_EQ(result(), R"(struct S { EXPECT_EQ(result(), R"(struct S {
int a; int a;
float b; float b;
@ -153,9 +152,8 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct) {
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitType(out, s, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(out, &s, "")) << gen.error();
EXPECT_EQ(result(), "S"); EXPECT_EQ(result(), "S");
} }
@ -166,9 +164,8 @@ TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_InjectPadding) {
Member("c", ty.f32, {MemberOffset(128)})}, Member("c", ty.f32, {MemberOffset(128)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitType(out, s, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(out, &s, "")) << gen.error();
EXPECT_EQ(result(), R"(struct { EXPECT_EQ(result(), R"(struct {
int8_t pad_0[4]; int8_t pad_0[4];
int a; int a;
@ -184,9 +181,8 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Struct_NameCollision) {
ast::StructMemberList{Member("double", ty.i32), Member("float", ty.f32)}, ast::StructMemberList{Member("double", ty.i32), Member("float", ty.f32)},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitStructType(out, s, "S")) << gen.error();
ASSERT_TRUE(gen.EmitStructType(out, &s, "S")) << gen.error();
EXPECT_EQ(result(), R"(struct S { EXPECT_EQ(result(), R"(struct S {
int double_tint_0; int double_tint_0;
float float_tint_0; float float_tint_0;
@ -204,9 +200,8 @@ TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_WithDecoration) {
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
decos); decos);
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitStructType(out, s, "B")) << gen.error();
ASSERT_TRUE(gen.EmitStructType(out, &s, "B")) << gen.error();
EXPECT_EQ(result(), R"(struct B { EXPECT_EQ(result(), R"(struct B {
int a; int a;
float b; float b;

View File

@ -28,17 +28,17 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitConstructedType_F32) { TEST_F(MslGeneratorImplTest, EmitConstructedType_F32) {
ast::type::Alias alias(mod->RegisterSymbol("a"), "a", ty.f32); auto* alias = ty.alias("a", ty.f32);
ASSERT_TRUE(gen.EmitConstructedType(&alias)) << gen.error(); ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
EXPECT_EQ(gen.result(), R"(typedef float a; EXPECT_EQ(gen.result(), R"(typedef float a;
)"); )");
} }
TEST_F(MslGeneratorImplTest, EmitConstructedType_NameCollision) { TEST_F(MslGeneratorImplTest, EmitConstructedType_NameCollision) {
ast::type::Alias alias(mod->RegisterSymbol("float"), "float", ty.f32); auto* alias = ty.alias("float", ty.f32);
ASSERT_TRUE(gen.EmitConstructedType(&alias)) << gen.error(); ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
EXPECT_EQ(gen.result(), R"(typedef float float_tint_0; EXPECT_EQ(gen.result(), R"(typedef float float_tint_0;
)"); )");
} }
@ -49,9 +49,8 @@ TEST_F(MslGeneratorImplTest, EmitConstructedType_Struct) {
Member("b", ty.i32, {MemberOffset(4)})}, Member("b", ty.i32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("a"), "a", str); auto* s = ty.struct_("a", str);
ASSERT_TRUE(gen.EmitConstructedType(s)) << gen.error();
ASSERT_TRUE(gen.EmitConstructedType(&s)) << gen.error();
EXPECT_EQ(gen.result(), R"(struct a { EXPECT_EQ(gen.result(), R"(struct a {
float a; float a;
int b; int b;
@ -65,10 +64,10 @@ TEST_F(MslGeneratorImplTest, EmitConstructedType_AliasStructIdent) {
Member("b", ty.i32, {MemberOffset(4)})}, Member("b", ty.i32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("b"), "b", str); auto* s = ty.struct_("b", str);
ast::type::Alias alias(mod->RegisterSymbol("a"), "a", &s); auto* alias = ty.alias("a", s);
ASSERT_TRUE(gen.EmitConstructedType(&alias)) << gen.error(); ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
EXPECT_EQ(gen.result(), R"(typedef b a; EXPECT_EQ(gen.result(), R"(typedef b a;
)"); )");
} }

View File

@ -32,27 +32,17 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitExpression_ArrayAccessor) { TEST_F(MslGeneratorImplTest, EmitExpression_ArrayAccessor) {
ast::type::I32 i32; auto* expr = IndexAccessor(Expr("ary"), 5);
auto* lit = create<ast::SintLiteral>(Source{}, &i32, 5);
auto* idx = create<ast::ScalarConstructorExpression>(Source{}, lit);
auto* ary = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("ary"), "ary");
ast::ArrayAccessorExpression expr(Source{}, ary, idx); ASSERT_TRUE(gen.EmitExpression(expr)) << gen.error();
ASSERT_TRUE(gen.EmitExpression(&expr)) << gen.error();
EXPECT_EQ(gen.result(), "ary[5]"); EXPECT_EQ(gen.result(), "ary[5]");
} }
TEST_F(MslGeneratorImplTest, EmitArrayAccessor) { TEST_F(MslGeneratorImplTest, EmitArrayAccessor) {
auto* ary = create<ast::IdentifierExpression>( auto* expr = IndexAccessor(Expr("ary"), Expr("idx"));
Source{}, mod->RegisterSymbol("ary"), "ary");
auto* idx = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("idx"), "idx");
ast::ArrayAccessorExpression expr(Source{}, ary, idx); ASSERT_TRUE(gen.EmitArrayAccessor(expr->As<ast::ArrayAccessorExpression>()))
<< gen.error();
ASSERT_TRUE(gen.EmitArrayAccessor(&expr)) << gen.error();
EXPECT_EQ(gen.result(), "ary[idx]"); EXPECT_EQ(gen.result(), "ary[idx]");
} }

View File

@ -30,12 +30,7 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, Emit_Assign) { TEST_F(MslGeneratorImplTest, Emit_Assign) {
auto* lhs = create<ast::IdentifierExpression>( ast::AssignmentStatement assign(Source{}, Expr("lhs"), Expr("rhs"));
Source{}, mod->RegisterSymbol("lhs"), "lhs");
auto* rhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("rhs"), "rhs");
ast::AssignmentStatement assign(Source{}, lhs, rhs);
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(&assign)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(&assign)) << gen.error();

View File

@ -38,13 +38,7 @@ using MslBinaryTest = TestParamHelper<BinaryData>;
TEST_P(MslBinaryTest, Emit) { TEST_P(MslBinaryTest, Emit) {
auto params = GetParam(); auto params = GetParam();
auto* left = create<ast::IdentifierExpression>( ast::BinaryExpression expr(Source{}, params.op, Expr("left"), Expr("right"));
Source{}, mod->RegisterSymbol("left"), "left");
auto* right = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("right"), "right");
ast::BinaryExpression expr(Source{}, params.op, left, right);
ASSERT_TRUE(gen.EmitExpression(&expr)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(&expr)) << gen.error();
EXPECT_EQ(gen.result(), params.result); EXPECT_EQ(gen.result(), params.result);
} }

View File

@ -30,11 +30,7 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitExpression_Bitcast) { TEST_F(MslGeneratorImplTest, EmitExpression_Bitcast) {
ast::type::F32 f32; ast::BitcastExpression bitcast(Source{}, ty.f32, Expr("id"));
auto* id = create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("id"), "id");
ast::BitcastExpression bitcast(Source{}, &f32, id);
ASSERT_TRUE(gen.EmitExpression(&bitcast)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(&bitcast)) << gen.error();
EXPECT_EQ(gen.result(), "as_type<float>(id)"); EXPECT_EQ(gen.result(), "as_type<float>(id)");
} }

View File

@ -32,59 +32,35 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitExpression_Call_WithoutParams) { TEST_F(MslGeneratorImplTest, EmitExpression_Call_WithoutParams) {
ast::type::Void void_type; auto* call = Call("my_func");
auto* func = Func("my_func", ast::VariableList{}, ty.void_,
auto* id = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("my_func"), "my_func");
ast::CallExpression call(Source{}, id, {});
auto* func = Func("my_func", ast::VariableList{}, &void_type,
ast::StatementList{}, ast::FunctionDecorationList{}); ast::StatementList{}, ast::FunctionDecorationList{});
mod->AddFunction(func); mod->AddFunction(func);
ASSERT_TRUE(gen.EmitExpression(&call)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
EXPECT_EQ(gen.result(), "my_func()"); EXPECT_EQ(gen.result(), "my_func()");
} }
TEST_F(MslGeneratorImplTest, EmitExpression_Call_WithParams) { TEST_F(MslGeneratorImplTest, EmitExpression_Call_WithParams) {
ast::type::Void void_type; auto* call = Call("my_func", "param1", "param2");
auto* func = Func("my_func", ast::VariableList{}, ty.void_,
auto* id = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("my_func"), "my_func");
ast::ExpressionList params;
params.push_back(create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("param1"), "param1"));
params.push_back(create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("param2"), "param2"));
ast::CallExpression call(Source{}, id, params);
auto* func = Func("my_func", ast::VariableList{}, &void_type,
ast::StatementList{}, ast::FunctionDecorationList{}); ast::StatementList{}, ast::FunctionDecorationList{});
mod->AddFunction(func); mod->AddFunction(func);
ASSERT_TRUE(gen.EmitExpression(&call)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
EXPECT_EQ(gen.result(), "my_func(param1, param2)"); EXPECT_EQ(gen.result(), "my_func(param1, param2)");
} }
TEST_F(MslGeneratorImplTest, EmitStatement_Call) { TEST_F(MslGeneratorImplTest, EmitStatement_Call) {
ast::type::Void void_type; auto* call = Call("my_func", "param1", "param2");
auto* func = Func("my_func", ast::VariableList{}, ty.void_,
auto* id = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("my_func"), "my_func");
ast::ExpressionList params;
params.push_back(create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("param1"), "param1"));
params.push_back(create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("param2"), "param2"));
ast::CallStatement call(Source{},
create<ast::CallExpression>(Source{}, id, params));
auto* func = Func("my_func", ast::VariableList{}, &void_type,
ast::StatementList{}, ast::FunctionDecorationList{}); ast::StatementList{}, ast::FunctionDecorationList{});
mod->AddFunction(func); mod->AddFunction(func);
ast::CallStatement expr(Source{}, call);
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(&call)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(&expr)) << gen.error();
EXPECT_EQ(gen.result(), " my_func(param1, param2);\n"); EXPECT_EQ(gen.result(), " my_func(param1, param2);\n");
} }

View File

@ -31,27 +31,20 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitExpression_Cast_Scalar) { TEST_F(MslGeneratorImplTest, EmitExpression_Cast_Scalar) {
ast::type::F32 f32;
ast::ExpressionList params; ast::ExpressionList params;
params.push_back(create<ast::IdentifierExpression>( params.push_back(Expr("id"));
Source{}, mod->RegisterSymbol("id"), "id"));
ast::TypeConstructorExpression cast(Source{}, &f32, params); ast::TypeConstructorExpression cast(Source{}, ty.f32, params);
ASSERT_TRUE(gen.EmitExpression(&cast)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(&cast)) << gen.error();
EXPECT_EQ(gen.result(), "float(id)"); EXPECT_EQ(gen.result(), "float(id)");
} }
TEST_F(MslGeneratorImplTest, EmitExpression_Cast_Vector) { TEST_F(MslGeneratorImplTest, EmitExpression_Cast_Vector) {
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
ast::ExpressionList params; ast::ExpressionList params;
params.push_back(create<ast::IdentifierExpression>( params.push_back(Expr("id"));
Source{}, mod->RegisterSymbol("id"), "id"));
ast::TypeConstructorExpression cast(Source{}, &vec3, params); ast::TypeConstructorExpression cast(Source{}, ty.vec3<f32>(), params);
ASSERT_TRUE(gen.EmitExpression(&cast)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(&cast)) << gen.error();
EXPECT_EQ(gen.result(), "float3(id)"); EXPECT_EQ(gen.result(), "float3(id)");

View File

@ -47,32 +47,13 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Vertex_Input) {
// int bar [[attribute(1)]]; // int bar [[attribute(1)]];
// }; // };
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = auto* foo_var =
create<ast::Variable>(Source{}, // source Var("foo", ast::StorageClass::kInput, ty.f32, nullptr,
"foo", // name ast::VariableDecorationList{create<ast::LocationDecoration>(0)});
ast::StorageClass::kInput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 0),
});
auto* bar_var = auto* bar_var =
create<ast::Variable>(Source{}, // source Var("bar", ast::StorageClass::kInput, ty.i32, nullptr,
"bar", // name ast::VariableDecorationList{create<ast::LocationDecoration>(1)});
ast::StorageClass::kInput, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 1),
});
td.RegisterVariableForTesting(foo_var); td.RegisterVariableForTesting(foo_var);
td.RegisterVariableForTesting(bar_var); td.RegisterVariableForTesting(bar_var);
@ -81,21 +62,11 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Vertex_Input) {
mod->AddGlobalVariable(bar_var); mod->AddGlobalVariable(bar_var);
auto body = ast::StatementList{ auto body = ast::StatementList{
create<ast::AssignmentStatement>( create<ast::AssignmentStatement>(Expr("foo"), Expr("foo")),
Source{}, create<ast::AssignmentStatement>(Expr("bar"), Expr("bar")),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("foo"), "foo"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("foo"), "foo")),
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("bar"), "bar"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("bar"), "bar")),
}; };
auto* func = Func( auto* func = Func(
"vtx_main", ast::VariableList{}, &f32, body, "vtx_main", ast::VariableList{}, ty.f32, body,
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kVertex), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kVertex),
}); });
@ -122,32 +93,13 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Vertex_Output) {
// int bar [[user(locn1)]]; // int bar [[user(locn1)]];
// }; // };
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = auto* foo_var =
create<ast::Variable>(Source{}, // source Var("foo", ast::StorageClass::kOutput, ty.f32, nullptr,
"foo", // name ast::VariableDecorationList{create<ast::LocationDecoration>(0)});
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 0),
});
auto* bar_var = auto* bar_var =
create<ast::Variable>(Source{}, // source Var("bar", ast::StorageClass::kOutput, ty.i32, nullptr,
"bar", // name ast::VariableDecorationList{create<ast::LocationDecoration>(1)});
ast::StorageClass::kOutput, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 1),
});
td.RegisterVariableForTesting(foo_var); td.RegisterVariableForTesting(foo_var);
td.RegisterVariableForTesting(bar_var); td.RegisterVariableForTesting(bar_var);
@ -156,21 +108,11 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Vertex_Output) {
mod->AddGlobalVariable(bar_var); mod->AddGlobalVariable(bar_var);
auto body = ast::StatementList{ auto body = ast::StatementList{
create<ast::AssignmentStatement>( create<ast::AssignmentStatement>(Expr("foo"), Expr("foo")),
Source{}, create<ast::AssignmentStatement>(Expr("bar"), Expr("bar")),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("foo"), "foo"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("foo"), "foo")),
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("bar"), "bar"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("bar"), "bar")),
}; };
auto* func = Func( auto* func = Func(
"vtx_main", ast::VariableList{}, &f32, body, "vtx_main", ast::VariableList{}, ty.f32, body,
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kVertex), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kVertex),
}); });
@ -197,32 +139,13 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Fragment_Input) {
// int bar [[user(locn1)]]; // int bar [[user(locn1)]];
// }; // };
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = auto* foo_var =
create<ast::Variable>(Source{}, // source Var("foo", ast::StorageClass::kInput, ty.f32, nullptr,
"foo", // name ast::VariableDecorationList{create<ast::LocationDecoration>(0)});
ast::StorageClass::kInput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 0),
});
auto* bar_var = auto* bar_var =
create<ast::Variable>(Source{}, // source Var("bar", ast::StorageClass::kInput, ty.i32, nullptr,
"bar", // name ast::VariableDecorationList{create<ast::LocationDecoration>(1)});
ast::StorageClass::kInput, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 1),
});
td.RegisterVariableForTesting(foo_var); td.RegisterVariableForTesting(foo_var);
td.RegisterVariableForTesting(bar_var); td.RegisterVariableForTesting(bar_var);
@ -231,21 +154,11 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Fragment_Input) {
mod->AddGlobalVariable(bar_var); mod->AddGlobalVariable(bar_var);
auto body = ast::StatementList{ auto body = ast::StatementList{
create<ast::AssignmentStatement>( create<ast::AssignmentStatement>(Expr("foo"), Expr("foo")),
Source{}, create<ast::AssignmentStatement>(Expr("bar"), Expr("bar")),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("foo"), "foo"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("foo"), "foo")),
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("bar"), "bar"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("bar"), "bar")),
}; };
auto* func = Func( auto* func = Func(
"main", ast::VariableList{}, &f32, body, "main", ast::VariableList{}, ty.f32, body,
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kFragment), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kFragment),
}); });
@ -272,32 +185,13 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Fragment_Output) {
// int bar [[color(1)]]; // int bar [[color(1)]];
// }; // };
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = auto* foo_var =
create<ast::Variable>(Source{}, // source Var("foo", ast::StorageClass::kOutput, ty.f32, nullptr,
"foo", // name ast::VariableDecorationList{create<ast::LocationDecoration>(0)});
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 0),
});
auto* bar_var = auto* bar_var =
create<ast::Variable>(Source{}, // source Var("bar", ast::StorageClass::kOutput, ty.i32, nullptr,
"bar", // name ast::VariableDecorationList{create<ast::LocationDecoration>(1)});
ast::StorageClass::kOutput, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 1),
});
td.RegisterVariableForTesting(foo_var); td.RegisterVariableForTesting(foo_var);
td.RegisterVariableForTesting(bar_var); td.RegisterVariableForTesting(bar_var);
@ -306,21 +200,11 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Fragment_Output) {
mod->AddGlobalVariable(bar_var); mod->AddGlobalVariable(bar_var);
auto body = ast::StatementList{ auto body = ast::StatementList{
create<ast::AssignmentStatement>( create<ast::AssignmentStatement>(Expr("foo"), Expr("foo")),
Source{}, create<ast::AssignmentStatement>(Expr("bar"), Expr("bar")),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("foo"), "foo"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("foo"), "foo")),
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("bar"), "bar"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("bar"), "bar")),
}; };
auto* func = Func( auto* func = Func(
"main", ast::VariableList{}, &f32, body, "main", ast::VariableList{}, ty.f32, body,
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kFragment), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kFragment),
}); });
@ -344,32 +228,13 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Compute_Input) {
// //
// -> Error, not allowed // -> Error, not allowed
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = auto* foo_var =
create<ast::Variable>(Source{}, // source Var("foo", ast::StorageClass::kInput, ty.f32, nullptr,
"foo", // name ast::VariableDecorationList{create<ast::LocationDecoration>(0)});
ast::StorageClass::kInput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 0),
});
auto* bar_var = auto* bar_var =
create<ast::Variable>(Source{}, // source Var("bar", ast::StorageClass::kInput, ty.i32, nullptr,
"bar", // name ast::VariableDecorationList{create<ast::LocationDecoration>(1)});
ast::StorageClass::kInput, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 1),
});
td.RegisterVariableForTesting(foo_var); td.RegisterVariableForTesting(foo_var);
td.RegisterVariableForTesting(bar_var); td.RegisterVariableForTesting(bar_var);
@ -378,21 +243,11 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Compute_Input) {
mod->AddGlobalVariable(bar_var); mod->AddGlobalVariable(bar_var);
auto body = ast::StatementList{ auto body = ast::StatementList{
create<ast::AssignmentStatement>( create<ast::AssignmentStatement>(Expr("foo"), Expr("foo")),
Source{}, create<ast::AssignmentStatement>(Expr("bar"), Expr("bar")),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("foo"), "foo"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("foo"), "foo")),
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("bar"), "bar"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("bar"), "bar")),
}; };
auto* func = Func( auto* func = Func(
"main", ast::VariableList{}, &f32, body, "main", ast::VariableList{}, ty.f32, body,
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kCompute), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kCompute),
}); });
@ -411,32 +266,13 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Compute_Output) {
// //
// -> Error not allowed // -> Error not allowed
ast::type::F32 f32;
ast::type::I32 i32;
auto* foo_var = auto* foo_var =
create<ast::Variable>(Source{}, // source Var("foo", ast::StorageClass::kOutput, ty.f32, nullptr,
"foo", // name ast::VariableDecorationList{create<ast::LocationDecoration>(0)});
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 0),
});
auto* bar_var = auto* bar_var =
create<ast::Variable>(Source{}, // source Var("bar", ast::StorageClass::kOutput, ty.i32, nullptr,
"bar", // name ast::VariableDecorationList{create<ast::LocationDecoration>(1)});
ast::StorageClass::kOutput, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 1),
});
td.RegisterVariableForTesting(foo_var); td.RegisterVariableForTesting(foo_var);
td.RegisterVariableForTesting(bar_var); td.RegisterVariableForTesting(bar_var);
@ -445,21 +281,11 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Compute_Output) {
mod->AddGlobalVariable(bar_var); mod->AddGlobalVariable(bar_var);
auto body = ast::StatementList{ auto body = ast::StatementList{
create<ast::AssignmentStatement>( create<ast::AssignmentStatement>(Expr("foo"), Expr("foo")),
Source{}, create<ast::AssignmentStatement>(Expr("bar"), Expr("bar")),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("foo"), "foo"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("foo"), "foo")),
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("bar"), "bar"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("bar"), "bar")),
}; };
auto* func = Func( auto* func = Func(
"main", ast::VariableList{}, &f32, body, "main", ast::VariableList{}, ty.f32, body,
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kCompute), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kCompute),
}); });
@ -483,33 +309,15 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Builtins) {
// float depth [[depth(any)]]; // float depth [[depth(any)]];
// }; // };
ast::type::F32 f32; auto* coord_var =
ast::type::Void void_type; Var("coord", ast::StorageClass::kInput, ty.vec4<f32>(), nullptr,
ast::type::Vector vec4(&f32, 4);
auto* coord_var = create<ast::Variable>(
Source{}, // source
"coord", // name
ast::StorageClass::kInput, // storage_class
&vec4, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{ ast::VariableDecorationList{
// decorations create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord)});
create<ast::BuiltinDecoration>(Source{}, ast::Builtin::kFragCoord),
});
auto* depth_var = create<ast::Variable>( auto* depth_var =
Source{}, // source Var("depth", ast::StorageClass::kOutput, ty.f32, nullptr,
"depth", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{ ast::VariableDecorationList{
// decorations create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth)});
create<ast::BuiltinDecoration>(Source{}, ast::Builtin::kFragDepth),
});
td.RegisterVariableForTesting(coord_var); td.RegisterVariableForTesting(coord_var);
td.RegisterVariableForTesting(depth_var); td.RegisterVariableForTesting(depth_var);
@ -517,20 +325,10 @@ TEST_F(MslGeneratorImplTest, Emit_Function_EntryPointData_Builtins) {
mod->AddGlobalVariable(coord_var); mod->AddGlobalVariable(coord_var);
mod->AddGlobalVariable(depth_var); mod->AddGlobalVariable(depth_var);
auto body = ast::StatementList{ auto body = ast::StatementList{create<ast::AssignmentStatement>(
create<ast::AssignmentStatement>( Expr("depth"), MemberAccessor("coord", "x"))};
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("depth"), "depth"),
create<ast::MemberAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("coord"), "coord"),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("x"), "x"))),
};
auto* func = Func( auto* func = Func(
"main", ast::VariableList{}, &void_type, body, "main", ast::VariableList{}, ty.void_, body,
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kFragment), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kFragment),
}); });

File diff suppressed because it is too large Load Diff

View File

@ -26,17 +26,14 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitIdentifierExpression) { TEST_F(MslGeneratorImplTest, EmitIdentifierExpression) {
ast::IdentifierExpression i(Source{}, mod->RegisterSymbol("foo"), "foo"); auto* i = Expr("foo");
ASSERT_TRUE(gen.EmitExpression(i)) << gen.error();
ASSERT_TRUE(gen.EmitExpression(&i)) << gen.error();
EXPECT_EQ(gen.result(), "foo"); EXPECT_EQ(gen.result(), "foo");
} }
TEST_F(MslGeneratorImplTest, EmitIdentifierExpression_Single_WithCollision) { TEST_F(MslGeneratorImplTest, EmitIdentifierExpression_Single_WithCollision) {
ast::IdentifierExpression i(Source{}, mod->RegisterSymbol("virtual"), auto* i = Expr("virtual");
"virtual"); ASSERT_TRUE(gen.EmitExpression(i)) << gen.error();
ASSERT_TRUE(gen.EmitExpression(&i)) << gen.error();
EXPECT_EQ(gen.result(), "virtual_tint_0"); EXPECT_EQ(gen.result(), "virtual_tint_0");
} }

View File

@ -29,11 +29,9 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, Emit_If) { TEST_F(MslGeneratorImplTest, Emit_If) {
auto* cond = create<ast::IdentifierExpression>( auto* cond = Expr("cond");
Source{}, mod->RegisterSymbol("cond"), "cond"); auto* body = create<ast::BlockStatement>(ast::StatementList{
auto* body = create<ast::BlockStatement>( create<ast::ReturnStatement>(),
Source{}, ast::StatementList{
create<ast::ReturnStatement>(Source{}),
}); });
ast::IfStatement i(Source{}, cond, body, ast::ElseStatementList{}); ast::IfStatement i(Source{}, cond, body, ast::ElseStatementList{});
@ -47,22 +45,17 @@ TEST_F(MslGeneratorImplTest, Emit_If) {
} }
TEST_F(MslGeneratorImplTest, Emit_IfWithElseIf) { TEST_F(MslGeneratorImplTest, Emit_IfWithElseIf) {
auto* else_cond = create<ast::IdentifierExpression>( auto* else_cond = Expr("else_cond");
Source{}, mod->RegisterSymbol("else_cond"), "else_cond"); auto* else_body = create<ast::BlockStatement>(ast::StatementList{
auto* else_body = create<ast::BlockStatement>( create<ast::ReturnStatement>(),
Source{}, ast::StatementList{
create<ast::ReturnStatement>(Source{}),
}); });
auto* cond = create<ast::IdentifierExpression>( auto* cond = Expr("cond");
Source{}, mod->RegisterSymbol("cond"), "cond"); auto* body = create<ast::BlockStatement>(ast::StatementList{
auto* body = create<ast::BlockStatement>( create<ast::ReturnStatement>(),
Source{}, ast::StatementList{
create<ast::ReturnStatement>(Source{}),
}); });
ast::IfStatement i( ast::IfStatement i(Source{}, cond, body,
Source{}, cond, body, {create<ast::ElseStatement>(else_cond, else_body)});
{create<ast::ElseStatement>(Source{}, else_cond, else_body)});
gen.increment_indent(); gen.increment_indent();
@ -76,20 +69,16 @@ TEST_F(MslGeneratorImplTest, Emit_IfWithElseIf) {
} }
TEST_F(MslGeneratorImplTest, Emit_IfWithElse) { TEST_F(MslGeneratorImplTest, Emit_IfWithElse) {
auto* else_body = create<ast::BlockStatement>( auto* else_body = create<ast::BlockStatement>(ast::StatementList{
Source{}, ast::StatementList{ create<ast::ReturnStatement>(),
create<ast::ReturnStatement>(Source{}),
}); });
auto* cond = create<ast::IdentifierExpression>( auto* cond = Expr("cond");
Source{}, mod->RegisterSymbol("cond"), "cond"); auto* body = create<ast::BlockStatement>(ast::StatementList{
auto* body = create<ast::BlockStatement>( create<ast::ReturnStatement>(),
Source{}, ast::StatementList{
create<ast::ReturnStatement>(Source{}),
}); });
ast::IfStatement i( ast::IfStatement i(Source{}, cond, body,
Source{}, cond, body, {create<ast::ElseStatement>(nullptr, else_body)});
{create<ast::ElseStatement>(Source{}, nullptr, else_body)});
gen.increment_indent(); gen.increment_indent();
@ -103,30 +92,27 @@ TEST_F(MslGeneratorImplTest, Emit_IfWithElse) {
} }
TEST_F(MslGeneratorImplTest, Emit_IfWithMultiple) { TEST_F(MslGeneratorImplTest, Emit_IfWithMultiple) {
auto* else_cond = create<ast::IdentifierExpression>( auto* else_cond = Expr("else_cond");
Source{}, mod->RegisterSymbol("else_cond"), "else_cond");
auto* else_body = create<ast::BlockStatement>( auto* else_body =
Source{}, ast::StatementList{ create<ast::BlockStatement>(Source{}, ast::StatementList{
create<ast::ReturnStatement>(Source{}), create<ast::ReturnStatement>(),
}); });
auto* else_body_2 = create<ast::BlockStatement>( auto* else_body_2 =
Source{}, ast::StatementList{ create<ast::BlockStatement>(Source{}, ast::StatementList{
create<ast::ReturnStatement>(Source{}), create<ast::ReturnStatement>(),
}); });
auto* cond = create<ast::IdentifierExpression>( auto* cond = Expr("cond");
Source{}, mod->RegisterSymbol("cond"), "cond"); auto* body =
auto* body = create<ast::BlockStatement>( create<ast::BlockStatement>(Source{}, ast::StatementList{
Source{}, ast::StatementList{ create<ast::ReturnStatement>(),
create<ast::ReturnStatement>(Source{}),
}); });
ast::IfStatement i( ast::IfStatement i(Source{}, cond, body,
Source{}, cond, body,
{ {
create<ast::ElseStatement>(Source{}, else_cond, else_body), create<ast::ElseStatement>(else_cond, else_body),
create<ast::ElseStatement>(Source{}, nullptr, else_body_2), create<ast::ElseStatement>(nullptr, else_body_2),
}); });
gen.increment_indent(); gen.increment_indent();

View File

@ -50,22 +50,13 @@ inline std::ostream& operator<<(std::ostream& out, MslImportData data) {
using MslImportData_SingleParamTest = TestParamHelper<MslImportData>; using MslImportData_SingleParamTest = TestParamHelper<MslImportData>;
TEST_P(MslImportData_SingleParamTest, FloatScalar) { TEST_P(MslImportData_SingleParamTest, FloatScalar) {
auto param = GetParam(); auto param = GetParam();
auto* call = Call(param.name, 1.f);
ast::type::F32 f32;
ast::ExpressionList params;
params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
auto* ident = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol(param.name), param.name);
ast::CallExpression call(Source{}, ident, params);
// The call type determination will set the intrinsic data for the ident // The call type determination will set the intrinsic data for the ident
ASSERT_TRUE(td.DetermineResultType(&call)) << td.error(); ASSERT_TRUE(td.DetermineResultType(call)) << td.error();
ASSERT_EQ(gen.generate_builtin_name(ident), ASSERT_EQ(
gen.generate_builtin_name(call->func()->As<ast::IdentifierExpression>()),
std::string("metal::") + param.msl_name); std::string("metal::") + param.msl_name);
} }
INSTANTIATE_TEST_SUITE_P(MslGeneratorImplTest, INSTANTIATE_TEST_SUITE_P(MslGeneratorImplTest,
@ -95,43 +86,20 @@ INSTANTIATE_TEST_SUITE_P(MslGeneratorImplTest,
MslImportData{"trunc", "trunc"})); MslImportData{"trunc", "trunc"}));
TEST_F(MslGeneratorImplTest, MslImportData_SingleParamTest_IntScalar) { TEST_F(MslGeneratorImplTest, MslImportData_SingleParamTest_IntScalar) {
ast::type::I32 i32; auto* expr = Call("abs", 1);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::ExpressionList params; ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
ast::CallExpression expr(Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("abs"), "abs"),
params);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ASSERT_TRUE(gen.EmitCall(&expr)) << gen.error();
EXPECT_EQ(gen.result(), R"(metal::abs(1))"); EXPECT_EQ(gen.result(), R"(metal::abs(1))");
} }
using MslImportData_DualParamTest = TestParamHelper<MslImportData>; using MslImportData_DualParamTest = TestParamHelper<MslImportData>;
TEST_P(MslImportData_DualParamTest, FloatScalar) { TEST_P(MslImportData_DualParamTest, FloatScalar) {
auto param = GetParam(); auto param = GetParam();
auto* expr = Call(param.name, 1.0f, 2.0f);
ast::type::F32 f32; ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
ast::ExpressionList params;
params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.f)));
ast::CallExpression expr(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol(param.name), param.name),
params);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ASSERT_TRUE(gen.EmitCall(&expr)) << gen.error();
EXPECT_EQ(gen.result(), EXPECT_EQ(gen.result(),
std::string("metal::") + param.msl_name + "(1.0f, 2.0f)"); std::string("metal::") + param.msl_name + "(1.0f, 2.0f)");
} }
@ -149,42 +117,10 @@ using MslImportData_DualParam_VectorTest = TestParamHelper<MslImportData>;
TEST_P(MslImportData_DualParam_VectorTest, FloatVector) { TEST_P(MslImportData_DualParam_VectorTest, FloatVector) {
auto param = GetParam(); auto param = GetParam();
ast::type::F32 f32; auto* expr = Call(param.name, Construct(ty.vec3<f32>(), 1.f, 2.f, 3.f),
ast::type::Vector vec(&f32, 3); Construct(ty.vec3<f32>(), 4.f, 5.f, 6.f));
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::ExpressionList type_params; ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
ast::ExpressionList params;
params.push_back(create<ast::TypeConstructorExpression>(
Source{}, &vec,
ast::ExpressionList{
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.f)),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.f)),
}));
params.push_back(create<ast::TypeConstructorExpression>(
Source{}, &vec,
ast::ExpressionList{
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 4.f)),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 5.f)),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 6.f)),
}));
ast::CallExpression expr(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol(param.name), param.name),
params);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ASSERT_TRUE(gen.EmitCall(&expr)) << gen.error();
EXPECT_EQ(gen.result(), std::string("metal::") + param.msl_name + EXPECT_EQ(gen.result(), std::string("metal::") + param.msl_name +
"(float3(1.0f, 2.0f, 3.0f), " "(float3(1.0f, 2.0f, 3.0f), "
"float3(4.0f, 5.0f, 6.0f))"); "float3(4.0f, 5.0f, 6.0f))");
@ -197,22 +133,9 @@ using MslImportData_DualParam_Int_Test = TestParamHelper<MslImportData>;
TEST_P(MslImportData_DualParam_Int_Test, IntScalar) { TEST_P(MslImportData_DualParam_Int_Test, IntScalar) {
auto param = GetParam(); auto param = GetParam();
ast::type::I32 i32; auto* expr = Call(param.name, 1, 2);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::ExpressionList params; ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2)));
ast::CallExpression expr(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol(param.name), param.name),
params);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ASSERT_TRUE(gen.EmitCall(&expr)) << gen.error();
EXPECT_EQ(gen.result(), std::string("metal::") + param.msl_name + "(1, 2)"); EXPECT_EQ(gen.result(), std::string("metal::") + param.msl_name + "(1, 2)");
} }
INSTANTIATE_TEST_SUITE_P(MslGeneratorImplTest, INSTANTIATE_TEST_SUITE_P(MslGeneratorImplTest,
@ -224,24 +147,9 @@ using MslImportData_TripleParamTest = TestParamHelper<MslImportData>;
TEST_P(MslImportData_TripleParamTest, FloatScalar) { TEST_P(MslImportData_TripleParamTest, FloatScalar) {
auto param = GetParam(); auto param = GetParam();
ast::type::F32 f32; auto* expr = Call(param.name, 1.f, 2.f, 3.f);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::ExpressionList params; ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.f)));
params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.f)));
ast::CallExpression expr(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol(param.name), param.name),
params);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ASSERT_TRUE(gen.EmitCall(&expr)) << gen.error();
EXPECT_EQ(gen.result(), EXPECT_EQ(gen.result(),
std::string("metal::") + param.msl_name + "(1.0f, 2.0f, 3.0f)"); std::string("metal::") + param.msl_name + "(1.0f, 2.0f, 3.0f)");
} }
@ -258,24 +166,9 @@ using MslImportData_TripleParam_Int_Test = TestParamHelper<MslImportData>;
TEST_P(MslImportData_TripleParam_Int_Test, IntScalar) { TEST_P(MslImportData_TripleParam_Int_Test, IntScalar) {
auto param = GetParam(); auto param = GetParam();
ast::type::I32 i32; auto* expr = Call(param.name, 1, 2, 3);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::ExpressionList params; ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2)));
params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 3)));
ast::CallExpression expr(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol(param.name), param.name),
params);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ASSERT_TRUE(gen.EmitCall(&expr)) << gen.error();
EXPECT_EQ(gen.result(), EXPECT_EQ(gen.result(),
std::string("metal::") + param.msl_name + "(1, 2, 3)"); std::string("metal::") + param.msl_name + "(1, 2, 3)");
} }
@ -288,31 +181,15 @@ TEST_F(MslGeneratorImplTest, MslImportData_Determinant) {
ast::type::F32 f32; ast::type::F32 f32;
ast::type::Matrix mat(&f32, 3, 3); ast::type::Matrix mat(&f32, 3, 3);
auto* var = auto* var = Var("var", ast::StorageClass::kFunction, &mat);
create<ast::Variable>(Source{}, // source
"var", // name
ast::StorageClass::kFunction, // storage_class
&mat, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::ExpressionList params;
params.push_back(create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("var"), "var"));
ast::CallExpression expr(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("determinant"), "determinant"),
params);
mod->AddGlobalVariable(var); mod->AddGlobalVariable(var);
auto* expr = Call("determinant", "var");
// Register the global // Register the global
ASSERT_TRUE(td.Determine()) << td.error(); ASSERT_TRUE(td.Determine()) << td.error();
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ASSERT_TRUE(gen.EmitCall(&expr)) << gen.error(); ASSERT_TRUE(gen.EmitCall(expr)) << gen.error();
EXPECT_EQ(gen.result(), std::string("metal::determinant(var)")); EXPECT_EQ(gen.result(), std::string("metal::determinant(var)"));
} }

View File

@ -66,39 +66,10 @@ INSTANTIATE_TEST_SUITE_P(
IntrinsicData{ast::Intrinsic::kSelect, "select"})); IntrinsicData{ast::Intrinsic::kSelect, "select"}));
TEST_F(MslGeneratorImplTest, DISABLED_Intrinsic_OuterProduct) { TEST_F(MslGeneratorImplTest, DISABLED_Intrinsic_OuterProduct) {
ast::type::F32 f32; auto* a = Var("a", ast::StorageClass::kNone, ty.vec2<f32>());
ast::type::Vector vec2(&f32, 2); auto* b = Var("b", ast::StorageClass::kNone, ty.vec3<f32>());
ast::type::Vector vec3(&f32, 3);
auto* a =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&vec2, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* b =
create<ast::Variable>(Source{}, // source
"b", // name
ast::StorageClass::kNone, // storage_class
&vec3, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::ExpressionList params;
params.push_back(create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("a"), "a"));
params.push_back(create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("b"), "b"));
ast::CallExpression call(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("outer_product"), "outer_product"),
params);
auto* call = Call("outer_product", "a", "b");
td.RegisterVariableForTesting(a); td.RegisterVariableForTesting(a);
td.RegisterVariableForTesting(b); td.RegisterVariableForTesting(b);
@ -106,10 +77,10 @@ TEST_F(MslGeneratorImplTest, DISABLED_Intrinsic_OuterProduct) {
mod->AddGlobalVariable(b); mod->AddGlobalVariable(b);
ASSERT_TRUE(td.Determine()) << td.error(); ASSERT_TRUE(td.Determine()) << td.error();
ASSERT_TRUE(td.DetermineResultType(&call)) << td.error(); ASSERT_TRUE(td.DetermineResultType(call)) << td.error();
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.EmitExpression(&call)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
EXPECT_EQ(gen.result(), " float3x2(a * b[0], a * b[1], a * b[2])"); EXPECT_EQ(gen.result(), " float3x2(a * b[0], a * b[1], a * b[2])");
} }
@ -118,32 +89,18 @@ TEST_F(MslGeneratorImplTest, Intrinsic_Bad_Name) {
} }
TEST_F(MslGeneratorImplTest, Intrinsic_Call) { TEST_F(MslGeneratorImplTest, Intrinsic_Call) {
ast::type::F32 f32; auto* call = Call("dot", "param1", "param2");
ast::type::Vector vec(&f32, 3);
ast::ExpressionList params; auto* v1 = Var("param1", ast::StorageClass::kFunction, ty.vec2<f32>());
params.push_back(create<ast::IdentifierExpression>( auto* v2 = Var("param2", ast::StorageClass::kFunction, ty.vec2<f32>());
Source{}, mod->RegisterSymbol("param1"), "param1"));
params.push_back(create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("param2"), "param2"));
ast::CallExpression call(Source{}, td.RegisterVariableForTesting(v1);
create<ast::IdentifierExpression>( td.RegisterVariableForTesting(v2);
Source{}, mod->RegisterSymbol("dot"), "dot"),
params);
ast::Variable v1(Source{}, "param1", ast::StorageClass::kFunction, &vec, ASSERT_TRUE(td.DetermineResultType(call)) << td.error();
false, nullptr, ast::VariableDecorationList{});
ast::Variable v2(Source{}, "param2", ast::StorageClass::kFunction, &vec,
false, nullptr, ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v1);
td.RegisterVariableForTesting(&v2);
ASSERT_TRUE(td.DetermineResultType(&call)) << td.error();
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.EmitExpression(&call)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
EXPECT_EQ(gen.result(), " dot(param1, param2)"); EXPECT_EQ(gen.result(), " dot(param1, param2)");
} }

View File

@ -36,9 +36,8 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, Emit_Loop) { TEST_F(MslGeneratorImplTest, Emit_Loop) {
auto* body = create<ast::BlockStatement>( auto* body = create<ast::BlockStatement>(ast::StatementList{
Source{}, ast::StatementList{ create<ast::DiscardStatement>(),
create<ast::DiscardStatement>(Source{}),
}); });
ast::LoopStatement l(Source{}, body, {}); ast::LoopStatement l(Source{}, body, {});
@ -52,13 +51,11 @@ TEST_F(MslGeneratorImplTest, Emit_Loop) {
} }
TEST_F(MslGeneratorImplTest, Emit_LoopWithContinuing) { TEST_F(MslGeneratorImplTest, Emit_LoopWithContinuing) {
auto* body = create<ast::BlockStatement>( auto* body = create<ast::BlockStatement>(ast::StatementList{
Source{}, ast::StatementList{ create<ast::DiscardStatement>(),
create<ast::DiscardStatement>(Source{}),
}); });
auto* continuing = create<ast::BlockStatement>( auto* continuing = create<ast::BlockStatement>(ast::StatementList{
Source{}, ast::StatementList{ create<ast::ReturnStatement>(),
create<ast::ReturnStatement>(Source{}),
}); });
ast::LoopStatement l(Source{}, body, continuing); ast::LoopStatement l(Source{}, body, continuing);
@ -80,30 +77,20 @@ TEST_F(MslGeneratorImplTest, Emit_LoopWithContinuing) {
} }
TEST_F(MslGeneratorImplTest, Emit_LoopNestedWithContinuing) { TEST_F(MslGeneratorImplTest, Emit_LoopNestedWithContinuing) {
ast::type::F32 f32; auto* body = create<ast::BlockStatement>(ast::StatementList{
create<ast::DiscardStatement>(),
auto* body = create<ast::BlockStatement>(
Source{}, ast::StatementList{
create<ast::DiscardStatement>(Source{}),
}); });
auto* continuing = create<ast::BlockStatement>( auto* continuing = create<ast::BlockStatement>(ast::StatementList{
Source{}, ast::StatementList{ create<ast::ReturnStatement>(),
create<ast::ReturnStatement>(Source{}),
}); });
auto* inner = create<ast::LoopStatement>(Source{}, body, continuing); auto* inner = create<ast::LoopStatement>(body, continuing);
body = create<ast::BlockStatement>(Source{}, ast::StatementList{ body = create<ast::BlockStatement>(ast::StatementList{
inner, inner,
}); });
auto* lhs = create<ast::IdentifierExpression>( continuing = create<ast::BlockStatement>(ast::StatementList{
Source{}, mod->RegisterSymbol("lhs"), "lhs"); create<ast::AssignmentStatement>(Expr("lhs"), Expr("rhs")),
auto* rhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("rhs"), "rhs");
continuing = create<ast::BlockStatement>(
Source{}, ast::StatementList{
create<ast::AssignmentStatement>(Source{}, lhs, rhs),
}); });
ast::LoopStatement outer(Source{}, body, continuing); ast::LoopStatement outer(Source{}, body, continuing);
@ -157,42 +144,16 @@ TEST_F(MslGeneratorImplTest, Emit_LoopWithVarUsedInContinuing) {
// } // }
// } // }
ast::type::F32 f32; auto* var = Var("lhs", ast::StorageClass::kFunction, ty.f32, Expr(2.4f),
ast::VariableDecorationList{});
auto* var = create<ast::Variable>(
Source{}, // source
"lhs", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
Source{},
create<ast::FloatLiteral>(Source{}, &f32, 2.4)), // constructor
ast::VariableDecorationList{}); // decorations
auto* body = create<ast::BlockStatement>( auto* body = create<ast::BlockStatement>(
Source{}, ast::StatementList{create<ast::VariableDeclStatement>(var),
ast::StatementList{ create<ast::VariableDeclStatement>(Var(
create<ast::VariableDeclStatement>(Source{}, var), "other", ast::StorageClass::kFunction, ty.f32))});
create<ast::VariableDeclStatement>(
Source{}, create<ast::Variable>(
Source{}, // source
"other", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})), // decorations
});
auto* lhs = create<ast::IdentifierExpression>( auto* continuing = create<ast::BlockStatement>(ast::StatementList{
Source{}, mod->RegisterSymbol("lhs"), "lhs"); create<ast::AssignmentStatement>(Expr("lhs"), Expr("rhs")),
auto* rhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("rhs"), "rhs");
auto* continuing = create<ast::BlockStatement>(
Source{}, ast::StatementList{
create<ast::AssignmentStatement>(Source{}, lhs, rhs),
}); });
gen.increment_indent(); gen.increment_indent();

View File

@ -29,14 +29,9 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor) { TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor) {
auto* str = create<ast::IdentifierExpression>( auto* expr = MemberAccessor("str", "mem");
Source{}, mod->RegisterSymbol("str"), "str");
auto* mem = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("mem"), "mem");
ast::MemberAccessorExpression expr(Source{}, str, mem); ASSERT_TRUE(gen.EmitExpression(expr)) << gen.error();
ASSERT_TRUE(gen.EmitExpression(&expr)) << gen.error();
EXPECT_EQ(gen.result(), "str.mem"); EXPECT_EQ(gen.result(), "str.mem");
} }

View File

@ -31,7 +31,6 @@ using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, Emit_Return) { TEST_F(MslGeneratorImplTest, Emit_Return) {
ast::ReturnStatement r(Source{}); ast::ReturnStatement r(Source{});
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(&r)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(&r)) << gen.error();
@ -39,10 +38,7 @@ TEST_F(MslGeneratorImplTest, Emit_Return) {
} }
TEST_F(MslGeneratorImplTest, Emit_ReturnWithValue) { TEST_F(MslGeneratorImplTest, Emit_ReturnWithValue) {
auto* expr = create<ast::IdentifierExpression>( ast::ReturnStatement r(Source{}, Expr("expr"));
Source{}, mod->RegisterSymbol("expr"), "expr");
ast::ReturnStatement r(Source{}, expr);
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(&r)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(&r)) << gen.error();

View File

@ -33,32 +33,25 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, Emit_Switch) { TEST_F(MslGeneratorImplTest, Emit_Switch) {
auto* def_body = create<ast::BlockStatement>( auto* def_body = create<ast::BlockStatement>(ast::StatementList{
Source{}, ast::StatementList{ create<ast::BreakStatement>(),
create<ast::BreakStatement>(Source{}),
}); });
auto* def = auto* def = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body);
create<ast::CaseStatement>(Source{}, ast::CaseSelectorList{}, def_body);
ast::type::I32 i32;
ast::CaseSelectorList case_val; ast::CaseSelectorList case_val;
case_val.push_back(create<ast::SintLiteral>(Source{}, &i32, 5)); case_val.push_back(Literal(5));
auto* case_body = create<ast::BlockStatement>( auto* case_body = create<ast::BlockStatement>(ast::StatementList{
Source{}, ast::StatementList{ create<ast::BreakStatement>(),
create<ast::BreakStatement>(Source{}),
}); });
auto* case_stmt = create<ast::CaseStatement>(Source{}, case_val, case_body); auto* case_stmt = create<ast::CaseStatement>(case_val, case_body);
ast::CaseStatementList body; ast::CaseStatementList body;
body.push_back(case_stmt); body.push_back(case_stmt);
body.push_back(def); body.push_back(def);
auto* cond = create<ast::IdentifierExpression>( ast::SwitchStatement s(Source{}, Expr("cond"), body);
Source{}, mod->RegisterSymbol("cond"), "cond");
ast::SwitchStatement s(Source{}, cond, body);
gen.increment_indent(); gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(&s)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(&s)) << gen.error();

View File

@ -48,12 +48,10 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, Generate) { TEST_F(MslGeneratorImplTest, Generate) {
ast::type::Void void_type; auto* func =
Func("my_func", ast::VariableList{}, ty.void_, ast::StatementList{},
auto* func = Func(
"my_func", ast::VariableList{}, &void_type, ast::StatementList{},
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kCompute), create<ast::StageDecoration>(ast::PipelineStage::kCompute),
}); });
mod->AddFunction(func); mod->AddFunction(func);
@ -77,10 +75,7 @@ TEST_F(MslGeneratorImplTest, InputStructName_ConflictWithExisting) {
TEST_F(MslGeneratorImplTest, NameConflictWith_InputStructName) { TEST_F(MslGeneratorImplTest, NameConflictWith_InputStructName) {
ASSERT_EQ(gen.generate_name("func_main_in"), "func_main_in"); ASSERT_EQ(gen.generate_name("func_main_in"), "func_main_in");
ASSERT_TRUE(gen.EmitIdentifier(Expr("func_main_in")));
ast::IdentifierExpression ident(Source{}, mod->RegisterSymbol("func_main_in"),
"func_main_in");
ASSERT_TRUE(gen.EmitIdentifier(&ident));
EXPECT_EQ(gen.result(), "func_main_in_0"); EXPECT_EQ(gen.result(), "func_main_in_0");
} }
@ -116,9 +111,8 @@ INSTANTIATE_TEST_SUITE_P(
"thread_position_in_grid"})); "thread_position_in_grid"}));
TEST_F(MslGeneratorImplTest, calculate_alignment_size_alias) { TEST_F(MslGeneratorImplTest, calculate_alignment_size_alias) {
ast::type::F32 f32; auto* alias = ty.alias("a", ty.f32);
ast::type::Alias alias(mod->RegisterSymbol("a"), "a", &f32); EXPECT_EQ(4u, gen.calculate_alignment_size(alias));
EXPECT_EQ(4u, gen.calculate_alignment_size(&alias));
} }
TEST_F(MslGeneratorImplTest, calculate_alignment_size_array) { TEST_F(MslGeneratorImplTest, calculate_alignment_size_array) {
@ -161,9 +155,8 @@ TEST_F(MslGeneratorImplTest, calculate_alignment_size_struct) {
Member("c", ty.f32, {MemberOffset(128)})}, Member("c", ty.f32, {MemberOffset(128)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
EXPECT_EQ(132u, gen.calculate_alignment_size(s));
EXPECT_EQ(132u, gen.calculate_alignment_size(&s));
} }
TEST_F(MslGeneratorImplTest, calculate_alignment_size_struct_of_struct) { TEST_F(MslGeneratorImplTest, calculate_alignment_size_struct_of_struct) {
@ -173,17 +166,16 @@ TEST_F(MslGeneratorImplTest, calculate_alignment_size_struct_of_struct) {
Member("c", ty.f32, {MemberOffset(32)})}, Member("c", ty.f32, {MemberOffset(32)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct inner_s(mod->RegisterSymbol("Inner"), "Inner", inner_str); auto* inner_s = ty.struct_("Inner", inner_str);
auto* outer_str = create<ast::Struct>( auto* outer_str = create<ast::Struct>(
ast::StructMemberList{Member("d", ty.f32, {MemberOffset(0)}), ast::StructMemberList{Member("d", ty.f32, {MemberOffset(0)}),
Member("e", &inner_s, {MemberOffset(32)}), Member("e", inner_s, {MemberOffset(32)}),
Member("f", ty.f32, {MemberOffset(64)})}, Member("f", ty.f32, {MemberOffset(64)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct outer_s(mod->RegisterSymbol("Outer"), "Outer", outer_str); auto* outer_s = ty.struct_("Outer", outer_str);
EXPECT_EQ(80u, gen.calculate_alignment_size(outer_s));
EXPECT_EQ(80u, gen.calculate_alignment_size(&outer_s));
} }
TEST_F(MslGeneratorImplTest, calculate_alignment_size_u32) { TEST_F(MslGeneratorImplTest, calculate_alignment_size_u32) {

View File

@ -47,18 +47,14 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, EmitType_Alias) { TEST_F(MslGeneratorImplTest, EmitType_Alias) {
ast::type::F32 f32; auto* alias = ty.alias("alias", ty.f32);
ast::type::Alias alias(mod->RegisterSymbol("alias"), "alias", &f32); ASSERT_TRUE(gen.EmitType(alias, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(&alias, "")) << gen.error();
EXPECT_EQ(gen.result(), "alias"); EXPECT_EQ(gen.result(), "alias");
} }
TEST_F(MslGeneratorImplTest, EmitType_Alias_NameCollision) { TEST_F(MslGeneratorImplTest, EmitType_Alias_NameCollision) {
ast::type::F32 f32; auto* alias = ty.alias("bool", ty.f32);
ast::type::Alias alias(mod->RegisterSymbol("bool"), "bool", &f32); ASSERT_TRUE(gen.EmitType(alias, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(&alias, "")) << gen.error();
EXPECT_EQ(gen.result(), "bool_tint_0"); EXPECT_EQ(gen.result(), "bool_tint_0");
} }
@ -176,9 +172,8 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct) {
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitType(s, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(&s, "")) << gen.error();
EXPECT_EQ(gen.result(), "S"); EXPECT_EQ(gen.result(), "S");
} }
@ -188,9 +183,9 @@ TEST_F(MslGeneratorImplTest, EmitType_StructDecl) {
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitStructType(&s)) << gen.error(); ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
EXPECT_EQ(gen.result(), R"(struct S { EXPECT_EQ(gen.result(), R"(struct S {
int a; int a;
float b; float b;
@ -207,9 +202,8 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_InjectPadding) {
}, },
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
ASSERT_TRUE(gen.EmitStructType(&s)) << gen.error();
EXPECT_EQ(gen.result(), R"(struct S { EXPECT_EQ(gen.result(), R"(struct S {
int8_t pad_0[4]; int8_t pad_0[4];
int a; int a;
@ -226,9 +220,8 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_NameCollision) {
ast::StructMemberList{Member("main", ty.i32), Member("float", ty.f32)}, ast::StructMemberList{Member("main", ty.i32), Member("float", ty.f32)},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
ASSERT_TRUE(gen.EmitStructType(&s)) << gen.error();
EXPECT_EQ(gen.result(), R"(struct S { EXPECT_EQ(gen.result(), R"(struct S {
int main_tint_0; int main_tint_0;
float float_tint_0; float float_tint_0;
@ -239,15 +232,14 @@ TEST_F(MslGeneratorImplTest, EmitType_Struct_NameCollision) {
// TODO(dsinclair): How to translate [[block]] // TODO(dsinclair): How to translate [[block]]
TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) { TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) {
ast::StructDecorationList decos; ast::StructDecorationList decos;
decos.push_back(create<ast::StructBlockDecoration>(Source{})); decos.push_back(create<ast::StructBlockDecoration>());
auto* str = create<ast::Struct>( auto* str = create<ast::Struct>(
ast::StructMemberList{Member("a", ty.i32), ast::StructMemberList{Member("a", ty.i32),
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
decos); decos);
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitType(s, "")) << gen.error();
ASSERT_TRUE(gen.EmitType(&s, "")) << gen.error();
EXPECT_EQ(gen.result(), R"(struct { EXPECT_EQ(gen.result(), R"(struct {
int a; int a;
float b; float b;

View File

@ -38,11 +38,7 @@ inline std::ostream& operator<<(std::ostream& out, UnaryOpData data) {
using MslUnaryOpTest = TestParamHelper<UnaryOpData>; using MslUnaryOpTest = TestParamHelper<UnaryOpData>;
TEST_P(MslUnaryOpTest, Emit) { TEST_P(MslUnaryOpTest, Emit) {
auto params = GetParam(); auto params = GetParam();
ast::UnaryOpExpression op(Source{}, params.op, Expr("expr"));
auto* expr = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("expr"), "expr");
ast::UnaryOpExpression op(Source{}, params.op, expr);
ASSERT_TRUE(gen.EmitExpression(&op)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(&op)) << gen.error();
EXPECT_EQ(gen.result(), std::string(params.name) + "(expr)"); EXPECT_EQ(gen.result(), std::string(params.name) + "(expr)");
} }

View File

@ -41,16 +41,7 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement) { TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement) {
ast::type::F32 f32; auto* var = Var("a", ast::StorageClass::kNone, ty.f32);
auto* var =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(Source{}, var); ast::VariableDeclStatement stmt(Source{}, var);
gen.increment_indent(); gen.increment_indent();
@ -60,16 +51,7 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement) {
} }
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) { TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) {
ast::type::F32 f32; auto* var = Const("a", ast::StorageClass::kNone, ty.f32);
auto* var =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
true, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(Source{}, var); ast::VariableDeclStatement stmt(Source{}, var);
gen.increment_indent(); gen.increment_indent();
@ -79,18 +61,9 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) {
} }
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Array) { TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Array) {
ast::type::F32 f32; ast::type::Array ary(ty.f32, 5, ast::ArrayDecorationList{});
ast::type::Array ary(&f32, 5, ast::ArrayDecorationList{});
auto* var =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&ary, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* var = Var("a", ast::StorageClass::kNone, &ary);
ast::VariableDeclStatement stmt(Source{}, var); ast::VariableDeclStatement stmt(Source{}, var);
gen.increment_indent(); gen.increment_indent();
@ -105,17 +78,8 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Struct) {
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
auto* var = Var("a", ast::StorageClass::kNone, s);
auto* var =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&s, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(Source{}, var); ast::VariableDeclStatement stmt(Source{}, var);
gen.increment_indent(); gen.increment_indent();
@ -126,18 +90,7 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Struct) {
} }
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Vector) { TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Vector) {
ast::type::F32 f32; auto* var = Var("a", ast::StorageClass::kFunction, ty.vec2<f32>());
ast::type::Vector vec(&f32, 2);
auto* var =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kFunction, // storage_class
&vec, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(Source{}, var); ast::VariableDeclStatement stmt(Source{}, var);
gen.increment_indent(); gen.increment_indent();
@ -147,16 +100,7 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Vector) {
} }
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Matrix) { TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Matrix) {
ast::type::F32 f32; auto* var = Var("a", ast::StorageClass::kFunction, ty.mat3x2<f32>());
ast::type::Matrix mat(&f32, 2, 3);
auto* var =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kFunction, // storage_class
&mat, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(Source{}, var); ast::VariableDeclStatement stmt(Source{}, var);
@ -167,16 +111,7 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Matrix) {
} }
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Private) { TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
ast::type::F32 f32; auto* var = Var("a", ast::StorageClass::kPrivate, ty.f32);
auto* var =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(Source{}, var); ast::VariableDeclStatement stmt(Source{}, var);
gen.increment_indent(); gen.increment_indent();
@ -186,19 +121,8 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
} }
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_Private) { TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_Private) {
auto* ident = create<ast::IdentifierExpression>( auto* var = Var("a", ast::StorageClass::kNone, ty.f32, Expr("initializer"),
Source{}, mod->RegisterSymbol("initializer"), "initializer"); ast::VariableDecorationList{});
ast::type::F32 f32;
auto* var =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
false, // is_const
ident, // constructor
ast::VariableDecorationList{}); // decorations
ast::VariableDeclStatement stmt(Source{}, var); ast::VariableDeclStatement stmt(Source{}, var);
ASSERT_TRUE(gen.EmitStatement(&stmt)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(&stmt)) << gen.error();
@ -207,22 +131,12 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_Private) {
} }
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_ZeroVec) { TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_ZeroVec) {
ast::type::F32 f32;
ast::type::Vector vec(&f32, 3);
ast::ExpressionList values; ast::ExpressionList values;
auto* zero_vec = auto* zero_vec =
create<ast::TypeConstructorExpression>(Source{}, &vec, values); create<ast::TypeConstructorExpression>(Source{}, ty.vec3<f32>(), values);
auto* var =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kNone, // storage_class
&vec, // type
false, // is_const
zero_vec, // constructor
ast::VariableDecorationList{}); // decorations
auto* var = Var("a", ast::StorageClass::kNone, ty.vec3<f32>(), zero_vec,
ast::VariableDecorationList{});
ast::VariableDeclStatement stmt(Source{}, var); ast::VariableDeclStatement stmt(Source{}, var);
ASSERT_TRUE(gen.EmitStatement(&stmt)) << gen.error(); ASSERT_TRUE(gen.EmitStatement(&stmt)) << gen.error();

View File

@ -247,9 +247,8 @@ TEST_F(BuilderTest, MemberAccessor) {
ast::StructMemberList{Member("a", ty.f32), Member("b", ty.f32)}, ast::StructMemberList{Member("a", ty.f32), Member("b", ty.f32)},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); auto* s_type = ty.struct_("my_struct", s);
auto* var = Var("ident", ast::StorageClass::kFunction, s_type);
auto* var = Var("ident", ast::StorageClass::kFunction, &s_type);
auto* expr = MemberAccessor("ident", "b"); auto* expr = MemberAccessor("ident", "b");
@ -287,19 +286,17 @@ TEST_F(BuilderTest, MemberAccessor_Nested) {
// //
// var ident : my_struct // var ident : my_struct
// ident.inner.a // ident.inner.a
ast::type::Struct inner_struct( auto* inner_struct = ty.struct_(
mod->RegisterSymbol("Inner"), "Inner", "Inner", create<ast::Struct>(ast::StructMemberList{Member("a", ty.f32),
create<ast::Struct>( Member("b", ty.f32)},
ast::StructMemberList{Member("a", ty.f32), Member("b", ty.f32)},
ast::StructDecorationList{})); ast::StructDecorationList{}));
ast::type::Struct s_type( auto* s_type = ty.struct_(
mod->RegisterSymbol("my_struct"), "my_struct", "my_struct",
create<ast::Struct>(ast::StructMemberList{Member("inner", &inner_struct)}, create<ast::Struct>(ast::StructMemberList{Member("inner", inner_struct)},
ast::StructDecorationList{})); ast::StructDecorationList{}));
auto* var = Var("ident", ast::StorageClass::kFunction, &s_type); auto* var = Var("ident", ast::StorageClass::kFunction, s_type);
auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "a"); auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "a");
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
@ -338,21 +335,18 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) {
// //
// var ident : my_struct // var ident : my_struct
// ident.inner.a // ident.inner.a
ast::type::Struct inner_struct( auto* inner_struct = ty.struct_(
mod->RegisterSymbol("Inner"), "Inner", "Inner", create<ast::Struct>(ast::StructMemberList{Member("a", ty.f32),
create<ast::Struct>( Member("b", ty.f32)},
ast::StructMemberList{Member("a", ty.f32), Member("b", ty.f32)},
ast::StructDecorationList{})); ast::StructDecorationList{}));
ast::type::Alias alias(mod->RegisterSymbol("Inner"), "Inner", &inner_struct); auto* alias = ty.alias("Inner", inner_struct);
auto* s_type = ty.struct_(
ast::type::Struct s_type( "Outer",
mod->RegisterSymbol("Outer"), "Outer", create<ast::Struct>(ast::StructMemberList{Member("inner", alias)},
create<ast::Struct>(ast::StructMemberList{Member("inner", &alias)},
ast::StructDecorationList{})); ast::StructDecorationList{}));
auto* var = Var("ident", ast::StorageClass::kFunction, &s_type); auto* var = Var("ident", ast::StorageClass::kFunction, s_type);
auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "a"); auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "a");
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
@ -390,24 +384,19 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_LHS) {
// //
// var ident : my_struct // var ident : my_struct
// ident.inner.a = 2.0f; // ident.inner.a = 2.0f;
ast::type::Struct inner_struct( auto* inner_struct = ty.struct_(
mod->RegisterSymbol("Inner"), "Inner", "Inner", create<ast::Struct>(ast::StructMemberList{Member("a", ty.f32),
create<ast::Struct>( Member("b", ty.f32)},
ast::StructMemberList{Member("a", ty.f32), Member("b", ty.f32)},
ast::StructDecorationList{})); ast::StructDecorationList{}));
ast::type::Struct s_type( auto* s_type = ty.struct_(
mod->RegisterSymbol("my_struct"), "my_struct", "my_struct",
create<ast::Struct>(ast::StructMemberList{Member("inner", &inner_struct)}, create<ast::Struct>(ast::StructMemberList{Member("inner", inner_struct)},
ast::StructDecorationList{})); ast::StructDecorationList{}));
auto* var = Var("ident", ast::StorageClass::kFunction, &s_type); auto* var = Var("ident", ast::StorageClass::kFunction, s_type);
auto* expr = create<ast::AssignmentStatement>(
auto* lhs = MemberAccessor(MemberAccessor("ident", "inner"), "a"); MemberAccessor(MemberAccessor("ident", "inner"), "a"), Expr(2.0f));
auto* rhs = Expr(2.0f);
auto* expr = create<ast::AssignmentStatement>(lhs, rhs);
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
@ -447,24 +436,21 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_RHS) {
// var ident : my_struct // var ident : my_struct
// var store : f32 = ident.inner.a // var store : f32 = ident.inner.a
ast::type::Struct inner_struct( auto* inner_struct = ty.struct_(
mod->RegisterSymbol("Inner"), "Inner", "Inner", create<ast::Struct>(ast::StructMemberList{Member("a", ty.f32),
create<ast::Struct>( Member("b", ty.f32)},
ast::StructMemberList{Member("a", ty.f32), Member("b", ty.f32)},
ast::StructDecorationList{})); ast::StructDecorationList{}));
ast::type::Struct s_type( auto* s_type = ty.struct_(
mod->RegisterSymbol("my_struct"), "my_struct", "my_struct",
create<ast::Struct>(ast::StructMemberList{Member("inner", &inner_struct)}, create<ast::Struct>(ast::StructMemberList{Member("inner", inner_struct)},
ast::StructDecorationList{})); ast::StructDecorationList{}));
auto* var = Var("ident", ast::StorageClass::kFunction, &s_type); auto* var = Var("ident", ast::StorageClass::kFunction, s_type);
auto* store = Var("store", ast::StorageClass::kFunction, ty.f32); auto* store = Var("store", ast::StorageClass::kFunction, ty.f32);
auto* lhs = Expr("store");
auto* rhs = MemberAccessor(MemberAccessor("ident", "inner"), "a"); auto* rhs = MemberAccessor(MemberAccessor("ident", "inner"), "a");
auto* expr = create<ast::AssignmentStatement>(Expr("store"), rhs);
auto* expr = create<ast::AssignmentStatement>(lhs, rhs);
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
td.RegisterVariableForTesting(store); td.RegisterVariableForTesting(store);
@ -667,22 +653,18 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) {
auto* s = auto* s =
create<ast::Struct>(ast::StructMemberList{Member("baz", ty.vec3<f32>())}, create<ast::Struct>(ast::StructMemberList{Member("baz", ty.vec3<f32>())},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct c_type(mod->RegisterSymbol("C"), "C", s); auto* c_type = ty.struct_("C", s);
s = create<ast::Struct>(ast::StructMemberList{Member("bar", &c_type)}, s = create<ast::Struct>(ast::StructMemberList{Member("bar", c_type)},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct b_type(mod->RegisterSymbol("B"), "B", s); auto* b_type = ty.struct_("B", s);
ast::type::Array b_ary_type(b_type, 3, ast::ArrayDecorationList{});
ast::type::Array b_ary_type(&b_type, 3, ast::ArrayDecorationList{});
s = create<ast::Struct>(ast::StructMemberList{Member("foo", &b_ary_type)}, s = create<ast::Struct>(ast::StructMemberList{Member("foo", &b_ary_type)},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct a_type(mod->RegisterSymbol("A"), "A", s); auto* a_type = ty.struct_("A", s);
ast::type::Array a_ary_type(&a_type, 2, ast::ArrayDecorationList{});
ast::type::Array a_ary_type(a_type, 2, ast::ArrayDecorationList{});
auto* var = Var("index", ast::StorageClass::kFunction, &a_ary_type); auto* var = Var("index", ast::StorageClass::kFunction, &a_ary_type);
auto* expr = MemberAccessor( auto* expr = MemberAccessor(
MemberAccessor( MemberAccessor(
MemberAccessor( MemberAccessor(

View File

@ -42,24 +42,15 @@ namespace {
using BuilderTest = TestHelper; using BuilderTest = TestHelper;
TEST_F(BuilderTest, Assign_Var) { TEST_F(BuilderTest, Assign_Var) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kOutput, ty.f32);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false, ast::AssignmentStatement assign(Source{}, Expr("var"), Expr(1.f));
nullptr, ast::VariableDecorationList{}); td.RegisterVariableForTesting(v);
auto* ident = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("var"), "var");
auto* val = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f));
ast::AssignmentStatement assign(Source{}, ident, val);
td.RegisterVariableForTesting(&v);
ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error(); EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error();
@ -77,23 +68,14 @@ TEST_F(BuilderTest, Assign_Var) {
} }
TEST_F(BuilderTest, Assign_Var_OutsideFunction_IsError) { TEST_F(BuilderTest, Assign_Var_OutsideFunction_IsError) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kOutput, ty.f32);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false, ast::AssignmentStatement assign(Source{}, Expr("var"), Expr(1.f));
nullptr, ast::VariableDecorationList{}); td.RegisterVariableForTesting(v);
auto* ident =
create<ast::IdentifierExpression>(mod->RegisterSymbol("var"), "var");
auto* val = create<ast::ScalarConstructorExpression>(
create<ast::FloatLiteral>(&f32, 1.0f));
ast::AssignmentStatement assign(Source{}, ident, val);
td.RegisterVariableForTesting(&v);
ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error();
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_FALSE(b.GenerateAssignStatement(&assign)) << b.error(); EXPECT_FALSE(b.GenerateAssignStatement(&assign)) << b.error();
@ -104,25 +86,18 @@ TEST_F(BuilderTest, Assign_Var_OutsideFunction_IsError) {
} }
TEST_F(BuilderTest, Assign_Var_ZeroConstructor) { TEST_F(BuilderTest, Assign_Var_ZeroConstructor) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kOutput, ty.vec3<f32>());
ast::type::Vector vec(&f32, 3);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec, false, auto* val = create<ast::TypeConstructorExpression>(Source{}, ty.vec3<f32>(),
nullptr, ast::VariableDecorationList{}); ast::ExpressionList{});
ast::AssignmentStatement assign(Source{}, Expr("var"), val);
auto* ident = create<ast::IdentifierExpression>( td.RegisterVariableForTesting(v);
Source{}, mod->RegisterSymbol("var"), "var");
ast::ExpressionList vals;
auto* val = create<ast::TypeConstructorExpression>(Source{}, &vec, vals);
ast::AssignmentStatement assign(Source{}, ident, val);
td.RegisterVariableForTesting(&v);
ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error(); EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error();
@ -140,41 +115,20 @@ TEST_F(BuilderTest, Assign_Var_ZeroConstructor) {
} }
TEST_F(BuilderTest, Assign_Var_Complex_ConstructorWithExtract) { TEST_F(BuilderTest, Assign_Var_Complex_ConstructorWithExtract) {
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
ast::type::Vector vec2(&f32, 2);
auto* first = create<ast::TypeConstructorExpression>( auto* first = create<ast::TypeConstructorExpression>(
Source{}, &vec2, Source{}, ty.vec2<f32>(), ast::ExpressionList{Expr(1.f), Expr(2.f)});
ast::ExpressionList{
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.0f)),
});
auto* init = create<ast::TypeConstructorExpression>( auto* init = create<ast::TypeConstructorExpression>(
Source{}, &vec3, Source{}, ty.vec3<f32>(), ast::ExpressionList{first, Expr(3.f)});
ast::ExpressionList{
first,
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)),
});
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false, auto* v = Var("var", ast::StorageClass::kOutput, ty.vec3<f32>());
nullptr, ast::VariableDecorationList{}); ast::AssignmentStatement assign(Source{}, Expr("var"), init);
ast::AssignmentStatement assign( td.RegisterVariableForTesting(v);
Source{},
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("var"),
"var"),
init);
td.RegisterVariableForTesting(&v);
ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error(); EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error();
@ -200,33 +154,18 @@ OpStore %1 %13
} }
TEST_F(BuilderTest, Assign_Var_Complex_Constructor) { TEST_F(BuilderTest, Assign_Var_Complex_Constructor) {
ast::type::F32 f32; auto* init = create<ast::TypeConstructorExpression>(
ast::type::Vector vec3(&f32, 3); Source{}, ty.vec3<f32>(),
ast::ExpressionList{Expr(1.f), Expr(2.f), Expr(3.f)});
ast::ExpressionList vals; auto* v = Var("var", ast::StorageClass::kOutput, ty.vec3<f32>());
vals.push_back(create<ast::ScalarConstructorExpression>( ast::AssignmentStatement assign(Source{}, Expr("var"), init);
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
auto* init = create<ast::TypeConstructorExpression>(Source{}, &vec3, vals); td.RegisterVariableForTesting(v);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false,
nullptr, ast::VariableDecorationList{});
ast::AssignmentStatement assign(
Source{},
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("var"),
"var"),
init);
td.RegisterVariableForTesting(&v);
ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error(); EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error();
@ -258,29 +197,17 @@ TEST_F(BuilderTest, Assign_StructMember) {
ast::StructMemberList{Member("a", ty.f32), Member("b", ty.f32)}, ast::StructMemberList{Member("a", ty.f32), Member("b", ty.f32)},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); auto* s_type = ty.struct_("my_struct", s);
auto* v = Var("ident", ast::StorageClass::kFunction, s_type);
ast::Variable v(Source{}, "ident", ast::StorageClass::kFunction, &s_type, ast::AssignmentStatement assign(Source{}, MemberAccessor("ident", "b"),
false, nullptr, ast::VariableDecorationList{}); Expr(4.f));
td.RegisterVariableForTesting(v);
auto* ident = create<ast::MemberAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("ident"),
"ident"),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("b"),
"b"));
auto* val = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, ty.f32, 4.0f));
ast::AssignmentStatement assign(Source{}, ident, val);
td.RegisterVariableForTesting(&v);
ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error(); EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error();
@ -303,33 +230,19 @@ OpStore %8 %9
} }
TEST_F(BuilderTest, Assign_Vector) { TEST_F(BuilderTest, Assign_Vector) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kOutput, ty.vec3<f32>());
ast::type::Vector vec3(&f32, 3);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false, auto* val = create<ast::TypeConstructorExpression>(
nullptr, ast::VariableDecorationList{}); Source{}, ty.vec3<f32>(),
ast::ExpressionList{Expr(1.f), Expr(1.f), Expr(3.f)});
auto* ident = create<ast::IdentifierExpression>( ast::AssignmentStatement assign(Source{}, Expr("var"), val);
Source{}, mod->RegisterSymbol("var"), "var"); td.RegisterVariableForTesting(v);
ast::ExpressionList vals;
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
auto* val = create<ast::TypeConstructorExpression>(Source{}, &vec3, vals);
ast::AssignmentStatement assign(Source{}, ident, val);
td.RegisterVariableForTesting(&v);
ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error(); EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error();
@ -350,31 +263,18 @@ TEST_F(BuilderTest, Assign_Vector) {
} }
TEST_F(BuilderTest, Assign_Vector_MemberByName) { TEST_F(BuilderTest, Assign_Vector_MemberByName) {
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
// var.y = 1 // var.y = 1
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false, auto* v = Var("var", ast::StorageClass::kOutput, ty.vec3<f32>());
nullptr, ast::VariableDecorationList{});
auto* ident = create<ast::MemberAccessorExpression>( ast::AssignmentStatement assign(Source{}, MemberAccessor("var", "y"),
Source{}, Expr(1.f));
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("var"), td.RegisterVariableForTesting(v);
"var"),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("y"),
"y"));
auto* val = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f));
ast::AssignmentStatement assign(Source{}, ident, val);
td.RegisterVariableForTesting(&v);
ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error(); EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error();
@ -398,32 +298,17 @@ OpStore %9 %10
} }
TEST_F(BuilderTest, Assign_Vector_MemberByIndex) { TEST_F(BuilderTest, Assign_Vector_MemberByIndex) {
ast::type::I32 i32;
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
// var[1] = 1 // var[1] = 1
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &vec3, false, auto* v = Var("var", ast::StorageClass::kOutput, ty.vec3<f32>());
nullptr, ast::VariableDecorationList{});
auto* ident = create<ast::ArrayAccessorExpression>( ast::AssignmentStatement assign(Source{}, IndexAccessor("var", 1), Expr(1.f));
Source{}, td.RegisterVariableForTesting(v);
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("var"),
"var"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
auto* val = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f));
ast::AssignmentStatement assign(Source{}, ident, val);
td.RegisterVariableForTesting(&v);
ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&assign)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error(); EXPECT_TRUE(b.GenerateAssignStatement(&assign)) << b.error();

View File

@ -121,23 +121,14 @@ TEST_P(BinaryArithSignedIntegerTest, Vector) {
TEST_P(BinaryArithSignedIntegerTest, Scalar_Loads) { TEST_P(BinaryArithSignedIntegerTest, Scalar_Loads) {
auto param = GetParam(); auto param = GetParam();
ast::type::I32 i32; auto* var = Var("param", ast::StorageClass::kFunction, ty.i32);
ast::BinaryExpression expr(Source{}, param.op, Expr("param"), Expr("param"));
ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &i32, td.RegisterVariableForTesting(var);
false, nullptr, ast::VariableDecorationList{});
auto* lhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("param"), "param");
auto* rhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("param"), "param");
ast::BinaryExpression expr(Source{}, param.op, lhs, rhs);
td.RegisterVariableForTesting(&var);
EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error(); EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateBinaryExpression(&expr), 7u) << b.error(); EXPECT_EQ(b.GenerateBinaryExpression(&expr), 7u) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
@ -646,26 +637,11 @@ TEST_F(BuilderTest, Binary_Multiply_ScalarVector) {
} }
TEST_F(BuilderTest, Binary_Multiply_MatrixScalar) { TEST_F(BuilderTest, Binary_Multiply_MatrixScalar) {
ast::type::F32 f32; auto* var = Var("mat", ast::StorageClass::kFunction, ty.mat3x3<f32>());
ast::type::Matrix mat3(&f32, 3, 3);
auto* var =
create<ast::Variable>(Source{}, // source
"mat", // name
ast::StorageClass::kFunction, // storage_class
&mat3, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* lhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("mat"), "mat");
auto* rhs = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f));
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
ast::BinaryExpression expr(Source{}, ast::BinaryOp::kMultiply, lhs, rhs); ast::BinaryExpression expr(Source{}, ast::BinaryOp::kMultiply, Expr("mat"),
Expr(1.f));
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
@ -686,25 +662,11 @@ TEST_F(BuilderTest, Binary_Multiply_MatrixScalar) {
} }
TEST_F(BuilderTest, Binary_Multiply_ScalarMatrix) { TEST_F(BuilderTest, Binary_Multiply_ScalarMatrix) {
ast::type::F32 f32; auto* var = Var("mat", ast::StorageClass::kFunction, ty.mat3x3<f32>());
ast::type::Matrix mat3(&f32, 3, 3);
auto* var =
create<ast::Variable>(Source{}, // source
"mat", // name
ast::StorageClass::kFunction, // storage_class
&mat3, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* lhs = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f));
auto* rhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("mat"), "mat");
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
ast::BinaryExpression expr(Source{}, ast::BinaryOp::kMultiply, lhs, rhs); ast::BinaryExpression expr(Source{}, ast::BinaryOp::kMultiply, Expr(1.f),
Expr("mat"));
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@ -726,33 +688,15 @@ TEST_F(BuilderTest, Binary_Multiply_ScalarMatrix) {
} }
TEST_F(BuilderTest, Binary_Multiply_MatrixVector) { TEST_F(BuilderTest, Binary_Multiply_MatrixVector) {
ast::type::F32 f32; auto* var = Var("mat", ast::StorageClass::kFunction, ty.mat3x3<f32>());
ast::type::Vector vec3(&f32, 3); auto* rhs = create<ast::TypeConstructorExpression>(
ast::type::Matrix mat3(&f32, 3, 3); Source{}, ty.vec3<f32>(),
ast::ExpressionList{Expr(1.f), Expr(1.f), Expr(1.f)});
auto* var =
create<ast::Variable>(Source{}, // source
"mat", // name
ast::StorageClass::kFunction, // storage_class
&mat3, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* lhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("mat"), "mat");
ast::ExpressionList vals;
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
auto* rhs = create<ast::TypeConstructorExpression>(Source{}, &vec3, vals);
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
ast::BinaryExpression expr(Source{}, ast::BinaryOp::kMultiply, lhs, rhs); ast::BinaryExpression expr(Source{}, ast::BinaryOp::kMultiply, Expr("mat"),
rhs);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@ -775,34 +719,15 @@ TEST_F(BuilderTest, Binary_Multiply_MatrixVector) {
} }
TEST_F(BuilderTest, Binary_Multiply_VectorMatrix) { TEST_F(BuilderTest, Binary_Multiply_VectorMatrix) {
ast::type::F32 f32; auto* var = Var("mat", ast::StorageClass::kFunction, ty.mat3x3<f32>());
ast::type::Vector vec3(&f32, 3); auto* lhs = create<ast::TypeConstructorExpression>(
ast::type::Matrix mat3(&f32, 3, 3); Source{}, ty.vec3<f32>(),
ast::ExpressionList{Expr(1.f), Expr(1.f), Expr(1.f)});
auto* var =
create<ast::Variable>(Source{}, // source
"mat", // name
ast::StorageClass::kFunction, // storage_class
&mat3, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
ast::ExpressionList vals;
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
auto* lhs = create<ast::TypeConstructorExpression>(Source{}, &vec3, vals);
auto* rhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("mat"), "mat");
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
ast::BinaryExpression expr(Source{}, ast::BinaryOp::kMultiply, lhs, rhs); ast::BinaryExpression expr(Source{}, ast::BinaryOp::kMultiply, lhs,
Expr("mat"));
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@ -825,26 +750,11 @@ TEST_F(BuilderTest, Binary_Multiply_VectorMatrix) {
} }
TEST_F(BuilderTest, Binary_Multiply_MatrixMatrix) { TEST_F(BuilderTest, Binary_Multiply_MatrixMatrix) {
ast::type::F32 f32; auto* var = Var("mat", ast::StorageClass::kFunction, ty.mat3x3<f32>());
ast::type::Vector vec3(&f32, 3);
ast::type::Matrix mat3(&f32, 3, 3);
auto* var =
create<ast::Variable>(Source{}, // source
"mat", // name
ast::StorageClass::kFunction, // storage_class
&mat3, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* lhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("mat"), "mat");
auto* rhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("mat"), "mat");
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
ast::BinaryExpression expr(Source{}, ast::BinaryOp::kMultiply, lhs, rhs); ast::BinaryExpression expr(Source{}, ast::BinaryOp::kMultiply, Expr("mat"),
Expr("mat"));
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@ -913,36 +823,16 @@ OpBranch %7
TEST_F(BuilderTest, Binary_LogicalAnd_WithLoads) { TEST_F(BuilderTest, Binary_LogicalAnd_WithLoads) {
ast::type::Bool bool_type; ast::type::Bool bool_type;
auto* a_var = create<ast::Variable>( auto* a_var = Var("a", ast::StorageClass::kFunction, ty.bool_, Expr(true),
Source{}, // source ast::VariableDecorationList{});
"a", // name auto* b_var = Var("b", ast::StorageClass::kFunction, ty.bool_, Expr(false),
ast::StorageClass::kFunction, // storage_class ast::VariableDecorationList{});
&bool_type, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
Source{},
create<ast::BoolLiteral>(Source{}, &bool_type, true)), // constructor
ast::VariableDecorationList{}); // decorations
auto* b_var = create<ast::Variable>(
Source{}, // source
"b", // name
ast::StorageClass::kFunction, // storage_class
&bool_type, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type,
false)), // constructor
ast::VariableDecorationList{}); // decorations
auto* lhs = create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("a"), "a");
auto* rhs = create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("b"), "b");
td.RegisterVariableForTesting(a_var); td.RegisterVariableForTesting(a_var);
td.RegisterVariableForTesting(b_var); td.RegisterVariableForTesting(b_var);
ast::BinaryExpression expr(Source{}, ast::BinaryOp::kLogicalAnd, lhs, rhs); ast::BinaryExpression expr(Source{}, ast::BinaryOp::kLogicalAnd, Expr("a"),
Expr("b"));
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@ -1115,36 +1005,16 @@ OpBranch %7
TEST_F(BuilderTest, Binary_LogicalOr_WithLoads) { TEST_F(BuilderTest, Binary_LogicalOr_WithLoads) {
ast::type::Bool bool_type; ast::type::Bool bool_type;
auto* a_var = create<ast::Variable>( auto* a_var = Var("a", ast::StorageClass::kFunction, ty.bool_, Expr(true),
Source{}, // source ast::VariableDecorationList{});
"a", // name auto* b_var = Var("b", ast::StorageClass::kFunction, ty.bool_, Expr(false),
ast::StorageClass::kFunction, // storage_class ast::VariableDecorationList{});
&bool_type, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
Source{},
create<ast::BoolLiteral>(Source{}, &bool_type, true)), // constructor
ast::VariableDecorationList{}); // decorations
auto* b_var = create<ast::Variable>(
Source{}, // source
"b", // name
ast::StorageClass::kFunction, // storage_class
&bool_type, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type,
false)), // constructor
ast::VariableDecorationList{}); // decorations
auto* lhs = create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("a"), "a");
auto* rhs = create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("b"), "b");
td.RegisterVariableForTesting(a_var); td.RegisterVariableForTesting(a_var);
td.RegisterVariableForTesting(b_var); td.RegisterVariableForTesting(b_var);
ast::BinaryExpression expr(Source{}, ast::BinaryOp::kLogicalOr, lhs, rhs); ast::BinaryExpression expr(Source{}, ast::BinaryOp::kLogicalOr, Expr("a"),
Expr("b"));
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();

View File

@ -43,47 +43,16 @@ TEST_F(BuilderTest, Block) {
Source{}, Source{},
ast::StatementList{ ast::StatementList{
create<ast::VariableDeclStatement>( create<ast::VariableDeclStatement>(
Source{}, create<ast::Variable>( Source{}, Var("var", ast::StorageClass::kFunction, ty.f32)),
Source{}, // source create<ast::AssignmentStatement>(Source{}, Expr("var"), Expr(2.f))});
"var", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})),
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("var"), "var"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.0f))),
}); // decorations
ast::BlockStatement outer( ast::BlockStatement outer(
Source{}, Source{},
ast::StatementList{ ast::StatementList{
create<ast::VariableDeclStatement>( create<ast::VariableDeclStatement>(
Source{}, create<ast::Variable>( Source{}, Var("var", ast::StorageClass::kFunction, ty.f32)),
Source{}, // source create<ast::AssignmentStatement>(Source{}, Expr("var"), Expr(1.f)),
"var", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})), // decorations
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("var"), "var"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f))),
inner, inner,
create<ast::AssignmentStatement>( create<ast::AssignmentStatement>(Source{}, Expr("var"), Expr(3.f))});
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("var"), "var"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f))),
});
ASSERT_TRUE(td.DetermineResultType(&outer)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&outer)) << td.error();

View File

@ -44,62 +44,26 @@ TEST_F(BuilderTest, Expression_Call) {
ast::type::Void void_type; ast::type::Void void_type;
ast::VariableList func_params; ast::VariableList func_params;
func_params.push_back( func_params.push_back(Var("a", ast::StorageClass::kFunction, ty.f32));
create<ast::Variable>(Source{}, // source func_params.push_back(Var("b", ast::StorageClass::kFunction, ty.f32));
"a", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})); // decorations
func_params.push_back(
create<ast::Variable>(Source{}, // source
"b", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})); // decorations
auto* body = create<ast::BlockStatement>( auto* a_func = Func(
Source{}, "a_func", func_params, ty.f32,
ast::StatementList{ ast::StatementList{create<ast::ReturnStatement>(Source{}, Add("a", "b"))},
create<ast::ReturnStatement>(
Source{}, create<ast::BinaryExpression>(
Source{}, ast::BinaryOp::kAdd,
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("a"), "a"),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("b"), "b"))),
});
ast::Function a_func(Source{}, mod->RegisterSymbol("a_func"), "a_func",
func_params, &f32, body, ast::FunctionDecorationList{});
ast::Function func(
Source{}, mod->RegisterSymbol("main"), "main", {}, &void_type,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ast::ExpressionList call_params; auto* func = Func("main", {}, ty.void_, ast::StatementList{},
call_params.push_back(create<ast::ScalarConstructorExpression>( ast::FunctionDecorationList{});
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
call_params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
ast::CallExpression expr( auto* expr = Call("a_func", 1.f, 1.f);
Source{}, ASSERT_TRUE(td.DetermineFunction(func)) << td.error();
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("a_func"), ASSERT_TRUE(td.DetermineFunction(a_func)) << td.error();
"a_func"), ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
call_params);
ASSERT_TRUE(td.DetermineFunction(&func)) << td.error(); ASSERT_TRUE(b.GenerateFunction(a_func)) << b.error();
ASSERT_TRUE(td.DetermineFunction(&a_func)) << td.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ASSERT_TRUE(b.GenerateFunction(&a_func)) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 14u) << b.error();
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(&expr), 14u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func" EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func"
OpName %4 "a" OpName %4 "a"
OpName %5 "b" OpName %5 "b"
@ -127,66 +91,26 @@ OpFunctionEnd
} }
TEST_F(BuilderTest, Statement_Call) { TEST_F(BuilderTest, Statement_Call) {
ast::type::F32 f32;
ast::type::Void void_type;
ast::VariableList func_params; ast::VariableList func_params;
func_params.push_back( func_params.push_back(Var("a", ast::StorageClass::kFunction, ty.f32));
create<ast::Variable>(Source{}, // source func_params.push_back(Var("b", ast::StorageClass::kFunction, ty.f32));
"a", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})); // decorations
func_params.push_back(
create<ast::Variable>(Source{}, // source
"b", // name
ast::StorageClass::kFunction, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{})); // decorations
auto* body = create<ast::BlockStatement>( auto* a_func = Func(
Source{}, "a_func", func_params, ty.void_,
ast::StatementList{ ast::StatementList{create<ast::ReturnStatement>(Source{}, Add("a", "b"))},
create<ast::ReturnStatement>(
Source{}, create<ast::BinaryExpression>(
Source{}, ast::BinaryOp::kAdd,
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("a"), "a"),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("b"), "b"))),
});
ast::Function a_func(Source{}, mod->RegisterSymbol("a_func"), "a_func",
func_params, &void_type, body,
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ast::Function func( auto* func = Func("main", {}, ty.void_, ast::StatementList{},
Source{}, mod->RegisterSymbol("main"), "main", {}, &void_type,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ast::ExpressionList call_params; ast::CallStatement expr(Source{}, Call("a_func", 1.f, 1.f));
call_params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
call_params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.f)));
ast::CallStatement expr( ASSERT_TRUE(td.DetermineFunction(func)) << td.error();
Source{}, create<ast::CallExpression>( ASSERT_TRUE(td.DetermineFunction(a_func)) << td.error();
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("a_func"), "a_func"),
call_params));
ASSERT_TRUE(td.DetermineFunction(&func)) << td.error();
ASSERT_TRUE(td.DetermineFunction(&a_func)) << td.error();
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ASSERT_TRUE(b.GenerateFunction(&a_func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(a_func)) << b.error();
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_TRUE(b.GenerateStatement(&expr)) << b.error(); EXPECT_TRUE(b.GenerateStatement(&expr)) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(OpName %4 "a_func" EXPECT_EQ(DumpBuilder(b), R"(OpName %4 "a_func"

View File

@ -114,9 +114,8 @@ TEST_F(SpvBuilderConstructorTest, Type_WithAlias) {
// type Int = i32 // type Int = i32
// cast<Int>(2.3f) // cast<Int>(2.3f)
ast::type::Alias alias(mod->RegisterSymbol("Int"), "Int", ty.i32); auto* alias = ty.alias("Int", ty.i32);
ast::TypeConstructorExpression cast(Source{}, alias, ExprList(2.3f));
ast::TypeConstructorExpression cast(Source{}, &alias, ExprList(2.3f));
ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&cast)) << td.error();
@ -959,10 +958,9 @@ TEST_F(SpvBuilderConstructorTest, Type_Struct) {
Member("b", ty.vec3<f32>()), Member("b", ty.vec3<f32>()),
}, },
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); auto* s_type = ty.struct_("my_struct", s);
auto* t = Construct(&s_type, 2.0f, vec3<f32>(2.0f, 2.0f, 2.0f));
auto* t = Construct(s_type, 2.0f, vec3<f32>(2.0f, 2.0f, 2.0f));
EXPECT_TRUE(td.DetermineResultType(t)) << td.error(); EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
@ -1096,10 +1094,8 @@ TEST_F(SpvBuilderConstructorTest, Type_ZeroInit_Struct) {
Member("a", ty.f32), Member("a", ty.f32),
}, },
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); auto* s_type = ty.struct_("my_struct", s);
auto* t = Construct(s_type);
auto* t = Construct(&s_type);
EXPECT_TRUE(td.DetermineResultType(t)) << td.error(); EXPECT_TRUE(td.DetermineResultType(t)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
@ -1510,10 +1506,8 @@ TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Struct) {
Member("b", ty.vec3<f32>()), Member("b", ty.vec3<f32>()),
}, },
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); auto* s_type = ty.struct_("my_struct", s);
auto* t = Construct(s_type, 2.f, vec3<f32>(2.f, 2.f, 2.f));
auto* t = Construct(&s_type, 2.f, vec3<f32>(2.f, 2.f, 2.f));
ASSERT_TRUE(td.DetermineResultType(t)) << td.error(); ASSERT_TRUE(td.DetermineResultType(t)) << td.error();
EXPECT_TRUE(b.is_constructor_const(t, false)); EXPECT_TRUE(b.is_constructor_const(t, false));
@ -1529,9 +1523,8 @@ TEST_F(SpvBuilderConstructorTest,
}, },
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); auto* s_type = ty.struct_("my_struct", s);
auto* t = Construct(s_type, 2.f, "a", 2.f);
auto* t = Construct(&s_type, 2.f, "a", 2.f);
Var("a", ast::StorageClass::kPrivate, ty.f32); Var("a", ast::StorageClass::kPrivate, ty.f32);
Var("b", ast::StorageClass::kPrivate, ty.f32); Var("b", ast::StorageClass::kPrivate, ty.f32);

View File

@ -39,16 +39,13 @@ namespace {
using BuilderTest = TestHelper; using BuilderTest = TestHelper;
TEST_F(BuilderTest, FunctionDecoration_Stage) { TEST_F(BuilderTest, FunctionDecoration_Stage) {
ast::type::Void void_type; auto* func = Func(
"main", {}, ty.void_, ast::StatementList{},
ast::Function func(
Source{}, mod->RegisterSymbol("main"), "main", {}, &void_type,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kVertex), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kVertex),
}); });
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(DumpInstructions(b.entry_points()), EXPECT_EQ(DumpInstructions(b.entry_points()),
R"(OpEntryPoint Vertex %3 "main" R"(OpEntryPoint Vertex %3 "main"
)"); )");
@ -66,16 +63,12 @@ using FunctionDecoration_StageTest = TestParamHelper<FunctionStageData>;
TEST_P(FunctionDecoration_StageTest, Emit) { TEST_P(FunctionDecoration_StageTest, Emit) {
auto params = GetParam(); auto params = GetParam();
ast::type::Void void_type; auto* func = Func("main", {}, ty.void_, ast::StatementList{},
ast::Function func(
Source{}, mod->RegisterSymbol("main"), "main", {}, &void_type,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, params.stage), create<ast::StageDecoration>(Source{}, params.stage),
}); });
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
auto preamble = b.entry_points(); auto preamble = b.entry_points();
ASSERT_GE(preamble.size(), 1u); ASSERT_GE(preamble.size(), 1u);
@ -98,37 +91,15 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUnusedInterfaceIds) {
ast::type::F32 f32; ast::type::F32 f32;
ast::type::Void void_type; ast::type::Void void_type;
ast::Function func( auto* func = Func(
Source{}, mod->RegisterSymbol("main"), "main", {}, &void_type, "main", {}, ty.void_, ast::StatementList{},
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kVertex), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kVertex),
}); });
auto* v_in = auto* v_in = Var("my_in", ast::StorageClass::kInput, ty.f32);
create<ast::Variable>(Source{}, // source auto* v_out = Var("my_out", ast::StorageClass::kOutput, ty.f32);
"my_in", // name auto* v_wg = Var("my_wg", ast::StorageClass::kWorkgroup, ty.f32);
ast::StorageClass::kInput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* v_out =
create<ast::Variable>(Source{}, // source
"my_out", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* v_wg =
create<ast::Variable>(Source{}, // source
"my_wg", // name
ast::StorageClass::kWorkgroup, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error();
@ -138,7 +109,7 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUnusedInterfaceIds) {
mod->AddGlobalVariable(v_out); mod->AddGlobalVariable(v_out);
mod->AddGlobalVariable(v_wg); mod->AddGlobalVariable(v_wg);
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_in" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_in"
OpName %4 "my_out" OpName %4 "my_out"
OpName %7 "my_wg" OpName %7 "my_wg"
@ -161,69 +132,29 @@ OpName %11 "main"
} }
TEST_F(BuilderTest, FunctionDecoration_Stage_WithUsedInterfaceIds) { TEST_F(BuilderTest, FunctionDecoration_Stage_WithUsedInterfaceIds) {
ast::type::F32 f32; auto* func = Func(
ast::type::Void void_type; "main", {}, ty.void_,
ast::StatementList{create<ast::AssignmentStatement>(
auto* body = create<ast::BlockStatement>( Source{}, Expr("my_out"), Expr("my_in")),
Source{}, ast::StatementList{
create<ast::AssignmentStatement>( create<ast::AssignmentStatement>(
Source{}, Source{}, Expr("my_wg"), Expr("my_wg")),
create<ast::IdentifierExpression>( // Add duplicate usages so we show they don't get
Source{}, mod->RegisterSymbol("my_out"), "my_out"), // output multiple times.
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("my_in"), "my_in")),
create<ast::AssignmentStatement>( create<ast::AssignmentStatement>(
Source{}, Source{}, Expr("my_out"), Expr("my_in"))},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("my_wg"), "my_wg"),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("my_wg"), "my_wg")),
// Add duplicate usages so we show they don't get output
// multiple times.
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("my_out"), "my_out"),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("my_in"), "my_in")),
});
ast::Function func(
Source{}, mod->RegisterSymbol("main"), "main", {}, &void_type, body,
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kVertex), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kVertex),
}); });
auto* v_in = auto* v_in = Var("my_in", ast::StorageClass::kInput, ty.f32);
create<ast::Variable>(Source{}, // source auto* v_out = Var("my_out", ast::StorageClass::kOutput, ty.f32);
"my_in", // name auto* v_wg = Var("my_wg", ast::StorageClass::kWorkgroup, ty.f32);
ast::StorageClass::kInput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* v_out =
create<ast::Variable>(Source{}, // source
"my_out", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* v_wg =
create<ast::Variable>(Source{}, // source
"my_wg", // name
ast::StorageClass::kWorkgroup, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
td.RegisterVariableForTesting(v_in); td.RegisterVariableForTesting(v_in);
td.RegisterVariableForTesting(v_out); td.RegisterVariableForTesting(v_out);
td.RegisterVariableForTesting(v_wg); td.RegisterVariableForTesting(v_wg);
ASSERT_TRUE(td.DetermineFunction(&func)) << td.error(); ASSERT_TRUE(td.DetermineFunction(func)) << td.error();
EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v_in)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v_out)) << b.error();
@ -233,7 +164,7 @@ TEST_F(BuilderTest, FunctionDecoration_Stage_WithUsedInterfaceIds) {
mod->AddGlobalVariable(v_out); mod->AddGlobalVariable(v_out);
mod->AddGlobalVariable(v_wg); mod->AddGlobalVariable(v_wg);
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_in" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_in"
OpName %4 "my_out" OpName %4 "my_out"
OpName %7 "my_wg" OpName %7 "my_wg"
@ -256,73 +187,60 @@ OpName %11 "main"
} }
TEST_F(BuilderTest, FunctionDecoration_ExecutionMode_Fragment_OriginUpperLeft) { TEST_F(BuilderTest, FunctionDecoration_ExecutionMode_Fragment_OriginUpperLeft) {
ast::type::Void void_type; auto* func = Func(
"main", {}, ty.void_, ast::StatementList{},
ast::Function func(
Source{}, mod->RegisterSymbol("main"), "main", {}, &void_type,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kFragment), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kFragment),
}); });
ASSERT_TRUE(b.GenerateExecutionModes(&func, 3)) << b.error(); ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
EXPECT_EQ(DumpInstructions(b.execution_modes()), EXPECT_EQ(DumpInstructions(b.execution_modes()),
R"(OpExecutionMode %3 OriginUpperLeft R"(OpExecutionMode %3 OriginUpperLeft
)"); )");
} }
TEST_F(BuilderTest, FunctionDecoration_ExecutionMode_WorkgroupSize_Default) { TEST_F(BuilderTest, FunctionDecoration_ExecutionMode_WorkgroupSize_Default) {
ast::type::Void void_type; auto* func = Func(
"main", {}, ty.void_, ast::StatementList{},
ast::Function func(
Source{}, mod->RegisterSymbol("main"), "main", {}, &void_type,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kCompute), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kCompute),
}); });
ASSERT_TRUE(b.GenerateExecutionModes(&func, 3)) << b.error(); ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
EXPECT_EQ(DumpInstructions(b.execution_modes()), EXPECT_EQ(DumpInstructions(b.execution_modes()),
R"(OpExecutionMode %3 LocalSize 1 1 1 R"(OpExecutionMode %3 LocalSize 1 1 1
)"); )");
} }
TEST_F(BuilderTest, FunctionDecoration_ExecutionMode_WorkgroupSize) { TEST_F(BuilderTest, FunctionDecoration_ExecutionMode_WorkgroupSize) {
ast::type::Void void_type; auto* func = Func(
"main", {}, ty.void_, ast::StatementList{},
ast::Function func(
Source{}, mod->RegisterSymbol("main"), "main", {}, &void_type,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::WorkgroupDecoration>(Source{}, 2u, 4u, 6u), create<ast::WorkgroupDecoration>(Source{}, 2u, 4u, 6u),
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kCompute), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kCompute),
}); });
ASSERT_TRUE(b.GenerateExecutionModes(&func, 3)) << b.error(); ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
EXPECT_EQ(DumpInstructions(b.execution_modes()), EXPECT_EQ(DumpInstructions(b.execution_modes()),
R"(OpExecutionMode %3 LocalSize 2 4 6 R"(OpExecutionMode %3 LocalSize 2 4 6
)"); )");
} }
TEST_F(BuilderTest, FunctionDecoration_ExecutionMode_MultipleFragment) { TEST_F(BuilderTest, FunctionDecoration_ExecutionMode_MultipleFragment) {
ast::type::Void void_type; auto* func1 = Func(
"main1", {}, ty.void_, ast::StatementList{},
ast::Function func1(
Source{}, mod->RegisterSymbol("main1"), "main1", {}, &void_type,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kFragment), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kFragment),
}); });
ast::Function func2( auto* func2 = Func(
Source{}, mod->RegisterSymbol("main2"), "main2", {}, &void_type, "main2", {}, ty.void_, ast::StatementList{},
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kFragment), create<ast::StageDecoration>(Source{}, ast::PipelineStage::kFragment),
}); });
ASSERT_TRUE(b.GenerateFunction(&func1)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func1)) << b.error();
ASSERT_TRUE(b.GenerateFunction(&func2)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func2)) << b.error();
EXPECT_EQ(DumpBuilder(b), EXPECT_EQ(DumpBuilder(b),
R"(OpEntryPoint Fragment %3 "main1" R"(OpEntryPoint Fragment %3 "main1"
OpEntryPoint Fragment %5 "main2" OpEntryPoint Fragment %5 "main2"
@ -345,15 +263,14 @@ OpFunctionEnd
TEST_F(BuilderTest, FunctionDecoration_ExecutionMode_FragDepth) { TEST_F(BuilderTest, FunctionDecoration_ExecutionMode_FragDepth) {
auto* fragdepth = auto* fragdepth =
Var("fragdepth", ast::StorageClass::kOutput, create<ast::type::F32>(), Var("fragdepth", ast::StorageClass::kOutput, ty.f32, nullptr,
nullptr,
ast::VariableDecorationList{ ast::VariableDecorationList{
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth), create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth),
}); });
mod->AddGlobalVariable(fragdepth); mod->AddGlobalVariable(fragdepth);
auto* func = auto* func =
Func("main", ast::VariableList{}, create<ast::type::Void>(), Func("main", ast::VariableList{}, ty.void_,
ast::StatementList{ ast::StatementList{
create<ast::AssignmentStatement>(Expr("fragdepth"), Expr(1.f)), create<ast::AssignmentStatement>(Expr("fragdepth"), Expr(1.f)),
}, },

View File

@ -46,13 +46,10 @@ namespace {
using BuilderTest = TestHelper; using BuilderTest = TestHelper;
TEST_F(BuilderTest, Function_Empty) { TEST_F(BuilderTest, Function_Empty) {
ast::type::Void void_type; auto* func = Func("a_func", {}, ty.void_, ast::StatementList{},
ast::Function func(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, &void_type,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)); ASSERT_TRUE(b.GenerateFunction(func));
EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func" EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func"
%2 = OpTypeVoid %2 = OpTypeVoid
%1 = OpTypeFunction %2 %1 = OpTypeFunction %2
@ -64,16 +61,13 @@ OpFunctionEnd
} }
TEST_F(BuilderTest, Function_Terminator_Return) { TEST_F(BuilderTest, Function_Terminator_Return) {
ast::type::Void void_type; auto* func = Func("a_func", {}, ty.void_,
ast::StatementList{
auto* body = create<ast::BlockStatement>(
Source{}, ast::StatementList{
create<ast::ReturnStatement>(Source{}), create<ast::ReturnStatement>(Source{}),
}); },
ast::Function func(Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ast::FunctionDecorationList{});
&void_type, body, ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)); ASSERT_TRUE(b.GenerateFunction(func));
EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func" EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func"
%2 = OpTypeVoid %2 = OpTypeVoid
%1 = OpTypeFunction %2 %1 = OpTypeFunction %2
@ -85,32 +79,16 @@ OpFunctionEnd
} }
TEST_F(BuilderTest, Function_Terminator_ReturnValue) { TEST_F(BuilderTest, Function_Terminator_ReturnValue) {
ast::type::Void void_type; auto* var_a = Var("a", ast::StorageClass::kPrivate, ty.f32);
ast::type::F32 f32;
auto* var_a =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
td.RegisterVariableForTesting(var_a); td.RegisterVariableForTesting(var_a);
auto* body = create<ast::BlockStatement>( auto* func = Func("a_func", {}, ty.void_,
Source{}, ast::StatementList{ ast::StatementList{create<ast::ReturnStatement>(Expr("a"))},
create<ast::ReturnStatement>( ast::FunctionDecorationList{});
Source{}, create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("a"), "a")),
});
ASSERT_TRUE(td.DetermineResultType(body)) << td.error();
ast::Function func(Source{}, mod->RegisterSymbol("a_func"), "a_func", {},
&void_type, body, ast::FunctionDecorationList{});
ASSERT_TRUE(td.DetermineFunction(func)) << td.error();
ASSERT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error();
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(OpName %1 "a" EXPECT_EQ(DumpBuilder(b), R"(OpName %1 "a"
OpName %7 "a_func" OpName %7 "a_func"
%3 = OpTypeFloat 32 %3 = OpTypeFloat 32
@ -128,16 +106,13 @@ OpFunctionEnd
} }
TEST_F(BuilderTest, Function_Terminator_Discard) { TEST_F(BuilderTest, Function_Terminator_Discard) {
ast::type::Void void_type; auto* func = Func("a_func", {}, ty.void_,
ast::StatementList{
auto* body = create<ast::BlockStatement>(
Source{}, ast::StatementList{
create<ast::DiscardStatement>(Source{}), create<ast::DiscardStatement>(Source{}),
}); },
ast::Function func(Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ast::FunctionDecorationList{});
&void_type, body, ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)); ASSERT_TRUE(b.GenerateFunction(func));
EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func" EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func"
%2 = OpTypeVoid %2 = OpTypeVoid
%1 = OpTypeFunction %2 %1 = OpTypeFunction %2
@ -149,42 +124,18 @@ OpFunctionEnd
} }
TEST_F(BuilderTest, Function_WithParams) { TEST_F(BuilderTest, Function_WithParams) {
ast::type::Void void_type; ast::VariableList params = {Var("a", ast::StorageClass::kFunction, ty.f32),
ast::type::F32 f32; Var("b", ast::StorageClass::kFunction, ty.i32)};
ast::type::I32 i32;
ast::VariableList params = { auto* func = Func("a_func", params, ty.f32,
create<ast::Variable>(Source{}, // source ast::StatementList{create<ast::ReturnStatement>(Expr("a"))},
"a", // name ast::FunctionDecorationList{});
ast::StorageClass::kFunction, // storage_class
&f32, // type
true, // is_const
nullptr, // constructor
ast::VariableDecorationList{}), // decorations
create<ast::Variable>(Source{}, // source td.RegisterVariableForTesting(func->params()[0]);
"b", // name td.RegisterVariableForTesting(func->params()[1]);
ast::StorageClass::kFunction, // storage_class EXPECT_TRUE(td.DetermineFunction(func));
&i32, // type
true, // is_const
nullptr, // constructor
ast::VariableDecorationList{}), // decorations
};
auto* body = create<ast::BlockStatement>( ASSERT_TRUE(b.GenerateFunction(func));
Source{}, ast::StatementList{
create<ast::ReturnStatement>(
Source{}, create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("a"), "a")),
});
ast::Function func(Source{}, mod->RegisterSymbol("a_func"), "a_func", params,
&f32, body, ast::FunctionDecorationList{});
td.RegisterVariableForTesting(func.params()[0]);
td.RegisterVariableForTesting(func.params()[1]);
EXPECT_TRUE(td.DetermineFunction(&func));
ASSERT_TRUE(b.GenerateFunction(&func));
EXPECT_EQ(DumpBuilder(b), R"(OpName %4 "a_func" EXPECT_EQ(DumpBuilder(b), R"(OpName %4 "a_func"
OpName %5 "a" OpName %5 "a"
OpName %6 "b" OpName %6 "b"
@ -195,22 +146,20 @@ OpName %6 "b"
%5 = OpFunctionParameter %2 %5 = OpFunctionParameter %2
%6 = OpFunctionParameter %3 %6 = OpFunctionParameter %3
%7 = OpLabel %7 = OpLabel
OpReturnValue %5 %8 = OpLoad %2 %5
OpReturnValue %8
OpFunctionEnd OpFunctionEnd
)") << DumpBuilder(b); )") << DumpBuilder(b);
} }
TEST_F(BuilderTest, Function_WithBody) { TEST_F(BuilderTest, Function_WithBody) {
ast::type::Void void_type; auto* func = Func("a_func", {}, ty.void_,
ast::StatementList{
auto* body = create<ast::BlockStatement>(
Source{}, ast::StatementList{
create<ast::ReturnStatement>(Source{}), create<ast::ReturnStatement>(Source{}),
}); },
ast::Function func(Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ast::FunctionDecorationList{});
&void_type, body, ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)); ASSERT_TRUE(b.GenerateFunction(func));
EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func" EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func"
%2 = OpTypeVoid %2 = OpTypeVoid
%1 = OpTypeFunction %2 %1 = OpTypeFunction %2
@ -222,31 +171,23 @@ OpFunctionEnd
} }
TEST_F(BuilderTest, FunctionType) { TEST_F(BuilderTest, FunctionType) {
ast::type::Void void_type; auto* func = Func("a_func", {}, ty.void_, ast::StatementList{},
ast::Function func(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, &void_type,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)); ASSERT_TRUE(b.GenerateFunction(func));
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2 %1 = OpTypeFunction %2
)"); )");
} }
TEST_F(BuilderTest, FunctionType_DeDuplicate) { TEST_F(BuilderTest, FunctionType_DeDuplicate) {
ast::type::Void void_type; auto* func1 = Func("a_func", {}, ty.void_, ast::StatementList{},
ast::Function func1(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, &void_type,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ast::Function func2( auto* func2 = Func("b_func", {}, ty.void_, ast::StatementList{},
Source{}, mod->RegisterSymbol("b_func"), "b_func", {}, &void_type,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func1)); ASSERT_TRUE(b.GenerateFunction(func1));
ASSERT_TRUE(b.GenerateFunction(&func2)); ASSERT_TRUE(b.GenerateFunction(func2));
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2 %1 = OpTypeFunction %2
)"); )");
@ -269,52 +210,31 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) {
// return; // return;
// } // }
ast::type::Void void_type;
ast::StructDecorationList s_decos; ast::StructDecorationList s_decos;
s_decos.push_back(create<ast::StructBlockDecoration>(Source{})); s_decos.push_back(create<ast::StructBlockDecoration>(Source{}));
auto* str = create<ast::Struct>( auto* str = create<ast::Struct>(
ast::StructMemberList{Member("d", ty.f32, {MemberOffset(0)})}, s_decos); ast::StructMemberList{Member("d", ty.f32, {MemberOffset(0)})}, s_decos);
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s); ast::type::AccessControl ac(ast::AccessControl::kReadWrite, s);
auto* data_var = auto* data_var = Var("data", ast::StorageClass::kStorageBuffer, &ac, nullptr,
create<ast::Variable>(Source{}, // source
"data", // name
ast::StorageClass::kStorageBuffer, // storage_class
&ac, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{ ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(Source{}, 0), create<ast::BindingDecoration>(Source{}, 0),
create<ast::SetDecoration>(Source{}, 0), create<ast::SetDecoration>(Source{}, 0),
}); });
mod->AddConstructedType(&s); mod->AddConstructedType(s);
td.RegisterVariableForTesting(data_var); td.RegisterVariableForTesting(data_var);
mod->AddGlobalVariable(data_var); mod->AddGlobalVariable(data_var);
{ {
auto* var = create<ast::Variable>( auto* var = Var("v", ast::StorageClass::kFunction, ty.f32,
Source{}, // source MemberAccessor("data", "d"), ast::VariableDecorationList{});
"v", // name
ast::StorageClass::kFunction, // storage_class
ty.f32, // type
false, // is_const
create<ast::MemberAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("data"), "data"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("d"),
"d")), // constructor
ast::VariableDecorationList{}); // decorations
auto* func = Func("a", ast::VariableList{}, &void_type, auto* func = Func("a", ast::VariableList{}, ty.void_,
ast::StatementList{ ast::StatementList{
create<ast::VariableDeclStatement>(Source{}, var), create<ast::VariableDeclStatement>(Source{}, var),
create<ast::ReturnStatement>(Source{}), create<ast::ReturnStatement>(Source{}),
@ -328,22 +248,10 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) {
} }
{ {
auto* var = create<ast::Variable>( auto* var = Var("v", ast::StorageClass::kFunction, ty.f32,
Source{}, // source MemberAccessor("data", "d"), ast::VariableDecorationList{});
"v", // name
ast::StorageClass::kFunction, // storage_class
ty.f32, // type
false, // is_const
create<ast::MemberAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("data"), "data"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("d"),
"d")), // constructor
ast::VariableDecorationList{}); // decorations
auto* func = Func("b", ast::VariableList{}, &void_type, auto* func = Func("b", ast::VariableList{}, ty.void_,
ast::StatementList{ ast::StatementList{
create<ast::VariableDeclStatement>(Source{}, var), create<ast::VariableDeclStatement>(Source{}, var),
create<ast::ReturnStatement>(Source{}), create<ast::ReturnStatement>(Source{}),

View File

@ -157,28 +157,20 @@ TEST_F(BuilderTest, FunctionVar_WithNonConstantConstructorLoadedFromVar) {
// var v : f32 = 1.0; // var v : f32 = 1.0;
// var v2 : f32 = v; // Should generate the load and store automatically. // var v2 : f32 = v; // Should generate the load and store automatically.
ast::type::F32 f32; auto* v = Var("v", ast::StorageClass::kFunction, ty.f32, Expr(1.f),
auto* init = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f));
ASSERT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "v", ast::StorageClass::kFunction, &f32, false,
init, ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
ast::Variable v2(Source{}, "v2", ast::StorageClass::kFunction, &f32, false,
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("v"), "v"),
ast::VariableDecorationList{}); ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v2); td.RegisterVariableForTesting(v);
ASSERT_TRUE(td.DetermineResultType(v2.constructor())) << td.error(); auto* v2 = Var("v2", ast::StorageClass::kFunction, ty.f32, Expr("v"),
ast::VariableDecorationList{});
td.RegisterVariableForTesting(v2);
ASSERT_TRUE(td.DetermineResultType(v->constructor())) << td.error();
ASSERT_TRUE(td.DetermineResultType(v2->constructor())) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
EXPECT_TRUE(b.GenerateFunctionVariable(&v2)) << b.error(); EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "v" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "v"
@ -204,31 +196,24 @@ TEST_F(BuilderTest, FunctionVar_ConstWithVarInitializer) {
// var v : f32 = 1.0; // var v : f32 = 1.0;
// const v2 : f32 = v; // Should generate the load // const v2 : f32 = v; // Should generate the load
ast::type::F32 f32; auto* v = Var("v", ast::StorageClass::kFunction, ty.f32, Expr(1.f),
auto* init = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f));
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "v", ast::StorageClass::kFunction, &f32, false,
init, ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
ast::Variable v2(Source{}, "v2", ast::StorageClass::kFunction, &f32, true,
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("v"), "v"),
ast::VariableDecorationList{}); ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v2); td.RegisterVariableForTesting(v);
ASSERT_TRUE(td.DetermineResultType(v2.constructor())) << td.error(); auto* v2 = Var("v2", ast::StorageClass::kFunction, ty.f32, Expr("v"),
ast::VariableDecorationList{});
td.RegisterVariableForTesting(v2);
ASSERT_TRUE(td.DetermineResultType(v->constructor())) << td.error();
ASSERT_TRUE(td.DetermineResultType(v2->constructor())) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
EXPECT_TRUE(b.GenerateFunctionVariable(&v2)) << b.error(); EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "v" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "v"
OpName %7 "v2"
)"); )");
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 1 %2 = OpConstant %1 1
@ -237,35 +222,27 @@ TEST_F(BuilderTest, FunctionVar_ConstWithVarInitializer) {
)"); )");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
R"(%3 = OpVariable %4 Function %5 R"(%3 = OpVariable %4 Function %5
%7 = OpVariable %4 Function %5
)"); )");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
R"(OpStore %3 %2 R"(OpStore %3 %2
%6 = OpLoad %1 %3 %6 = OpLoad %1 %3
OpStore %7 %6
)"); )");
} }
TEST_F(BuilderTest, FunctionVar_Const) { TEST_F(BuilderTest, FunctionVar_Const) {
ast::type::F32 f32; auto* init = create<ast::TypeConstructorExpression>(
ast::type::Vector vec(&f32, 3); Source{}, ty.vec3<f32>(),
ast::ExpressionList{Expr(1.f), Expr(1.f), Expr(3.f)});
ast::ExpressionList vals;
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
auto* init = create<ast::TypeConstructorExpression>(Source{}, &vec, vals);
EXPECT_TRUE(td.DetermineResultType(init)) << td.error(); EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init, auto* v = Const("var", ast::StorageClass::kOutput, ty.f32, init,
ast::VariableDecorationList{}); ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v); td.RegisterVariableForTesting(v);
EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32

View File

@ -50,11 +50,8 @@ namespace {
using BuilderTest = TestHelper; using BuilderTest = TestHelper;
TEST_F(BuilderTest, GlobalVar_NoStorageClass) { TEST_F(BuilderTest, GlobalVar_NoStorageClass) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kNone, ty.f32);
ast::Variable v(Source{}, "var", ast::StorageClass::kNone, &f32, false, EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
nullptr, ast::VariableDecorationList{});
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
)"); )");
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
@ -65,11 +62,8 @@ TEST_F(BuilderTest, GlobalVar_NoStorageClass) {
} }
TEST_F(BuilderTest, GlobalVar_WithStorageClass) { TEST_F(BuilderTest, GlobalVar_WithStorageClass) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kOutput, ty.f32);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false, EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
nullptr, ast::VariableDecorationList{});
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
)"); )");
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
@ -80,11 +74,8 @@ TEST_F(BuilderTest, GlobalVar_WithStorageClass) {
} }
TEST_F(BuilderTest, GlobalVar_WithStorageClass_Input) { TEST_F(BuilderTest, GlobalVar_WithStorageClass_Input) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kInput, ty.f32);
ast::Variable v(Source{}, "var", ast::StorageClass::kInput, &f32, false, EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
nullptr, ast::VariableDecorationList{});
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
)"); )");
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
@ -94,27 +85,16 @@ TEST_F(BuilderTest, GlobalVar_WithStorageClass_Input) {
} }
TEST_F(BuilderTest, GlobalVar_WithConstructor) { TEST_F(BuilderTest, GlobalVar_WithConstructor) {
ast::type::F32 f32; auto* init = create<ast::TypeConstructorExpression>(
ast::type::Vector vec(&f32, 3); Source{}, ty.vec3<f32>(),
ast::ExpressionList{Expr(1.f), Expr(1.f), Expr(3.f)});
ast::ExpressionList vals;
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
auto* init = create<ast::TypeConstructorExpression>(Source{}, &vec, vals);
EXPECT_TRUE(td.DetermineResultType(init)) << td.error(); EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false, auto* v = Var("var", ast::StorageClass::kOutput, ty.f32, init,
init, ast::VariableDecorationList{}); ast::VariableDecorationList{});
td.RegisterVariableForTesting(v);
td.RegisterVariableForTesting(&v); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %6 "var" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %6 "var"
@ -130,26 +110,16 @@ TEST_F(BuilderTest, GlobalVar_WithConstructor) {
} }
TEST_F(BuilderTest, GlobalVar_Const) { TEST_F(BuilderTest, GlobalVar_Const) {
ast::type::F32 f32; auto* init = create<ast::TypeConstructorExpression>(
ast::type::Vector vec(&f32, 3); Source{}, ty.vec3<f32>(),
ast::ExpressionList{Expr(1.f), Expr(1.f), Expr(3.f)});
ast::ExpressionList vals;
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
auto* init = create<ast::TypeConstructorExpression>(Source{}, &vec, vals);
EXPECT_TRUE(td.DetermineResultType(init)) << td.error(); EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init, auto* v = Const("var", ast::StorageClass::kOutput, ty.f32, init,
ast::VariableDecorationList{}); ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v); td.RegisterVariableForTesting(v);
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %5 "var" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %5 "var"
@ -163,25 +133,16 @@ TEST_F(BuilderTest, GlobalVar_Const) {
} }
TEST_F(BuilderTest, GlobalVar_Complex_Constructor) { TEST_F(BuilderTest, GlobalVar_Complex_Constructor) {
ast::type::F32 f32; auto* init = create<ast::TypeConstructorExpression>(
ast::type::Vector vec3(&f32, 3); Source{}, ty.vec3<f32>(),
ast::ExpressionList{Expr(1.f), Expr(2.f), Expr(3.f)});
ast::ExpressionList vals;
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
auto* init = create<ast::TypeConstructorExpression>(Source{}, &vec3, vals);
EXPECT_TRUE(td.DetermineResultType(init)) << td.error(); EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init, auto* v = Const("var", ast::StorageClass::kOutput, ty.f32, init,
ast::VariableDecorationList{}); ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v); td.RegisterVariableForTesting(v);
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@ -194,34 +155,19 @@ TEST_F(BuilderTest, GlobalVar_Complex_Constructor) {
} }
TEST_F(BuilderTest, GlobalVar_Complex_ConstructorWithExtract) { TEST_F(BuilderTest, GlobalVar_Complex_ConstructorWithExtract) {
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
ast::type::Vector vec2(&f32, 2);
auto* first = create<ast::TypeConstructorExpression>( auto* first = create<ast::TypeConstructorExpression>(
Source{}, &vec2, Source{}, ty.vec2<f32>(), ast::ExpressionList{Expr(1.f), Expr(2.f)});
ast::ExpressionList{
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.0f)),
});
auto* init = create<ast::TypeConstructorExpression>( auto* init = create<ast::TypeConstructorExpression>(
Source{}, &vec3, Source{}, ty.vec3<f32>(), ast::ExpressionList{first, Expr(3.f)});
ast::ExpressionList{
first,
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)),
});
EXPECT_TRUE(td.DetermineResultType(init)) << td.error(); EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init, auto* v = Const("var", ast::StorageClass::kOutput, ty.f32, init,
ast::VariableDecorationList{}); ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v); td.RegisterVariableForTesting(v);
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@ -241,16 +187,8 @@ TEST_F(BuilderTest, GlobalVar_Complex_ConstructorWithExtract) {
} }
TEST_F(BuilderTest, GlobalVar_WithLocation) { TEST_F(BuilderTest, GlobalVar_WithLocation) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kOutput, ty.f32, nullptr,
auto* v =
create<ast::Variable>(Source{}, // source
"var", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{ ast::VariableDecorationList{
// decorations
create<ast::LocationDecoration>(Source{}, 5), create<ast::LocationDecoration>(Source{}, 5),
}); });
@ -267,16 +205,8 @@ TEST_F(BuilderTest, GlobalVar_WithLocation) {
} }
TEST_F(BuilderTest, GlobalVar_WithBindingAndSet) { TEST_F(BuilderTest, GlobalVar_WithBindingAndSet) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kOutput, ty.f32, nullptr,
auto* v =
create<ast::Variable>(Source{}, // source
"var", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{ ast::VariableDecorationList{
// decorations
create<ast::BindingDecoration>(Source{}, 2), create<ast::BindingDecoration>(Source{}, 2),
create<ast::SetDecoration>(Source{}, 3), create<ast::SetDecoration>(Source{}, 3),
}); });
@ -295,16 +225,9 @@ OpDecorate %1 DescriptorSet 3
} }
TEST_F(BuilderTest, GlobalVar_WithBuiltin) { TEST_F(BuilderTest, GlobalVar_WithBuiltin) {
ast::type::F32 f32; auto* v =
auto* v = create<ast::Variable>( Var("var", ast::StorageClass::kOutput, ty.f32, nullptr,
Source{}, // source
"var", // name
ast::StorageClass::kOutput, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{ ast::VariableDecorationList{
// decorations
create<ast::BuiltinDecoration>(Source{}, ast::Builtin::kPosition), create<ast::BuiltinDecoration>(Source{}, ast::Builtin::kPosition),
}); });
@ -321,19 +244,8 @@ TEST_F(BuilderTest, GlobalVar_WithBuiltin) {
} }
TEST_F(BuilderTest, GlobalVar_ConstantId_Bool) { TEST_F(BuilderTest, GlobalVar_ConstantId_Bool) {
ast::type::Bool bool_type; auto* v = Var("var", ast::StorageClass::kNone, ty.bool_, Expr(true),
auto* v = create<ast::Variable>(
Source{}, // source
"var", // name
ast::StorageClass::kNone, // storage_class
&bool_type, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
Source{},
create<ast::BoolLiteral>(Source{}, &bool_type, true)), // constructor
ast::VariableDecorationList{ ast::VariableDecorationList{
// decorations
create<ast::ConstantIdDecoration>(Source{}, 1200), create<ast::ConstantIdDecoration>(Source{}, 1200),
}); });
@ -350,17 +262,8 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Bool) {
} }
TEST_F(BuilderTest, GlobalVar_ConstantId_Bool_NoConstructor) { TEST_F(BuilderTest, GlobalVar_ConstantId_Bool_NoConstructor) {
ast::type::Bool bool_type; auto* v = Var("var", ast::StorageClass::kNone, ty.bool_, nullptr,
auto* v = create<ast::Variable>(
Source{}, // source
"var", // name
ast::StorageClass::kNone, // storage_class
&bool_type, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{ ast::VariableDecorationList{
// decorations
create<ast::ConstantIdDecoration>(Source{}, 1200), create<ast::ConstantIdDecoration>(Source{}, 1200),
}); });
@ -377,19 +280,8 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Bool_NoConstructor) {
} }
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar) { TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kNone, ty.f32, Expr(2.f),
auto* v = create<ast::Variable>(
Source{}, // source
"var", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
false, // is_const
create<ast::ScalarConstructorExpression>(
Source{},
create<ast::FloatLiteral>(Source{}, &f32, 2.0)), // constructor
ast::VariableDecorationList{ ast::VariableDecorationList{
// decorations
create<ast::ConstantIdDecoration>(Source{}, 0), create<ast::ConstantIdDecoration>(Source{}, 0),
}); });
@ -406,17 +298,8 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar) {
} }
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_F32_NoConstructor) { TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_F32_NoConstructor) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kNone, ty.f32, nullptr,
auto* v =
create<ast::Variable>(Source{}, // source
"var", // name
ast::StorageClass::kNone, // storage_class
&f32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{ ast::VariableDecorationList{
// decorations
create<ast::ConstantIdDecoration>(Source{}, 0), create<ast::ConstantIdDecoration>(Source{}, 0),
}); });
@ -433,17 +316,8 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_F32_NoConstructor) {
} }
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_I32_NoConstructor) { TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_I32_NoConstructor) {
ast::type::I32 i32; auto* v = Var("var", ast::StorageClass::kNone, ty.i32, nullptr,
auto* v =
create<ast::Variable>(Source{}, // source
"var", // name
ast::StorageClass::kNone, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{ ast::VariableDecorationList{
// decorations
create<ast::ConstantIdDecoration>(Source{}, 0), create<ast::ConstantIdDecoration>(Source{}, 0),
}); });
@ -460,17 +334,8 @@ TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_I32_NoConstructor) {
} }
TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_U32_NoConstructor) { TEST_F(BuilderTest, GlobalVar_ConstantId_Scalar_U32_NoConstructor) {
ast::type::U32 u32; auto* v = Var("var", ast::StorageClass::kNone, ty.u32, nullptr,
auto* v =
create<ast::Variable>(Source{}, // source
"var", // name
ast::StorageClass::kNone, // storage_class
&u32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{ ast::VariableDecorationList{
// decorations
create<ast::ConstantIdDecoration>(Source{}, 0), create<ast::ConstantIdDecoration>(Source{}, 0),
}); });
@ -526,17 +391,14 @@ TEST_F(BuilderTest, GlobalVar_DeclReadOnly) {
// }; // };
// var b : [[access(read)]] A // var b : [[access(read)]] A
ast::type::Struct A( auto* A = ty.struct_(
mod->RegisterSymbol("A"), "A", "A", create<ast::Struct>(
create<ast::Struct>(
ast::StructMemberList{Member("a", ty.i32), Member("b", ty.i32)}, ast::StructMemberList{Member("a", ty.i32), Member("b", ty.i32)},
ast::StructDecorationList{})); ast::StructDecorationList{}));
ast::type::AccessControl ac{ast::AccessControl::kReadOnly, &A}; ast::type::AccessControl ac{ast::AccessControl::kReadOnly, A};
ast::Variable var(Source{}, "b", ast::StorageClass::kStorageBuffer, &ac, auto* var = Var("b", ast::StorageClass::kStorageBuffer, &ac);
false, nullptr, ast::VariableDecorationList{}); EXPECT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(&var)) << b.error();
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %3 0 NonWritable EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %3 0 NonWritable
OpMemberDecorate %3 1 NonWritable OpMemberDecorate %3 1 NonWritable
@ -560,17 +422,13 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasDeclReadOnly) {
// type B = A; // type B = A;
// var b : [[access(read)]] B // var b : [[access(read)]] B
ast::type::Struct A( auto* A = ty.struct_(
mod->RegisterSymbol("A"), "A", "A", create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32)},
create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32)},
ast::StructDecorationList{})); ast::StructDecorationList{}));
ast::type::Alias B(mod->RegisterSymbol("B"), "B", &A); auto* B = ty.alias("B", A);
ast::type::AccessControl ac{ast::AccessControl::kReadOnly, &B}; ast::type::AccessControl ac{ast::AccessControl::kReadOnly, B};
auto* var = Var("b", ast::StorageClass::kStorageBuffer, &ac);
ast::Variable var(Source{}, "b", ast::StorageClass::kStorageBuffer, &ac, EXPECT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
false, nullptr, ast::VariableDecorationList{});
EXPECT_TRUE(b.GenerateGlobalVariable(&var)) << b.error();
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %3 0 NonWritable EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %3 0 NonWritable
)"); )");
@ -592,17 +450,13 @@ TEST_F(BuilderTest, GlobalVar_TypeAliasAssignReadOnly) {
// type B = [[access(read)]] A; // type B = [[access(read)]] A;
// var b : B // var b : B
ast::type::Struct A( auto* A = ty.struct_(
mod->RegisterSymbol("A"), "A", "A", create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32)},
create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32)},
ast::StructDecorationList{})); ast::StructDecorationList{}));
ast::type::AccessControl ac{ast::AccessControl::kReadOnly, &A}; ast::type::AccessControl ac{ast::AccessControl::kReadOnly, A};
ast::type::Alias B(mod->RegisterSymbol("B"), "B", &ac); auto* B = ty.alias("B", &ac);
auto* var = Var("b", ast::StorageClass::kStorageBuffer, B);
ast::Variable var(Source{}, "b", ast::StorageClass::kStorageBuffer, &B, false, EXPECT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
nullptr, ast::VariableDecorationList{});
EXPECT_TRUE(b.GenerateGlobalVariable(&var)) << b.error();
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %3 0 NonWritable EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %3 0 NonWritable
)"); )");
@ -624,20 +478,16 @@ TEST_F(BuilderTest, GlobalVar_TwoVarDeclReadOnly) {
// var b : [[access(read)]] A // var b : [[access(read)]] A
// var c : [[access(read_write)]] A // var c : [[access(read_write)]] A
ast::type::Struct A( auto* A = ty.struct_(
mod->RegisterSymbol("A"), "A", "A", create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32)},
create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32)},
ast::StructDecorationList{})); ast::StructDecorationList{}));
ast::type::AccessControl read{ast::AccessControl::kReadOnly, &A}; ast::type::AccessControl read{ast::AccessControl::kReadOnly, A};
ast::type::AccessControl rw{ast::AccessControl::kReadWrite, &A}; ast::type::AccessControl rw{ast::AccessControl::kReadWrite, A};
ast::Variable var_b(Source{}, "b", ast::StorageClass::kStorageBuffer, &read, auto* var_b = Var("b", ast::StorageClass::kStorageBuffer, &read);
false, nullptr, ast::VariableDecorationList{}); auto* var_c = Var("c", ast::StorageClass::kStorageBuffer, &rw);
ast::Variable var_c(Source{}, "c", ast::StorageClass::kStorageBuffer, &rw, EXPECT_TRUE(b.GenerateGlobalVariable(var_b)) << b.error();
false, nullptr, ast::VariableDecorationList{}); EXPECT_TRUE(b.GenerateGlobalVariable(var_c)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(&var_b)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(&var_c)) << b.error();
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %3 0 NonWritable EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %3 0 NonWritable
)"); )");
@ -660,15 +510,14 @@ OpName %5 "c"
TEST_F(BuilderTest, GlobalVar_TextureStorageReadOnly) { TEST_F(BuilderTest, GlobalVar_TextureStorageReadOnly) {
// var<uniform_constant> a : texture_storage_ro_2d<r32uint>; // var<uniform_constant> a : texture_storage_ro_2d<r32uint>;
ast::type::StorageTexture type(ast::type::TextureDimension::k2d, ast::type::StorageTexture type(ast::type::TextureDimension::k2d,
ast::AccessControl::kReadOnly, ast::AccessControl::kReadOnly,
ast::type::ImageFormat::kR32Uint); ast::type::ImageFormat::kR32Uint);
ASSERT_TRUE(td.DetermineStorageTextureSubtype(&type)) << td.error(); ASSERT_TRUE(td.DetermineStorageTextureSubtype(&type)) << td.error();
ast::Variable var_a(Source{}, "a", ast::StorageClass::kUniformConstant, &type, auto* var_a = Var("a", ast::StorageClass::kUniformConstant, &type);
false, nullptr, ast::VariableDecorationList{}); EXPECT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(&var_a)) << b.error();
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 NonWritable EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 NonWritable
)"); )");
@ -681,15 +530,14 @@ TEST_F(BuilderTest, GlobalVar_TextureStorageReadOnly) {
TEST_F(BuilderTest, GlobalVar_TextureStorageWriteOnly) { TEST_F(BuilderTest, GlobalVar_TextureStorageWriteOnly) {
// var<uniform_constant> a : texture_storage_wo_2d<r32uint>; // var<uniform_constant> a : texture_storage_wo_2d<r32uint>;
ast::type::StorageTexture type(ast::type::TextureDimension::k2d, ast::type::StorageTexture type(ast::type::TextureDimension::k2d,
ast::AccessControl::kWriteOnly, ast::AccessControl::kWriteOnly,
ast::type::ImageFormat::kR32Uint); ast::type::ImageFormat::kR32Uint);
ASSERT_TRUE(td.DetermineStorageTextureSubtype(&type)) << td.error(); ASSERT_TRUE(td.DetermineStorageTextureSubtype(&type)) << td.error();
ast::Variable var_a(Source{}, "a", ast::StorageClass::kUniformConstant, &type, auto* var_a = Var("a", ast::StorageClass::kUniformConstant, &type);
false, nullptr, ast::VariableDecorationList{}); EXPECT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(&var_a)) << b.error();
EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 NonReadable EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 NonReadable
)"); )");

View File

@ -38,27 +38,16 @@ namespace {
using BuilderTest = TestHelper; using BuilderTest = TestHelper;
TEST_F(BuilderTest, IdentifierExpression_GlobalConst) { TEST_F(BuilderTest, IdentifierExpression_GlobalConst) {
ast::type::F32 f32; auto* init = create<ast::TypeConstructorExpression>(
ast::type::Vector vec(&f32, 3); Source{}, ty.vec3<f32>(),
ast::ExpressionList{Expr(1.f), Expr(1.f), Expr(3.f)});
ast::ExpressionList vals;
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
auto* init = create<ast::TypeConstructorExpression>(Source{}, &vec, vals);
EXPECT_TRUE(td.DetermineResultType(init)) << td.error(); EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init, auto* v = Const("var", ast::StorageClass::kOutput, ty.f32, init,
ast::VariableDecorationList{}); ast::VariableDecorationList{});
td.RegisterVariableForTesting(v);
td.RegisterVariableForTesting(&v); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@ -68,21 +57,17 @@ TEST_F(BuilderTest, IdentifierExpression_GlobalConst) {
%5 = OpConstantComposite %1 %3 %3 %4 %5 = OpConstantComposite %1 %3 %3 %4
)"); )");
ast::IdentifierExpression expr(Source{}, mod->RegisterSymbol("var"), "var"); auto* expr = Expr("var");
ASSERT_TRUE(td.DetermineResultType(&expr)); ASSERT_TRUE(td.DetermineResultType(expr));
EXPECT_EQ(b.GenerateIdentifierExpression(expr), 5u);
EXPECT_EQ(b.GenerateIdentifierExpression(&expr), 5u);
} }
TEST_F(BuilderTest, IdentifierExpression_GlobalVar) { TEST_F(BuilderTest, IdentifierExpression_GlobalVar) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kOutput, ty.f32);
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, false, td.RegisterVariableForTesting(v);
nullptr, ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateGlobalVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
)"); )");
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
@ -91,32 +76,22 @@ TEST_F(BuilderTest, IdentifierExpression_GlobalVar) {
%1 = OpVariable %2 Output %4 %1 = OpVariable %2 Output %4
)"); )");
ast::IdentifierExpression expr(Source{}, mod->RegisterSymbol("var"), "var"); auto* expr = Expr("var");
ASSERT_TRUE(td.DetermineResultType(&expr)); ASSERT_TRUE(td.DetermineResultType(expr));
EXPECT_EQ(b.GenerateIdentifierExpression(&expr), 1u); EXPECT_EQ(b.GenerateIdentifierExpression(expr), 1u);
} }
TEST_F(BuilderTest, IdentifierExpression_FunctionConst) { TEST_F(BuilderTest, IdentifierExpression_FunctionConst) {
ast::type::F32 f32; auto* init = create<ast::TypeConstructorExpression>(
ast::type::Vector vec(&f32, 3); Source{}, ty.vec3<f32>(),
ast::ExpressionList{Expr(1.f), Expr(1.f), Expr(3.f)});
ast::ExpressionList vals;
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
auto* init = create<ast::TypeConstructorExpression>(Source{}, &vec, vals);
EXPECT_TRUE(td.DetermineResultType(init)) << td.error(); EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
ast::Variable v(Source{}, "var", ast::StorageClass::kOutput, &f32, true, init, auto* v = Const("var", ast::StorageClass::kOutput, ty.f32, init,
ast::VariableDecorationList{}); ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v); td.RegisterVariableForTesting(v);
EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
@ -126,20 +101,17 @@ TEST_F(BuilderTest, IdentifierExpression_FunctionConst) {
%5 = OpConstantComposite %1 %3 %3 %4 %5 = OpConstantComposite %1 %3 %3 %4
)"); )");
ast::IdentifierExpression expr(Source{}, mod->RegisterSymbol("var"), "var"); auto* expr = Expr("var");
ASSERT_TRUE(td.DetermineResultType(&expr)); ASSERT_TRUE(td.DetermineResultType(expr));
EXPECT_EQ(b.GenerateIdentifierExpression(&expr), 5u); EXPECT_EQ(b.GenerateIdentifierExpression(expr), 5u);
} }
TEST_F(BuilderTest, IdentifierExpression_FunctionVar) { TEST_F(BuilderTest, IdentifierExpression_FunctionVar) {
ast::type::F32 f32; auto* v = Var("var", ast::StorageClass::kNone, ty.f32);
ast::Variable v(Source{}, "var", ast::StorageClass::kNone, &f32, false, td.RegisterVariableForTesting(v);
nullptr, ast::VariableDecorationList{});
td.RegisterVariableForTesting(&v);
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateFunctionVariable(&v)) << b.error(); EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var" EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
)"); )");
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
@ -152,32 +124,23 @@ TEST_F(BuilderTest, IdentifierExpression_FunctionVar) {
R"(%1 = OpVariable %2 Function %4 R"(%1 = OpVariable %2 Function %4
)"); )");
ast::IdentifierExpression expr(Source{}, mod->RegisterSymbol("var"), "var"); auto* expr = Expr("var");
ASSERT_TRUE(td.DetermineResultType(&expr)); ASSERT_TRUE(td.DetermineResultType(expr));
EXPECT_EQ(b.GenerateIdentifierExpression(&expr), 1u); EXPECT_EQ(b.GenerateIdentifierExpression(expr), 1u);
} }
TEST_F(BuilderTest, IdentifierExpression_Load) { TEST_F(BuilderTest, IdentifierExpression_Load) {
ast::type::I32 i32; auto* var = Var("var", ast::StorageClass::kPrivate, ty.i32);
td.RegisterVariableForTesting(var);
ast::Variable var(Source{}, "var", ast::StorageClass::kPrivate, &i32, false, auto* expr = Add("var", "var");
nullptr, ast::VariableDecorationList{}); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
td.RegisterVariableForTesting(&var);
auto* lhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("var"), "var");
auto* rhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("var"), "var");
ast::BinaryExpression expr(Source{}, ast::BinaryOp::kAdd, lhs, rhs);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateGlobalVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
EXPECT_EQ(b.GenerateBinaryExpression(&expr), 7u) << b.error(); EXPECT_EQ(b.GenerateBinaryExpression(expr->As<ast::BinaryExpression>()), 7u)
<< b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
%2 = OpTypePointer Private %3 %2 = OpTypePointer Private %3
%4 = OpConstantNull %3 %4 = OpConstantNull %3
@ -191,28 +154,18 @@ TEST_F(BuilderTest, IdentifierExpression_Load) {
} }
TEST_F(BuilderTest, IdentifierExpression_NoLoadConst) { TEST_F(BuilderTest, IdentifierExpression_NoLoadConst) {
ast::type::I32 i32; auto* var = Const("var", ast::StorageClass::kNone, ty.i32, Expr(2),
ast::Variable var(Source{}, "var", ast::StorageClass::kNone, &i32, true,
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2)),
ast::VariableDecorationList{}); ast::VariableDecorationList{});
td.RegisterVariableForTesting(var);
td.RegisterVariableForTesting(&var); auto* expr = Add("var", "var");
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
auto* lhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("var"), "var");
auto* rhs = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("var"), "var");
ast::BinaryExpression expr(Source{}, ast::BinaryOp::kAdd, lhs, rhs);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateGlobalVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
EXPECT_EQ(b.GenerateBinaryExpression(&expr), 3u) << b.error(); EXPECT_EQ(b.GenerateBinaryExpression(expr->As<ast::BinaryExpression>()), 3u)
<< b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1 EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 2 %2 = OpConstant %1 2
)"); )");

View File

@ -93,35 +93,15 @@ TEST_F(BuilderTest, If_Empty_OutsideFunction_IsError) {
} }
TEST_F(BuilderTest, If_WithStatements) { TEST_F(BuilderTest, If_WithStatements) {
ast::type::Bool bool_type;
ast::type::I32 i32;
// if (true) { // if (true) {
// v = 2; // v = 2;
// } // }
auto* var =
create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* var = Var("v", ast::StorageClass::kPrivate, ty.i32);
auto* body = create<ast::BlockStatement>( auto* body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(2))});
create<ast::AssignmentStatement>( ast::IfStatement expr(Source{}, Expr(true), body, ast::ElseStatementList{});
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2))),
});
auto* cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true));
ast::IfStatement expr(Source{}, cond, body, ast::ElseStatementList{});
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
@ -149,49 +129,22 @@ OpBranch %7
} }
TEST_F(BuilderTest, If_WithElse) { TEST_F(BuilderTest, If_WithElse) {
ast::type::Bool bool_type;
ast::type::I32 i32;
// if (true) { // if (true) {
// v = 2; // v = 2;
// } else { // } else {
// v = 3; // v = 3;
// } // }
auto* var =
create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* var = Var("v", ast::StorageClass::kPrivate, ty.i32);
auto* body = create<ast::BlockStatement>( auto* body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(2))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2))),
});
auto* else_body = create<ast::BlockStatement>( auto* else_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(3))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 3))),
});
auto* cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true));
ast::IfStatement expr( ast::IfStatement expr(
Source{}, cond, body, Source{}, Expr(true), body,
{create<ast::ElseStatement>(Source{}, nullptr, else_body)}); {create<ast::ElseStatement>(Source{}, nullptr, else_body)});
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
@ -225,53 +178,23 @@ OpBranch %7
} }
TEST_F(BuilderTest, If_WithElseIf) { TEST_F(BuilderTest, If_WithElseIf) {
ast::type::Bool bool_type;
ast::type::I32 i32;
// if (true) { // if (true) {
// v = 2; // v = 2;
// } elseif (true) { // } elseif (true) {
// v = 3; // v = 3;
// } // }
auto* var =
create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* var = Var("v", ast::StorageClass::kPrivate, ty.i32);
auto* body = create<ast::BlockStatement>( auto* body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(2))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2))),
});
auto* else_body = create<ast::BlockStatement>( auto* else_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(3))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 3))),
});
auto* else_cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true));
auto* cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true));
ast::IfStatement expr( ast::IfStatement expr(
Source{}, cond, body, Source{}, Expr(true), body,
{create<ast::ElseStatement>(Source{}, else_cond, else_body)}); {create<ast::ElseStatement>(Source{}, Expr(true), else_body)});
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
@ -309,9 +232,6 @@ OpBranch %7
} }
TEST_F(BuilderTest, If_WithMultiple) { TEST_F(BuilderTest, If_WithMultiple) {
ast::type::Bool bool_type;
ast::type::I32 i32;
// if (true) { // if (true) {
// v = 2; // v = 2;
// } elseif (true) { // } elseif (true) {
@ -321,69 +241,26 @@ TEST_F(BuilderTest, If_WithMultiple) {
// } else { // } else {
// v = 5; // v = 5;
// } // }
auto* var =
create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* var = Var("v", ast::StorageClass::kPrivate, ty.i32);
auto* body = create<ast::BlockStatement>( auto* body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(2))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2))),
});
auto* elseif_1_body = create<ast::BlockStatement>( auto* elseif_1_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(3))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 3))),
});
auto* elseif_2_body = create<ast::BlockStatement>( auto* elseif_2_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(4))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 4))),
});
auto* else_body = create<ast::BlockStatement>( auto* else_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(5))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 5))),
});
auto* elseif_1_cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true));
auto* elseif_2_cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, false));
auto* cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true));
ast::IfStatement expr( ast::IfStatement expr(
Source{}, cond, body, Source{}, Expr(true), body,
{ {
create<ast::ElseStatement>(Source{}, elseif_1_cond, elseif_1_body), create<ast::ElseStatement>(Source{}, Expr(true), elseif_1_body),
create<ast::ElseStatement>(Source{}, elseif_2_cond, elseif_2_body), create<ast::ElseStatement>(Source{}, Expr(false), elseif_2_body),
create<ast::ElseStatement>(Source{}, nullptr, else_body), create<ast::ElseStatement>(Source{}, nullptr, else_body),
}); });
@ -437,21 +314,18 @@ OpBranch %7
} }
TEST_F(BuilderTest, If_WithBreak) { TEST_F(BuilderTest, If_WithBreak) {
ast::type::Bool bool_type;
// loop { // loop {
// if (true) { // if (true) {
// break; // break;
// } // }
// } // }
auto* cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true));
auto* if_body = create<ast::BlockStatement>( auto* if_body = create<ast::BlockStatement>(
Source{}, ast::StatementList{ Source{}, ast::StatementList{
create<ast::BreakStatement>(Source{}), create<ast::BreakStatement>(Source{}),
}); });
auto* if_stmt = create<ast::IfStatement>(Source{}, cond, if_body, auto* if_stmt = create<ast::IfStatement>(Source{}, Expr(true), if_body,
ast::ElseStatementList{}); ast::ElseStatementList{});
auto* loop_body = create<ast::BlockStatement>(Source{}, ast::StatementList{ auto* loop_body = create<ast::BlockStatement>(Source{}, ast::StatementList{
@ -489,23 +363,19 @@ OpBranch %1
} }
TEST_F(BuilderTest, If_WithElseBreak) { TEST_F(BuilderTest, If_WithElseBreak) {
ast::type::Bool bool_type;
// loop { // loop {
// if (true) { // if (true) {
// } else { // } else {
// break; // break;
// } // }
// } // }
auto* cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true));
auto* else_body = create<ast::BlockStatement>( auto* else_body = create<ast::BlockStatement>(
Source{}, ast::StatementList{ Source{}, ast::StatementList{
create<ast::BreakStatement>(Source{}), create<ast::BreakStatement>(Source{}),
}); });
auto* if_stmt = create<ast::IfStatement>( auto* if_stmt = create<ast::IfStatement>(
Source{}, cond, Source{}, Expr(true),
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::ElseStatementList{ ast::ElseStatementList{
create<ast::ElseStatement>(Source{}, nullptr, else_body)}); create<ast::ElseStatement>(Source{}, nullptr, else_body)});
@ -547,21 +417,17 @@ OpBranch %1
} }
TEST_F(BuilderTest, If_WithContinue) { TEST_F(BuilderTest, If_WithContinue) {
ast::type::Bool bool_type;
// loop { // loop {
// if (true) { // if (true) {
// continue; // continue;
// } // }
// } // }
auto* cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true));
auto* if_body = create<ast::BlockStatement>( auto* if_body = create<ast::BlockStatement>(
Source{}, ast::StatementList{ Source{}, ast::StatementList{
create<ast::ContinueStatement>(Source{}), create<ast::ContinueStatement>(Source{}),
}); });
auto* if_stmt = create<ast::IfStatement>(Source{}, cond, if_body, auto* if_stmt = create<ast::IfStatement>(Source{}, Expr(true), if_body,
ast::ElseStatementList{}); ast::ElseStatementList{});
auto* loop_body = create<ast::BlockStatement>(Source{}, ast::StatementList{ auto* loop_body = create<ast::BlockStatement>(Source{}, ast::StatementList{
@ -599,23 +465,19 @@ OpBranch %1
} }
TEST_F(BuilderTest, If_WithElseContinue) { TEST_F(BuilderTest, If_WithElseContinue) {
ast::type::Bool bool_type;
// loop { // loop {
// if (true) { // if (true) {
// } else { // } else {
// continue; // continue;
// } // }
// } // }
auto* cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true));
auto* else_body = create<ast::BlockStatement>( auto* else_body = create<ast::BlockStatement>(
Source{}, ast::StatementList{ Source{}, ast::StatementList{
create<ast::ContinueStatement>(Source{}), create<ast::ContinueStatement>(Source{}),
}); });
auto* if_stmt = create<ast::IfStatement>( auto* if_stmt = create<ast::IfStatement>(
Source{}, cond, Source{}, Expr(true),
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::ElseStatementList{ ast::ElseStatementList{
create<ast::ElseStatement>(Source{}, nullptr, else_body)}); create<ast::ElseStatement>(Source{}, nullptr, else_body)});
@ -657,20 +519,16 @@ OpBranch %1
} }
TEST_F(BuilderTest, If_WithReturn) { TEST_F(BuilderTest, If_WithReturn) {
ast::type::Bool bool_type;
// if (true) { // if (true) {
// return; // return;
// } // }
auto* cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true));
auto* if_body = create<ast::BlockStatement>( auto* if_body = create<ast::BlockStatement>(
Source{}, ast::StatementList{ Source{}, ast::StatementList{
create<ast::ReturnStatement>(Source{}), create<ast::ReturnStatement>(Source{}),
}); });
ast::IfStatement expr(Source{}, cond, if_body, ast::ElseStatementList{}); ast::IfStatement expr(Source{}, Expr(true), if_body,
ast::ElseStatementList{});
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
@ -689,22 +547,16 @@ OpReturn
} }
TEST_F(BuilderTest, If_WithReturnValue) { TEST_F(BuilderTest, If_WithReturnValue) {
ast::type::Bool bool_type;
// if (true) { // if (true) {
// return false; // return false;
// } // }
auto* cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, true));
auto* cond2 = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, false));
auto* if_body = create<ast::BlockStatement>( auto* if_body = create<ast::BlockStatement>(
Source{}, ast::StatementList{ Source{}, ast::StatementList{
create<ast::ReturnStatement>(Source{}, cond2), create<ast::ReturnStatement>(Source{}, Expr(false)),
}); });
ast::IfStatement expr(Source{}, cond, if_body, ast::ElseStatementList{}); ast::IfStatement expr(Source{}, Expr(true), if_body,
ast::ElseStatementList{});
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
@ -728,21 +580,11 @@ TEST_F(BuilderTest, If_WithLoad_Bug327) {
// if (a) { // if (a) {
// } // }
ast::type::Bool bool_type; auto* var = Var("a", ast::StorageClass::kFunction, ty.bool_);
auto* var =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kFunction, // storage_class
&bool_type, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);
ast::IfStatement expr( ast::IfStatement expr(
Source{}, Source{}, Expr("a"),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("a"),
"a"),
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::ElseStatementList{}); ast::ElseStatementList{});

View File

@ -1283,10 +1283,8 @@ TEST_F(IntrinsicBuilderTest, Call_ArrayLength) {
auto* s = auto* s =
create<ast::Struct>(ast::StructMemberList{Member("a", ty.array<f32>())}, create<ast::Struct>(ast::StructMemberList{Member("a", ty.array<f32>())},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); auto* s_type = ty.struct_("my_struct", s);
auto* var = Var("b", ast::StorageClass::kPrivate, s_type);
auto* var = Var("b", ast::StorageClass::kPrivate, &s_type);
auto* expr = Call("arrayLength", create<ast::MemberAccessorExpression>( auto* expr = Call("arrayLength", create<ast::MemberAccessorExpression>(
Expr("b"), Expr("a"))); Expr("b"), Expr("a")));
@ -1321,9 +1319,8 @@ TEST_F(IntrinsicBuilderTest, Call_ArrayLength_OtherMembersInStruct) {
ast::StructMemberList{Member("z", ty.f32), Member("a", ty.array<f32>())}, ast::StructMemberList{Member("z", ty.f32), Member("a", ty.array<f32>())},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); auto* s_type = ty.struct_("my_struct", s);
auto* var = Var("b", ast::StorageClass::kPrivate, s_type);
auto* var = Var("b", ast::StorageClass::kPrivate, &s_type);
auto* expr = Call("arrayLength", create<ast::MemberAccessorExpression>( auto* expr = Call("arrayLength", create<ast::MemberAccessorExpression>(
Expr("b"), Expr("a"))); Expr("b"), Expr("a")));
@ -1358,13 +1355,10 @@ TEST_F(IntrinsicBuilderTest, DISABLED_Call_ArrayLength_Ptr) {
ast::type::Pointer ptr(ty.array<f32>(), ast::StorageClass::kStorageBuffer); ast::type::Pointer ptr(ty.array<f32>(), ast::StorageClass::kStorageBuffer);
auto* s = create<ast::Struct>( auto* s = create<ast::Struct>(
ast::StructMemberList{Member("z", ty.f32), Member("a", ty.array<f32>()) ast::StructMemberList{Member("z", ty.f32), Member("a", ty.array<f32>())},
},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); auto* s_type = ty.struct_("my_struct", s);
auto* var = Var("b", ast::StorageClass::kPrivate, s_type);
auto* var = Var("b", ast::StorageClass::kPrivate, &s_type);
Var("ptr_var", ast::StorageClass::kPrivate, &ptr, Var("ptr_var", ast::StorageClass::kPrivate, &ptr,
create<ast::MemberAccessorExpression>(Expr("b"), Expr("a")), {}); create<ast::MemberAccessorExpression>(Expr("b"), Expr("a")), {});

View File

@ -61,30 +61,15 @@ OpBranch %1
} }
TEST_F(BuilderTest, Loop_WithoutContinuing) { TEST_F(BuilderTest, Loop_WithoutContinuing) {
ast::type::I32 i32;
// loop { // loop {
// v = 2; // v = 2;
// } // }
auto* var =
create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* var = Var("v", ast::StorageClass::kPrivate, ty.i32);
auto* body = create<ast::BlockStatement>( auto* body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(2))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2))),
});
ast::LoopStatement loop( ast::LoopStatement loop(
Source{}, body, Source{}, body,
create<ast::BlockStatement>(Source{}, ast::StatementList{})); create<ast::BlockStatement>(Source{}, ast::StatementList{}));
@ -125,35 +110,14 @@ TEST_F(BuilderTest, Loop_WithContinuing) {
// } // }
// } // }
auto* var = auto* var = Var("v", ast::StorageClass::kPrivate, ty.i32);
create<ast::Variable>(Source{}, // source
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* body = create<ast::BlockStatement>( auto* body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(2))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2))),
});
auto* continuing = create<ast::BlockStatement>( auto* continuing = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(3))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 3))),
});
ast::LoopStatement loop(Source{}, body, continuing); ast::LoopStatement loop(Source{}, body, continuing);
td.RegisterVariableForTesting(var); td.RegisterVariableForTesting(var);

View File

@ -46,18 +46,9 @@ TEST_F(BuilderTest, Return) {
} }
TEST_F(BuilderTest, Return_WithValue) { TEST_F(BuilderTest, Return_WithValue) {
ast::type::F32 f32; auto* val = create<ast::TypeConstructorExpression>(
ast::type::Vector vec(&f32, 3); Source{}, ty.vec3<f32>(),
ast::ExpressionList{Expr(1.f), Expr(1.f), Expr(3.f)});
ast::ExpressionList vals;
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f)));
vals.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 3.0f)));
auto* val = create<ast::TypeConstructorExpression>(Source{}, &vec, vals);
ast::ReturnStatement ret(Source{}, val); ast::ReturnStatement ret(Source{}, val);
@ -79,20 +70,15 @@ TEST_F(BuilderTest, Return_WithValue) {
} }
TEST_F(BuilderTest, Return_WithValue_GeneratesLoad) { TEST_F(BuilderTest, Return_WithValue_GeneratesLoad) {
ast::type::F32 f32; auto* var = Var("param", ast::StorageClass::kFunction, ty.f32);
ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &f32, ast::ReturnStatement ret(Source{}, Expr("param"));
false, nullptr, ast::VariableDecorationList{});
ast::ReturnStatement ret( td.RegisterVariableForTesting(var);
Source{}, create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("param"), "param"));
td.RegisterVariableForTesting(&var);
EXPECT_TRUE(td.DetermineResultType(&ret)) << td.error(); EXPECT_TRUE(td.DetermineResultType(&ret)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_TRUE(b.GenerateReturnStatement(&ret)) << b.error(); EXPECT_TRUE(b.GenerateReturnStatement(&ret)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();

View File

@ -40,15 +40,10 @@ namespace {
using BuilderTest = TestHelper; using BuilderTest = TestHelper;
TEST_F(BuilderTest, Switch_Empty) { TEST_F(BuilderTest, Switch_Empty) {
ast::type::I32 i32;
// switch (1) { // switch (1) {
// } // }
auto* cond = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1));
ast::SwitchStatement expr(Source{}, cond, ast::CaseStatementList{});
ast::SwitchStatement expr(Source{}, Expr(1), ast::CaseStatementList{});
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
@ -67,8 +62,6 @@ OpBranch %1
} }
TEST_F(BuilderTest, Switch_WithCase) { TEST_F(BuilderTest, Switch_WithCase) {
ast::type::I32 i32;
// switch(a) { // switch(a) {
// case 1: // case 1:
// v = 1; // v = 1;
@ -76,50 +69,22 @@ TEST_F(BuilderTest, Switch_WithCase) {
// v = 2; // v = 2;
// } // }
auto* v = auto* v = Var("v", ast::StorageClass::kPrivate, ty.i32);
create<ast::Variable>(Source{}, // source auto* a = Var("a", ast::StorageClass::kPrivate, ty.i32);
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* a =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* case_1_body = create<ast::BlockStatement>( auto* case_1_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(1))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1))),
});
auto* case_2_body = create<ast::BlockStatement>( auto* case_2_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(2))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2))),
});
ast::CaseSelectorList selector_1; ast::CaseSelectorList selector_1;
selector_1.push_back(create<ast::SintLiteral>(Source{}, &i32, 1)); selector_1.push_back(Literal(1));
ast::CaseSelectorList selector_2; ast::CaseSelectorList selector_2;
selector_2.push_back(create<ast::SintLiteral>(Source{}, &i32, 2)); selector_2.push_back(Literal(2));
ast::CaseStatementList cases; ast::CaseStatementList cases;
cases.push_back( cases.push_back(
@ -127,23 +92,18 @@ TEST_F(BuilderTest, Switch_WithCase) {
cases.push_back( cases.push_back(
create<ast::CaseStatement>(Source{}, selector_2, case_2_body)); create<ast::CaseStatement>(Source{}, selector_2, case_2_body));
ast::SwitchStatement expr(Source{}, ast::SwitchStatement expr(Source{}, Expr("a"), cases);
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("a"), "a"),
cases);
td.RegisterVariableForTesting(v); td.RegisterVariableForTesting(v);
td.RegisterVariableForTesting(a); td.RegisterVariableForTesting(a);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ast::Function func( auto* func = Func("a_func", {}, ty.i32, ast::StatementList{},
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, &i32,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error(); EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error();
@ -178,62 +138,34 @@ OpFunctionEnd
} }
TEST_F(BuilderTest, Switch_WithDefault) { TEST_F(BuilderTest, Switch_WithDefault) {
ast::type::I32 i32;
// switch(true) { // switch(true) {
// default: // default:
// v = 1; // v = 1;
// } // }
auto* v = auto* v = Var("v", ast::StorageClass::kPrivate, ty.i32);
create<ast::Variable>(Source{}, // source auto* a = Var("a", ast::StorageClass::kPrivate, ty.i32);
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* a =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* default_body = create<ast::BlockStatement>( auto* default_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(1))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1))),
});
ast::CaseStatementList cases; ast::CaseStatementList cases;
cases.push_back(create<ast::CaseStatement>(Source{}, ast::CaseSelectorList{}, cases.push_back(create<ast::CaseStatement>(Source{}, ast::CaseSelectorList{},
default_body)); default_body));
ast::SwitchStatement expr(Source{}, ast::SwitchStatement expr(Source{}, Expr("a"), cases);
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("a"), "a"),
cases);
td.RegisterVariableForTesting(v); td.RegisterVariableForTesting(v);
td.RegisterVariableForTesting(a); td.RegisterVariableForTesting(a);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ast::Function func( auto* func = Func("a_func", {}, ty.i32, ast::StatementList{},
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, &i32,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error(); EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error();
@ -262,8 +194,6 @@ OpFunctionEnd
} }
TEST_F(BuilderTest, Switch_WithCaseAndDefault) { TEST_F(BuilderTest, Switch_WithCaseAndDefault) {
ast::type::I32 i32;
// switch(a) { // switch(a) {
// case 1: // case 1:
// v = 1; // v = 1;
@ -273,62 +203,27 @@ TEST_F(BuilderTest, Switch_WithCaseAndDefault) {
// v = 3; // v = 3;
// } // }
auto* v = auto* v = Var("v", ast::StorageClass::kPrivate, ty.i32);
create<ast::Variable>(Source{}, // source auto* a = Var("a", ast::StorageClass::kPrivate, ty.i32);
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* a =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* case_1_body = create<ast::BlockStatement>( auto* case_1_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(1))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1))),
});
auto* case_2_body = create<ast::BlockStatement>( auto* case_2_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(2))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2))),
});
auto* default_body = create<ast::BlockStatement>( auto* default_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(3))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 3))),
});
ast::CaseSelectorList selector_1; ast::CaseSelectorList selector_1;
selector_1.push_back(create<ast::SintLiteral>(Source{}, &i32, 1)); selector_1.push_back(Literal(1));
ast::CaseSelectorList selector_2; ast::CaseSelectorList selector_2;
selector_2.push_back(create<ast::SintLiteral>(Source{}, &i32, 2)); selector_2.push_back(Literal(2));
selector_2.push_back(create<ast::SintLiteral>(Source{}, &i32, 3)); selector_2.push_back(Literal(3));
ast::CaseStatementList cases; ast::CaseStatementList cases;
cases.push_back( cases.push_back(
@ -338,23 +233,18 @@ TEST_F(BuilderTest, Switch_WithCaseAndDefault) {
cases.push_back(create<ast::CaseStatement>(Source{}, ast::CaseSelectorList{}, cases.push_back(create<ast::CaseStatement>(Source{}, ast::CaseSelectorList{},
default_body)); default_body));
ast::SwitchStatement expr(Source{}, ast::SwitchStatement expr(Source{}, Expr("a"), cases);
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("a"), "a"),
cases);
td.RegisterVariableForTesting(v); td.RegisterVariableForTesting(v);
td.RegisterVariableForTesting(a); td.RegisterVariableForTesting(a);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ast::Function func( auto* func = Func("a_func", {}, ty.i32, ast::StatementList{},
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, &i32,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error(); EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error();
@ -391,8 +281,6 @@ OpFunctionEnd
} }
TEST_F(BuilderTest, Switch_CaseWithFallthrough) { TEST_F(BuilderTest, Switch_CaseWithFallthrough) {
ast::type::I32 i32;
// switch(a) { // switch(a) {
// case 1: // case 1:
// v = 1; // v = 1;
@ -403,61 +291,28 @@ TEST_F(BuilderTest, Switch_CaseWithFallthrough) {
// v = 3; // v = 3;
// } // }
auto* v = auto* v = Var("v", ast::StorageClass::kPrivate, ty.i32);
create<ast::Variable>(Source{}, // source auto* a = Var("a", ast::StorageClass::kPrivate, ty.i32);
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* a =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* case_1_body = create<ast::BlockStatement>( auto* case_1_body = create<ast::BlockStatement>(
Source{}, Source{},
ast::StatementList{ ast::StatementList{
create<ast::AssignmentStatement>( create<ast::AssignmentStatement>(Source{}, Expr("v"), Expr(1)),
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1))),
create<ast::FallthroughStatement>(Source{})}); create<ast::FallthroughStatement>(Source{})});
auto* case_2_body = create<ast::BlockStatement>( auto* case_2_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(2))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2))),
});
auto* default_body = create<ast::BlockStatement>( auto* default_body = create<ast::BlockStatement>(
Source{}, Source{}, ast::StatementList{create<ast::AssignmentStatement>(
ast::StatementList{ Source{}, Expr("v"), Expr(3))});
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 3))),
});
ast::CaseSelectorList selector_1; ast::CaseSelectorList selector_1;
selector_1.push_back(create<ast::SintLiteral>(Source{}, &i32, 1)); selector_1.push_back(Literal(1));
ast::CaseSelectorList selector_2; ast::CaseSelectorList selector_2;
selector_2.push_back(create<ast::SintLiteral>(Source{}, &i32, 2)); selector_2.push_back(Literal(2));
ast::CaseStatementList cases; ast::CaseStatementList cases;
cases.push_back( cases.push_back(
@ -467,23 +322,18 @@ TEST_F(BuilderTest, Switch_CaseWithFallthrough) {
cases.push_back(create<ast::CaseStatement>(Source{}, ast::CaseSelectorList{}, cases.push_back(create<ast::CaseStatement>(Source{}, ast::CaseSelectorList{},
default_body)); default_body));
ast::SwitchStatement expr(Source{}, ast::SwitchStatement expr(Source{}, Expr("a"), cases);
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("a"), "a"),
cases);
td.RegisterVariableForTesting(v); td.RegisterVariableForTesting(v);
td.RegisterVariableForTesting(a); td.RegisterVariableForTesting(a);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ast::Function func( auto* func = Func("a_func", {}, ty.i32, ast::StatementList{},
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, &i32,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error(); EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error();
@ -520,75 +370,46 @@ OpFunctionEnd
} }
TEST_F(BuilderTest, Switch_CaseFallthroughLastStatement) { TEST_F(BuilderTest, Switch_CaseFallthroughLastStatement) {
ast::type::I32 i32;
// switch(a) { // switch(a) {
// case 1: // case 1:
// v = 1; // v = 1;
// fallthrough; // fallthrough;
// } // }
auto* v = auto* v = Var("v", ast::StorageClass::kPrivate, ty.i32);
create<ast::Variable>(Source{}, // source auto* a = Var("a", ast::StorageClass::kPrivate, ty.i32);
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* a =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* case_1_body = create<ast::BlockStatement>( auto* case_1_body = create<ast::BlockStatement>(
Source{}, Source{},
ast::StatementList{ ast::StatementList{
create<ast::AssignmentStatement>( create<ast::AssignmentStatement>(Source{}, Expr("v"), Expr(1)),
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1))),
create<ast::FallthroughStatement>(Source{})}); create<ast::FallthroughStatement>(Source{})});
ast::CaseSelectorList selector_1; ast::CaseSelectorList selector_1;
selector_1.push_back(create<ast::SintLiteral>(Source{}, &i32, 1)); selector_1.push_back(Literal(1));
ast::CaseStatementList cases; ast::CaseStatementList cases;
cases.push_back( cases.push_back(
create<ast::CaseStatement>(Source{}, selector_1, case_1_body)); create<ast::CaseStatement>(Source{}, selector_1, case_1_body));
ast::SwitchStatement expr(Source{}, ast::SwitchStatement expr(Source{}, Expr("a"), cases);
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("a"), "a"),
cases);
td.RegisterVariableForTesting(v); td.RegisterVariableForTesting(v);
td.RegisterVariableForTesting(a); td.RegisterVariableForTesting(a);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ast::Function func( auto* func = Func("a_func", {}, ty.i32, ast::StatementList{},
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, &i32,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_FALSE(b.GenerateSwitchStatement(&expr)) << b.error(); EXPECT_FALSE(b.GenerateSwitchStatement(&expr)) << b.error();
EXPECT_EQ(b.error(), "fallthrough of last case statement is disallowed"); EXPECT_EQ(b.error(), "fallthrough of last case statement is disallowed");
} }
TEST_F(BuilderTest, Switch_WithNestedBreak) { TEST_F(BuilderTest, Switch_WithNestedBreak) {
ast::type::I32 i32;
ast::type::Bool bool_type;
// switch (a) { // switch (a) {
// case 1: // case 1:
// if (true) { // if (true) {
@ -597,22 +418,8 @@ TEST_F(BuilderTest, Switch_WithNestedBreak) {
// v = 1; // v = 1;
// } // }
auto* v = auto* v = Var("v", ast::StorageClass::kPrivate, ty.i32);
create<ast::Variable>(Source{}, // source auto* a = Var("a", ast::StorageClass::kPrivate, ty.i32);
"v", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* a =
create<ast::Variable>(Source{}, // source
"a", // name
ast::StorageClass::kPrivate, // storage_class
&i32, // type
false, // is_const
nullptr, // constructor
ast::VariableDecorationList{}); // decorations
auto* if_body = create<ast::BlockStatement>( auto* if_body = create<ast::BlockStatement>(
Source{}, ast::StatementList{ Source{}, ast::StatementList{
@ -622,43 +429,29 @@ TEST_F(BuilderTest, Switch_WithNestedBreak) {
auto* case_1_body = create<ast::BlockStatement>( auto* case_1_body = create<ast::BlockStatement>(
Source{}, Source{},
ast::StatementList{ ast::StatementList{
create<ast::IfStatement>( create<ast::IfStatement>(Source{}, Expr(true), if_body,
Source{}, ast::ElseStatementList{}),
create<ast::ScalarConstructorExpression>( create<ast::AssignmentStatement>(Source{}, Expr("v"), Expr(1))});
Source{},
create<ast::BoolLiteral>(Source{}, &bool_type, true)),
if_body, ast::ElseStatementList{}),
create<ast::AssignmentStatement>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("v"), "v"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)))});
ast::CaseSelectorList selector_1; ast::CaseSelectorList selector_1;
selector_1.push_back(create<ast::SintLiteral>(Source{}, &i32, 1)); selector_1.push_back(Literal(1));
ast::CaseStatementList cases; ast::CaseStatementList cases;
cases.push_back( cases.push_back(
create<ast::CaseStatement>(Source{}, selector_1, case_1_body)); create<ast::CaseStatement>(Source{}, selector_1, case_1_body));
ast::SwitchStatement expr(Source{}, ast::SwitchStatement expr(Source{}, Expr("a"), cases);
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("a"), "a"),
cases);
td.RegisterVariableForTesting(v); td.RegisterVariableForTesting(v);
td.RegisterVariableForTesting(a); td.RegisterVariableForTesting(a);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
ast::Function func( auto* func = Func("a_func", {}, ty.i32, ast::StatementList{},
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, &i32,
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error(); EXPECT_TRUE(b.GenerateSwitchStatement(&expr)) << b.error();

View File

@ -52,10 +52,8 @@ namespace {
using BuilderTest_Type = TestHelper; using BuilderTest_Type = TestHelper;
TEST_F(BuilderTest_Type, GenerateAlias) { TEST_F(BuilderTest_Type, GenerateAlias) {
ast::type::F32 f32; auto* alias_type = ty.alias("my_type", ty.f32);
ast::type::Alias alias_type(mod->RegisterSymbol("my_type"), "my_type", &f32); auto id = b.GenerateTypeIfNeeded(alias_type);
auto id = b.GenerateTypeIfNeeded(&alias_type);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -65,24 +63,20 @@ TEST_F(BuilderTest_Type, GenerateAlias) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedAlias) { TEST_F(BuilderTest_Type, ReturnsGeneratedAlias) {
ast::type::I32 i32; auto* alias_type = ty.alias("my_type", ty.f32);
ast::type::F32 f32;
ast::type::Alias alias_type(mod->RegisterSymbol("my_type"), "my_type", &f32);
EXPECT_EQ(b.GenerateTypeIfNeeded(&alias_type), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(alias_type), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 2u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 2u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&alias_type), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(alias_type), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&f32), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.f32), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
} }
TEST_F(BuilderTest_Type, GenerateRuntimeArray) { TEST_F(BuilderTest_Type, GenerateRuntimeArray) {
ast::type::I32 i32; ast::type::Array ary(ty.i32, 0, ast::ArrayDecorationList{});
ast::type::Array ary(&i32, 0, ast::ArrayDecorationList{});
auto id = b.GenerateTypeIfNeeded(&ary); auto id = b.GenerateTypeIfNeeded(&ary);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(1u, id); EXPECT_EQ(1u, id);
@ -93,8 +87,7 @@ TEST_F(BuilderTest_Type, GenerateRuntimeArray) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedRuntimeArray) { TEST_F(BuilderTest_Type, ReturnsGeneratedRuntimeArray) {
ast::type::I32 i32; ast::type::Array ary(ty.i32, 0, ast::ArrayDecorationList{});
ast::type::Array ary(&i32, 0, ast::ArrayDecorationList{});
EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u);
EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u);
@ -106,9 +99,7 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedRuntimeArray) {
} }
TEST_F(BuilderTest_Type, GenerateArray) { TEST_F(BuilderTest_Type, GenerateArray) {
ast::type::I32 i32; ast::type::Array ary(ty.i32, 4, ast::ArrayDecorationList{});
ast::type::Array ary(&i32, 4, ast::ArrayDecorationList{});
auto id = b.GenerateTypeIfNeeded(&ary); auto id = b.GenerateTypeIfNeeded(&ary);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(1u, id); EXPECT_EQ(1u, id);
@ -121,9 +112,7 @@ TEST_F(BuilderTest_Type, GenerateArray) {
} }
TEST_F(BuilderTest_Type, GenerateArray_WithStride) { TEST_F(BuilderTest_Type, GenerateArray_WithStride) {
ast::type::I32 i32; ast::type::Array ary(ty.i32, 4,
ast::type::Array ary(&i32, 4,
ast::ArrayDecorationList{ ast::ArrayDecorationList{
create<ast::StrideDecoration>(Source{}, 16u), create<ast::StrideDecoration>(Source{}, 16u),
}); });
@ -143,8 +132,7 @@ TEST_F(BuilderTest_Type, GenerateArray_WithStride) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedArray) { TEST_F(BuilderTest_Type, ReturnsGeneratedArray) {
ast::type::I32 i32; ast::type::Array ary(ty.i32, 4, ast::ArrayDecorationList{});
ast::type::Array ary(&i32, 4, ast::ArrayDecorationList{});
EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u);
EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&ary), 1u);
@ -158,9 +146,7 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedArray) {
} }
TEST_F(BuilderTest_Type, GenerateBool) { TEST_F(BuilderTest_Type, GenerateBool) {
ast::type::Bool bool_type; auto id = b.GenerateTypeIfNeeded(ty.bool_);
auto id = b.GenerateTypeIfNeeded(&bool_type);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -170,21 +156,16 @@ TEST_F(BuilderTest_Type, GenerateBool) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedBool) { TEST_F(BuilderTest_Type, ReturnsGeneratedBool) {
ast::type::I32 i32; EXPECT_EQ(b.GenerateTypeIfNeeded(ty.bool_), 1u);
ast::type::Bool bool_type;
EXPECT_EQ(b.GenerateTypeIfNeeded(&bool_type), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 2u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 2u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&bool_type), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.bool_), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
} }
TEST_F(BuilderTest_Type, GenerateF32) { TEST_F(BuilderTest_Type, GenerateF32) {
ast::type::F32 f32; auto id = b.GenerateTypeIfNeeded(ty.f32);
auto id = b.GenerateTypeIfNeeded(&f32);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -194,21 +175,16 @@ TEST_F(BuilderTest_Type, GenerateF32) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedF32) { TEST_F(BuilderTest_Type, ReturnsGeneratedF32) {
ast::type::I32 i32; EXPECT_EQ(b.GenerateTypeIfNeeded(ty.f32), 1u);
ast::type::F32 f32;
EXPECT_EQ(b.GenerateTypeIfNeeded(&f32), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 2u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 2u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&f32), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.f32), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
} }
TEST_F(BuilderTest_Type, GenerateI32) { TEST_F(BuilderTest_Type, GenerateI32) {
ast::type::I32 i32; auto id = b.GenerateTypeIfNeeded(ty.i32);
auto id = b.GenerateTypeIfNeeded(&i32);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -218,22 +194,16 @@ TEST_F(BuilderTest_Type, GenerateI32) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedI32) { TEST_F(BuilderTest_Type, ReturnsGeneratedI32) {
ast::type::I32 i32; EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 1u);
ast::type::F32 f32;
EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&f32), 2u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.f32), 2u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
} }
TEST_F(BuilderTest_Type, GenerateMatrix) { TEST_F(BuilderTest_Type, GenerateMatrix) {
ast::type::F32 f32; auto id = b.GenerateTypeIfNeeded(ty.mat2x3<f32>());
ast::type::Matrix mat_type(&f32, 3, 2);
auto id = b.GenerateTypeIfNeeded(&mat_type);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -245,21 +215,17 @@ TEST_F(BuilderTest_Type, GenerateMatrix) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedMatrix) { TEST_F(BuilderTest_Type, ReturnsGeneratedMatrix) {
ast::type::I32 i32; auto* mat = ty.mat4x3<i32>();
ast::type::Matrix mat_type(&i32, 3, 4); EXPECT_EQ(b.GenerateTypeIfNeeded(mat), 1u);
EXPECT_EQ(b.GenerateTypeIfNeeded(&mat_type), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 3u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 3u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&mat_type), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(mat), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
} }
TEST_F(BuilderTest_Type, GeneratePtr) { TEST_F(BuilderTest_Type, GeneratePtr) {
ast::type::I32 i32; ast::type::Pointer ptr(ty.i32, ast::StorageClass::kOutput);
ast::type::Pointer ptr(&i32, ast::StorageClass::kOutput);
auto id = b.GenerateTypeIfNeeded(&ptr); auto id = b.GenerateTypeIfNeeded(&ptr);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(1u, id); EXPECT_EQ(1u, id);
@ -270,9 +236,7 @@ TEST_F(BuilderTest_Type, GeneratePtr) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedPtr) { TEST_F(BuilderTest_Type, ReturnsGeneratedPtr) {
ast::type::I32 i32; ast::type::Pointer ptr(ty.i32, ast::StorageClass::kOutput);
ast::type::Pointer ptr(&i32, ast::StorageClass::kOutput);
EXPECT_EQ(b.GenerateTypeIfNeeded(&ptr), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&ptr), 1u);
EXPECT_EQ(b.GenerateTypeIfNeeded(&ptr), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&ptr), 1u);
} }
@ -280,9 +244,9 @@ TEST_F(BuilderTest_Type, ReturnsGeneratedPtr) {
TEST_F(BuilderTest_Type, GenerateStruct_Empty) { TEST_F(BuilderTest_Type, GenerateStruct_Empty) {
auto* s = create<ast::Struct>(Source{}, ast::StructMemberList{}, auto* s = create<ast::Struct>(Source{}, ast::StructMemberList{},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("S"), "S", s); auto* s_type = ty.struct_("S", s);
auto id = b.GenerateTypeIfNeeded(&s_type); auto id = b.GenerateTypeIfNeeded(s_type);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -296,9 +260,9 @@ TEST_F(BuilderTest_Type, GenerateStruct_Empty) {
TEST_F(BuilderTest_Type, GenerateStruct) { TEST_F(BuilderTest_Type, GenerateStruct) {
auto* s = create<ast::Struct>(ast::StructMemberList{Member("a", ty.f32)}, auto* s = create<ast::Struct>(ast::StructMemberList{Member("a", ty.f32)},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); auto* s_type = ty.struct_("my_struct", s);
auto id = b.GenerateTypeIfNeeded(&s_type); auto id = b.GenerateTypeIfNeeded(s_type);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -316,9 +280,9 @@ TEST_F(BuilderTest_Type, GenerateStruct_Decorated) {
auto* s = create<ast::Struct>(ast::StructMemberList{Member("a", ty.f32)}, auto* s = create<ast::Struct>(ast::StructMemberList{Member("a", ty.f32)},
struct_decos); struct_decos);
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); auto* s_type = ty.struct_("my_struct", s);
auto id = b.GenerateTypeIfNeeded(&s_type); auto id = b.GenerateTypeIfNeeded(s_type);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -337,9 +301,9 @@ TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers) {
ast::StructMemberList{Member("a", ty.f32, {MemberOffset(0)}), ast::StructMemberList{Member("a", ty.f32, {MemberOffset(0)}),
Member("b", ty.f32, {MemberOffset(8)})}, Member("b", ty.f32, {MemberOffset(8)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("S"), "S", s); auto* s_type = ty.struct_("S", s);
auto id = b.GenerateTypeIfNeeded(&s_type); auto id = b.GenerateTypeIfNeeded(s_type);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -361,9 +325,9 @@ TEST_F(BuilderTest_Type, GenerateStruct_NonLayout_Matrix) {
Member("b", ty.mat2x3<f32>()), Member("b", ty.mat2x3<f32>()),
Member("c", ty.mat4x4<f32>())}, Member("c", ty.mat4x4<f32>())},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("S"), "S", s); auto* s_type = ty.struct_("S", s);
auto id = b.GenerateTypeIfNeeded(&s_type); auto id = b.GenerateTypeIfNeeded(s_type);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -391,9 +355,9 @@ TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutMatrix) {
Member("b", ty.mat2x3<f32>(), {MemberOffset(16)}), Member("b", ty.mat2x3<f32>(), {MemberOffset(16)}),
Member("c", ty.mat4x4<f32>(), {MemberOffset(48)})}, Member("c", ty.mat4x4<f32>(), {MemberOffset(48)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("S"), "S", s); auto* s_type = ty.struct_("S", s);
auto id = b.GenerateTypeIfNeeded(&s_type); auto id = b.GenerateTypeIfNeeded(s_type);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -442,9 +406,9 @@ TEST_F(BuilderTest_Type, GenerateStruct_DecoratedMembers_LayoutArraysOfMatrix) {
Member("b", &arr_arr_mat2x3, {MemberOffset(16)}), Member("b", &arr_arr_mat2x3, {MemberOffset(16)}),
Member("c", &rtarr_mat4x4, {MemberOffset(48)})}, Member("c", &rtarr_mat4x4, {MemberOffset(48)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("S"), "S", s); auto* s_type = ty.struct_("S", s);
auto id = b.GenerateTypeIfNeeded(&s_type); auto id = b.GenerateTypeIfNeeded(s_type);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -480,9 +444,7 @@ OpMemberDecorate %1 2 MatrixStride 16
} }
TEST_F(BuilderTest_Type, GenerateU32) { TEST_F(BuilderTest_Type, GenerateU32) {
ast::type::U32 u32; auto id = b.GenerateTypeIfNeeded(ty.u32);
auto id = b.GenerateTypeIfNeeded(&u32);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -492,22 +454,16 @@ TEST_F(BuilderTest_Type, GenerateU32) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedU32) { TEST_F(BuilderTest_Type, ReturnsGeneratedU32) {
ast::type::U32 u32; EXPECT_EQ(b.GenerateTypeIfNeeded(ty.u32), 1u);
ast::type::F32 f32;
EXPECT_EQ(b.GenerateTypeIfNeeded(&u32), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&f32), 2u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.f32), 2u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&u32), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.u32), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
} }
TEST_F(BuilderTest_Type, GenerateVector) { TEST_F(BuilderTest_Type, GenerateVector) {
ast::type::F32 f32; auto id = b.GenerateTypeIfNeeded(ty.vec3<f32>());
ast::type::Vector vec_type(&f32, 3);
auto id = b.GenerateTypeIfNeeded(&vec_type);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -518,21 +474,17 @@ TEST_F(BuilderTest_Type, GenerateVector) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedVector) { TEST_F(BuilderTest_Type, ReturnsGeneratedVector) {
ast::type::I32 i32; auto* vec_type = ty.vec3<i32>();
ast::type::Vector vec_type(&i32, 3); EXPECT_EQ(b.GenerateTypeIfNeeded(vec_type), 1u);
EXPECT_EQ(b.GenerateTypeIfNeeded(&vec_type), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 2u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 2u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&vec_type), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(vec_type), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
} }
TEST_F(BuilderTest_Type, GenerateVoid) { TEST_F(BuilderTest_Type, GenerateVoid) {
ast::type::Void void_type; auto id = b.GenerateTypeIfNeeded(ty.void_);
auto id = b.GenerateTypeIfNeeded(&void_type);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(id, 1u); EXPECT_EQ(id, 1u);
@ -542,14 +494,11 @@ TEST_F(BuilderTest_Type, GenerateVoid) {
} }
TEST_F(BuilderTest_Type, ReturnsGeneratedVoid) { TEST_F(BuilderTest_Type, ReturnsGeneratedVoid) {
ast::type::I32 i32; EXPECT_EQ(b.GenerateTypeIfNeeded(ty.void_), 1u);
ast::type::Void void_type;
EXPECT_EQ(b.GenerateTypeIfNeeded(&void_type), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&i32), 2u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.i32), 2u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(b.GenerateTypeIfNeeded(&void_type), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(ty.void_), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
} }
@ -637,8 +586,7 @@ TEST_F(BuilderTest_Type, DepthTexture_Generate_CubeArray) {
} }
TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_i32) { TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_i32) {
ast::type::I32 i32; ast::type::MultisampledTexture ms(ast::type::TextureDimension::k2d, ty.i32);
ast::type::MultisampledTexture ms(ast::type::TextureDimension::k2d, &i32);
EXPECT_EQ(1u, b.GenerateTypeIfNeeded(&ms)); EXPECT_EQ(1u, b.GenerateTypeIfNeeded(&ms));
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
@ -648,8 +596,7 @@ TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_i32) {
} }
TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_u32) { TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_u32) {
ast::type::U32 u32; ast::type::MultisampledTexture ms(ast::type::TextureDimension::k2d, ty.u32);
ast::type::MultisampledTexture ms(ast::type::TextureDimension::k2d, &u32);
EXPECT_EQ(b.GenerateTypeIfNeeded(&ms), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&ms), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
@ -660,8 +607,7 @@ TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_u32) {
} }
TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_f32) { TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_f32) {
ast::type::F32 f32; ast::type::MultisampledTexture ms(ast::type::TextureDimension::k2d, ty.f32);
ast::type::MultisampledTexture ms(ast::type::TextureDimension::k2d, &f32);
EXPECT_EQ(b.GenerateTypeIfNeeded(&ms), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&ms), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
@ -672,8 +618,7 @@ TEST_F(BuilderTest_Type, MultisampledTexture_Generate_2d_f32) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_i32) { TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_i32) {
ast::type::I32 i32; ast::type::SampledTexture s(ast::type::TextureDimension::k1d, ty.i32);
ast::type::SampledTexture s(ast::type::TextureDimension::k1d, &i32);
EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
@ -688,8 +633,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_i32) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_u32) { TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_u32) {
ast::type::U32 u32; ast::type::SampledTexture s(ast::type::TextureDimension::k1d, ty.u32);
ast::type::SampledTexture s(ast::type::TextureDimension::k1d, &u32);
EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
@ -704,8 +648,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_u32) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_f32) { TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_f32) {
ast::type::F32 f32; ast::type::SampledTexture s(ast::type::TextureDimension::k1d, ty.f32);
ast::type::SampledTexture s(ast::type::TextureDimension::k1d, &f32);
EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
@ -720,8 +663,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_1d_f32) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_1dArray) { TEST_F(BuilderTest_Type, SampledTexture_Generate_1dArray) {
ast::type::F32 f32; ast::type::SampledTexture s(ast::type::TextureDimension::k1dArray, ty.f32);
ast::type::SampledTexture s(ast::type::TextureDimension::k1dArray, &f32);
EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
@ -736,8 +678,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_1dArray) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_2d) { TEST_F(BuilderTest_Type, SampledTexture_Generate_2d) {
ast::type::F32 f32; ast::type::SampledTexture s(ast::type::TextureDimension::k2d, ty.f32);
ast::type::SampledTexture s(ast::type::TextureDimension::k2d, &f32);
EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
@ -748,8 +689,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_2d) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_2d_array) { TEST_F(BuilderTest_Type, SampledTexture_Generate_2d_array) {
ast::type::F32 f32; ast::type::SampledTexture s(ast::type::TextureDimension::k2dArray, ty.f32);
ast::type::SampledTexture s(ast::type::TextureDimension::k2dArray, &f32);
EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
@ -760,8 +700,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_2d_array) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_3d) { TEST_F(BuilderTest_Type, SampledTexture_Generate_3d) {
ast::type::F32 f32; ast::type::SampledTexture s(ast::type::TextureDimension::k3d, ty.f32);
ast::type::SampledTexture s(ast::type::TextureDimension::k3d, &f32);
EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
@ -772,8 +711,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_3d) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_Cube) { TEST_F(BuilderTest_Type, SampledTexture_Generate_Cube) {
ast::type::F32 f32; ast::type::SampledTexture s(ast::type::TextureDimension::kCube, ty.f32);
ast::type::SampledTexture s(ast::type::TextureDimension::kCube, &f32);
EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();
@ -785,8 +723,7 @@ TEST_F(BuilderTest_Type, SampledTexture_Generate_Cube) {
} }
TEST_F(BuilderTest_Type, SampledTexture_Generate_CubeArray) { TEST_F(BuilderTest_Type, SampledTexture_Generate_CubeArray) {
ast::type::F32 f32; ast::type::SampledTexture s(ast::type::TextureDimension::kCubeArray, ty.f32);
ast::type::SampledTexture s(ast::type::TextureDimension::kCubeArray, &f32);
EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u); EXPECT_EQ(b.GenerateTypeIfNeeded(&s), 1u);
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();

View File

@ -38,13 +38,7 @@ namespace {
using BuilderTest = TestHelper; using BuilderTest = TestHelper;
TEST_F(BuilderTest, UnaryOp_Negation_Integer) { TEST_F(BuilderTest, UnaryOp_Negation_Integer) {
ast::type::I32 i32; ast::UnaryOpExpression expr(Source{}, ast::UnaryOp::kNegation, Expr(1));
ast::UnaryOpExpression expr(
Source{}, ast::UnaryOp::kNegation,
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
@ -58,13 +52,7 @@ TEST_F(BuilderTest, UnaryOp_Negation_Integer) {
} }
TEST_F(BuilderTest, UnaryOp_Negation_Float) { TEST_F(BuilderTest, UnaryOp_Negation_Float) {
ast::type::F32 f32; ast::UnaryOpExpression expr(Source{}, ast::UnaryOp::kNegation, Expr(1.f));
ast::UnaryOpExpression expr(
Source{}, ast::UnaryOp::kNegation,
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1)));
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
@ -78,13 +66,7 @@ TEST_F(BuilderTest, UnaryOp_Negation_Float) {
} }
TEST_F(BuilderTest, UnaryOp_Not) { TEST_F(BuilderTest, UnaryOp_Not) {
ast::type::Bool bool_type; ast::UnaryOpExpression expr(Source{}, ast::UnaryOp::kNot, Expr(false));
ast::UnaryOpExpression expr(
Source{}, ast::UnaryOp::kNot,
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::BoolLiteral>(Source{}, &bool_type, false)));
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
@ -98,22 +80,15 @@ TEST_F(BuilderTest, UnaryOp_Not) {
} }
TEST_F(BuilderTest, UnaryOp_LoadRequired) { TEST_F(BuilderTest, UnaryOp_LoadRequired) {
ast::type::F32 f32; auto* var = Var("param", ast::StorageClass::kFunction, ty.vec3<f32>());
ast::type::Vector vec(&f32, 3);
ast::Variable var(Source{}, "param", ast::StorageClass::kFunction, &vec, ast::UnaryOpExpression expr(Source{}, ast::UnaryOp::kNegation, Expr("param"));
false, nullptr, ast::VariableDecorationList{});
ast::UnaryOpExpression expr( td.RegisterVariableForTesting(var);
Source{}, ast::UnaryOp::kNegation,
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("param"),
"param"));
td.RegisterVariableForTesting(&var);
EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error(); EXPECT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
EXPECT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateUnaryOpExpression(&expr), 6u) << b.error(); EXPECT_EQ(b.GenerateUnaryOpExpression(&expr), 6u) << b.error();
ASSERT_FALSE(b.has_error()) << b.error(); ASSERT_FALSE(b.has_error()) << b.error();

View File

@ -28,9 +28,8 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitAlias_F32) { TEST_F(WgslGeneratorImplTest, EmitAlias_F32) {
ast::type::Alias alias(mod->RegisterSymbol("a"), "a", ty.f32); auto* alias = ty.alias("a", ty.f32);
ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
ASSERT_TRUE(gen.EmitConstructedType(&alias)) << gen.error();
EXPECT_EQ(gen.result(), R"(type a = f32; EXPECT_EQ(gen.result(), R"(type a = f32;
)"); )");
} }
@ -41,11 +40,11 @@ TEST_F(WgslGeneratorImplTest, EmitConstructedType_Struct) {
Member("b", ty.i32, {MemberOffset(4)})}, Member("b", ty.i32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("A"), "A", str); auto* s = ty.struct_("A", str);
ast::type::Alias alias(mod->RegisterSymbol("B"), "B", &s); auto* alias = ty.alias("B", s);
ASSERT_TRUE(gen.EmitConstructedType(&s)) << gen.error(); ASSERT_TRUE(gen.EmitConstructedType(s)) << gen.error();
ASSERT_TRUE(gen.EmitConstructedType(&alias)) << gen.error(); ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
EXPECT_EQ(gen.result(), R"(struct A { EXPECT_EQ(gen.result(), R"(struct A {
a : f32; a : f32;
[[offset(4)]] [[offset(4)]]
@ -61,10 +60,10 @@ TEST_F(WgslGeneratorImplTest, EmitAlias_ToStruct) {
Member("b", ty.i32, {MemberOffset(4)})}, Member("b", ty.i32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("A"), "A", str); auto* s = ty.struct_("A", str);
ast::type::Alias alias(mod->RegisterSymbol("B"), "B", &s); auto* alias = ty.alias("B", s);
ASSERT_TRUE(gen.EmitConstructedType(&alias)) << gen.error(); ASSERT_TRUE(gen.EmitConstructedType(alias)) << gen.error();
EXPECT_EQ(gen.result(), R"(type B = A; EXPECT_EQ(gen.result(), R"(type B = A;
)"); )");
} }

View File

@ -171,8 +171,8 @@ TEST_F(WgslGeneratorImplTest,
auto* str = create<ast::Struct>( auto* str = create<ast::Struct>(
ast::StructMemberList{Member("d", ty.f32, {MemberOffset(0)})}, s_decos); ast::StructMemberList{Member("d", ty.f32, {MemberOffset(0)})}, s_decos);
ast::type::Struct s(mod->RegisterSymbol("Data"), "Data", str); auto* s = ty.struct_("Data", str);
ast::type::AccessControl ac(ast::AccessControl::kReadWrite, &s); ast::type::AccessControl ac(ast::AccessControl::kReadWrite, s);
auto* data_var = Var("data", ast::StorageClass::kStorageBuffer, &ac, nullptr, auto* data_var = Var("data", ast::StorageClass::kStorageBuffer, &ac, nullptr,
ast::VariableDecorationList{ ast::VariableDecorationList{
@ -181,7 +181,7 @@ TEST_F(WgslGeneratorImplTest,
create<ast::SetDecoration>(0), create<ast::SetDecoration>(0),
}); });
mod->AddConstructedType(&s); mod->AddConstructedType(s);
td.RegisterVariableForTesting(data_var); td.RegisterVariableForTesting(data_var);
mod->AddGlobalVariable(data_var); mod->AddGlobalVariable(data_var);

View File

@ -44,19 +44,17 @@ TEST_F(WgslGeneratorImplTest, Emit_If) {
} }
TEST_F(WgslGeneratorImplTest, Emit_IfWithElseIf) { TEST_F(WgslGeneratorImplTest, Emit_IfWithElseIf) {
auto* else_cond = create<ast::IdentifierExpression>(
mod->RegisterSymbol("else_cond"), "else_cond");
auto* else_body = create<ast::BlockStatement>(ast::StatementList{ auto* else_body = create<ast::BlockStatement>(ast::StatementList{
create<ast::DiscardStatement>(), create<ast::DiscardStatement>(),
}); });
auto* cond = Expr("cond");
auto* body = create<ast::BlockStatement>(ast::StatementList{ auto* body = create<ast::BlockStatement>(ast::StatementList{
create<ast::DiscardStatement>(), create<ast::DiscardStatement>(),
}); });
auto* i = create<ast::IfStatement>( auto* i = create<ast::IfStatement>(
cond, body, Expr("cond"), body,
ast::ElseStatementList{create<ast::ElseStatement>(else_cond, else_body)}); ast::ElseStatementList{
create<ast::ElseStatement>(Expr("else_cond"), else_body)});
gen.increment_indent(); gen.increment_indent();
@ -94,9 +92,6 @@ TEST_F(WgslGeneratorImplTest, Emit_IfWithElse) {
} }
TEST_F(WgslGeneratorImplTest, Emit_IfWithMultiple) { TEST_F(WgslGeneratorImplTest, Emit_IfWithMultiple) {
auto* else_cond = create<ast::IdentifierExpression>(
mod->RegisterSymbol("else_cond"), "else_cond");
auto* else_body = create<ast::BlockStatement>(ast::StatementList{ auto* else_body = create<ast::BlockStatement>(ast::StatementList{
create<ast::DiscardStatement>(), create<ast::DiscardStatement>(),
}); });
@ -105,14 +100,13 @@ TEST_F(WgslGeneratorImplTest, Emit_IfWithMultiple) {
create<ast::DiscardStatement>(), create<ast::DiscardStatement>(),
}); });
auto* cond = Expr("cond");
auto* body = create<ast::BlockStatement>(ast::StatementList{ auto* body = create<ast::BlockStatement>(ast::StatementList{
create<ast::DiscardStatement>(), create<ast::DiscardStatement>(),
}); });
auto* i = create<ast::IfStatement>( auto* i = create<ast::IfStatement>(
cond, body, Expr("cond"), body,
ast::ElseStatementList{ ast::ElseStatementList{
create<ast::ElseStatement>(else_cond, else_body), create<ast::ElseStatement>(Expr("else_cond"), else_body),
create<ast::ElseStatement>(nullptr, else_body_2), create<ast::ElseStatement>(nullptr, else_body_2),
}); });

View File

@ -48,9 +48,9 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, EmitType_Alias) { TEST_F(WgslGeneratorImplTest, EmitType_Alias) {
ast::type::Alias alias(mod->RegisterSymbol("alias"), "alias", ty.f32); auto* alias = ty.alias("alias", ty.f32);
ASSERT_TRUE(gen.EmitType(&alias)) << gen.error(); ASSERT_TRUE(gen.EmitType(alias)) << gen.error();
EXPECT_EQ(gen.result(), "alias"); EXPECT_EQ(gen.result(), "alias");
} }
@ -66,7 +66,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_Read) {
auto* str = auto* str =
create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32)}, decos); create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32)}, decos);
auto* s = create<ast::type::Struct>(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ast::type::AccessControl a(ast::AccessControl::kReadOnly, s); ast::type::AccessControl a(ast::AccessControl::kReadOnly, s);
@ -81,7 +81,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_AccessControl_ReadWrite) {
auto* str = auto* str =
create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32)}, decos); create<ast::Struct>(ast::StructMemberList{Member("a", ty.i32)}, decos);
auto* s = create<ast::type::Struct>(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ast::type::AccessControl a(ast::AccessControl::kReadWrite, s); ast::type::AccessControl a(ast::AccessControl::kReadWrite, s);
@ -150,9 +150,8 @@ TEST_F(WgslGeneratorImplTest, EmitType_Struct) {
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitType(s)) << gen.error();
ASSERT_TRUE(gen.EmitType(&s)) << gen.error();
EXPECT_EQ(gen.result(), "S"); EXPECT_EQ(gen.result(), "S");
} }
@ -162,9 +161,8 @@ TEST_F(WgslGeneratorImplTest, EmitType_StructDecl) {
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
ASSERT_TRUE(gen.EmitStructType(&s)) << gen.error();
EXPECT_EQ(gen.result(), R"(struct S { EXPECT_EQ(gen.result(), R"(struct S {
a : i32; a : i32;
[[offset(4)]] [[offset(4)]]
@ -182,9 +180,8 @@ TEST_F(WgslGeneratorImplTest, EmitType_Struct_WithDecoration) {
Member("b", ty.f32, {MemberOffset(4)})}, Member("b", ty.f32, {MemberOffset(4)})},
decos); decos);
ast::type::Struct s(mod->RegisterSymbol("S"), "S", str); auto* s = ty.struct_("S", str);
ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
ASSERT_TRUE(gen.EmitStructType(&s)) << gen.error();
EXPECT_EQ(gen.result(), R"([[block]] EXPECT_EQ(gen.result(), R"([[block]]
struct S { struct S {
a : i32; a : i32;

View File

@ -78,10 +78,7 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_Decorated_Multiple) {
} }
TEST_F(WgslGeneratorImplTest, EmitVariable_Constructor) { TEST_F(WgslGeneratorImplTest, EmitVariable_Constructor) {
auto* ident = create<ast::IdentifierExpression>( auto* v = Var("a", ast::StorageClass::kNone, ty.f32, Expr("initializer"),
mod->RegisterSymbol("initializer"), "initializer");
auto* v = Var("a", ast::StorageClass::kNone, ty.f32, ident,
ast::VariableDecorationList{}); ast::VariableDecorationList{});
ASSERT_TRUE(gen.EmitVariable(v)) << gen.error(); ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
@ -90,10 +87,7 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_Constructor) {
} }
TEST_F(WgslGeneratorImplTest, EmitVariable_Const) { TEST_F(WgslGeneratorImplTest, EmitVariable_Const) {
auto* ident = create<ast::IdentifierExpression>( auto* v = Const("a", ast::StorageClass::kNone, ty.f32, Expr("initializer"),
mod->RegisterSymbol("initializer"), "initializer");
auto* v = Const("a", ast::StorageClass::kNone, ty.f32, ident,
ast::VariableDecorationList{}); ast::VariableDecorationList{});
ASSERT_TRUE(gen.EmitVariable(v)) << gen.error(); ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();