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:
parent
e5d288be5e
commit
b5839939e1
|
@ -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
|
||||||
|
|
|
@ -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>());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,26 +43,20 @@ 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);
|
||||||
ASSERT_EQ(f->referenced_module_variables().size(), 1u);
|
ASSERT_EQ(f->referenced_module_variables().size(), 1u);
|
||||||
|
@ -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,9 +92,8 @@ 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);
|
||||||
f->add_referenced_module_variable(builtin1);
|
f->add_referenced_module_variable(builtin1);
|
||||||
|
@ -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,9 +130,8 @@ 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);
|
||||||
f->add_referenced_module_variable(builtin1);
|
f->add_referenced_module_variable(builtin1);
|
||||||
|
@ -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{},
|
||||||
|
FunctionDecorationList{});
|
||||||
|
|
||||||
auto main_sym = mod->RegisterSymbol("main");
|
auto main_sym = mod->RegisterSymbol("main");
|
||||||
|
|
||||||
auto* f = create<Function>(func_sym, "func", VariableList{}, ty.void_,
|
|
||||||
create<BlockStatement>(StatementList{}),
|
|
||||||
FunctionDecorationList{});
|
|
||||||
|
|
||||||
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,111 +162,87 @@ 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_,
|
||||||
create<DiscardStatement>(),
|
StatementList{
|
||||||
});
|
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_,
|
||||||
create<DiscardStatement>(),
|
StatementList{
|
||||||
nullptr,
|
create<DiscardStatement>(),
|
||||||
});
|
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_,
|
||||||
create<DiscardStatement>(),
|
StatementList{
|
||||||
nullptr,
|
create<DiscardStatement>(),
|
||||||
});
|
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>(),
|
},
|
||||||
});
|
FunctionDecorationList{});
|
||||||
|
|
||||||
auto* f = create<Function>(func_sym, "func", VariableList{}, ty.void_, body,
|
|
||||||
FunctionDecorationList{});
|
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
f->to_str(out, 2);
|
f->to_str(out, 2);
|
||||||
|
@ -297,14 +255,11 @@ 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>(),
|
},
|
||||||
});
|
FunctionDecorationList{create<WorkgroupDecoration>(2, 4, 6)});
|
||||||
auto* f = create<Function>(
|
|
||||||
func_sym, "func", VariableList{}, ty.void_, body,
|
|
||||||
FunctionDecorationList{create<WorkgroupDecoration>(2, 4, 6)});
|
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
f->to_str(out, 2);
|
f->to_str(out, 2);
|
||||||
|
@ -318,16 +273,14 @@ 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_,
|
||||||
create<DiscardStatement>(),
|
StatementList{
|
||||||
});
|
create<DiscardStatement>(),
|
||||||
auto* f = create<Function>(func_sym, "func", params, ty.void_, body,
|
},
|
||||||
FunctionDecorationList{});
|
FunctionDecorationList{});
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
f->to_str(out, 2);
|
f->to_str(out, 2);
|
||||||
|
@ -346,56 +299,41 @@ 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{},
|
||||||
|
FunctionDecorationList{});
|
||||||
auto* f = create<Function>(func_sym, "func", VariableList{}, ty.void_,
|
|
||||||
create<BlockStatement>(StatementList{}),
|
|
||||||
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{},
|
||||||
|
FunctionDecorationList{});
|
||||||
auto* f = create<Function>(func_sym, "func", VariableList{}, ty.void_,
|
|
||||||
create<BlockStatement>(StatementList{}),
|
|
||||||
FunctionDecorationList{});
|
|
||||||
uint32_t x = 0;
|
uint32_t x = 0;
|
||||||
uint32_t y = 0;
|
uint32_t y = 0;
|
||||||
uint32_t z = 0;
|
uint32_t z = 0;
|
||||||
|
@ -406,12 +344,9 @@ 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>(
|
FunctionDecorationList{create<WorkgroupDecoration>(2u, 4u, 6u)});
|
||||||
func_sym, "func", VariableList{}, ty.void_,
|
|
||||||
create<BlockStatement>(StatementList{}),
|
|
||||||
FunctionDecorationList{create<WorkgroupDecoration>(2u, 4u, 6u)});
|
|
||||||
|
|
||||||
uint32_t x = 0;
|
uint32_t x = 0;
|
||||||
uint32_t y = 0;
|
uint32_t y = 0;
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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]{
|
||||||
|
|
|
@ -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{},
|
||||||
|
ast::FunctionDecorationList{});
|
||||||
auto func_sym = m.RegisterSymbol("main");
|
mod->AddFunction(func);
|
||||||
auto* func = create<Function>(func_sym, "main", VariableList{}, ty.f32,
|
EXPECT_EQ(func, mod->FindFunctionBySymbol(mod->RegisterSymbol("main")));
|
||||||
create<BlockStatement>(StatementList{}),
|
|
||||||
ast::FunctionDecorationList{});
|
|
||||||
m.AddFunction(func);
|
|
||||||
EXPECT_EQ(func, m.FindFunctionBySymbol(func_sym));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
@ -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{})),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -277,20 +277,16 @@ 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);
|
ast::StatementList{
|
||||||
|
create<ast::AssignmentStatement>(Source{Source::Location{12, 34}},
|
||||||
auto* func =
|
Expr("global_var"), Expr(3.14f)),
|
||||||
Func("my_func", ast::VariableList{}, ty.void_,
|
create<ast::ReturnStatement>(),
|
||||||
ast::StatementList{
|
},
|
||||||
create<ast::AssignmentStatement>(
|
ast::FunctionDecorationList{
|
||||||
Source{Source::Location{12, 34}}, lhs, rhs),
|
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
|
||||||
create<ast::ReturnStatement>(),
|
});
|
||||||
},
|
|
||||||
ast::FunctionDecorationList{
|
|
||||||
create<ast::StageDecoration>(ast::PipelineStage::kVertex),
|
|
||||||
});
|
|
||||||
mod->AddFunction(func);
|
mod->AddFunction(func);
|
||||||
|
|
||||||
EXPECT_TRUE(td()->Determine()) << td()->error();
|
EXPECT_TRUE(td()->Determine()) << td()->error();
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)");
|
||||||
|
|
|
@ -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);
|
ast::VariableDecorationList{
|
||||||
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragCoord)});
|
||||||
|
|
||||||
auto* coord_var = create<ast::Variable>(
|
auto* depth_var =
|
||||||
Source{}, // source
|
Var("depth", ast::StorageClass::kOutput, ty.f32, nullptr,
|
||||||
"coord", // name
|
ast::VariableDecorationList{
|
||||||
ast::StorageClass::kInput, // storage_class
|
create<ast::BuiltinDecoration>(ast::Builtin::kFragDepth)});
|
||||||
&vec4, // type
|
|
||||||
false, // is_const
|
|
||||||
nullptr, // constructor
|
|
||||||
ast::VariableDecorationList{
|
|
||||||
// decorations
|
|
||||||
create<ast::BuiltinDecoration>(Source{}, ast::Builtin::kFragCoord),
|
|
||||||
});
|
|
||||||
|
|
||||||
auto* depth_var = create<ast::Variable>(
|
|
||||||
Source{}, // source
|
|
||||||
"depth", // name
|
|
||||||
ast::StorageClass::kOutput, // storage_class
|
|
||||||
&f32, // type
|
|
||||||
false, // is_const
|
|
||||||
nullptr, // constructor
|
|
||||||
ast::VariableDecorationList{
|
|
||||||
// decorations
|
|
||||||
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
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,12 +29,10 @@ 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{});
|
||||||
|
|
||||||
gen.increment_indent();
|
gen.increment_indent();
|
||||||
|
@ -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(Source{}, cond, body,
|
||||||
});
|
{create<ast::ElseStatement>(else_cond, else_body)});
|
||||||
ast::IfStatement i(
|
|
||||||
Source{}, cond, 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(Source{}, cond, body,
|
||||||
});
|
{create<ast::ElseStatement>(nullptr, else_body)});
|
||||||
ast::IfStatement i(
|
|
||||||
Source{}, cond, body,
|
|
||||||
{create<ast::ElseStatement>(Source{}, nullptr, else_body)});
|
|
||||||
|
|
||||||
gen.increment_indent();
|
gen.increment_indent();
|
||||||
|
|
||||||
|
@ -103,31 +92,28 @@ 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(Source{}, cond, body,
|
||||||
ast::IfStatement i(
|
{
|
||||||
Source{}, cond, body,
|
create<ast::ElseStatement>(else_cond, else_body),
|
||||||
{
|
create<ast::ElseStatement>(nullptr, else_body_2),
|
||||||
create<ast::ElseStatement>(Source{}, else_cond, else_body),
|
});
|
||||||
create<ast::ElseStatement>(Source{}, nullptr, else_body_2),
|
|
||||||
});
|
|
||||||
|
|
||||||
gen.increment_indent();
|
gen.increment_indent();
|
||||||
|
|
||||||
|
|
|
@ -50,23 +50,14 @@ 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(
|
||||||
std::string("metal::") + param.msl_name);
|
gen.generate_builtin_name(call->func()->As<ast::IdentifierExpression>()),
|
||||||
|
std::string("metal::") + param.msl_name);
|
||||||
}
|
}
|
||||||
INSTANTIATE_TEST_SUITE_P(MslGeneratorImplTest,
|
INSTANTIATE_TEST_SUITE_P(MslGeneratorImplTest,
|
||||||
MslImportData_SingleParamTest,
|
MslImportData_SingleParamTest,
|
||||||
|
@ -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)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,10 +36,9 @@ 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, {});
|
||||||
|
|
||||||
gen.increment_indent();
|
gen.increment_indent();
|
||||||
|
@ -52,14 +51,12 @@ 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>(ast::StatementList{
|
||||||
auto* continuing = create<ast::BlockStatement>(
|
create<ast::ReturnStatement>(),
|
||||||
Source{}, ast::StatementList{
|
});
|
||||||
create<ast::ReturnStatement>(Source{}),
|
|
||||||
});
|
|
||||||
ast::LoopStatement l(Source{}, body, continuing);
|
ast::LoopStatement l(Source{}, body, continuing);
|
||||||
|
|
||||||
gen.increment_indent();
|
gen.increment_indent();
|
||||||
|
@ -80,31 +77,21 @@ 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* continuing = create<ast::BlockStatement>(ast::StatementList{
|
||||||
|
create<ast::ReturnStatement>(),
|
||||||
|
});
|
||||||
|
auto* inner = create<ast::LoopStatement>(body, continuing);
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>(
|
body = create<ast::BlockStatement>(ast::StatementList{
|
||||||
Source{}, ast::StatementList{
|
inner,
|
||||||
create<ast::DiscardStatement>(Source{}),
|
});
|
||||||
});
|
|
||||||
auto* continuing = create<ast::BlockStatement>(
|
|
||||||
Source{}, ast::StatementList{
|
|
||||||
create<ast::ReturnStatement>(Source{}),
|
|
||||||
});
|
|
||||||
auto* inner = create<ast::LoopStatement>(Source{}, body, continuing);
|
|
||||||
|
|
||||||
body = create<ast::BlockStatement>(Source{}, ast::StatementList{
|
continuing = create<ast::BlockStatement>(ast::StatementList{
|
||||||
inner,
|
create<ast::AssignmentStatement>(Expr("lhs"), Expr("rhs")),
|
||||||
});
|
});
|
||||||
|
|
||||||
auto* lhs = create<ast::IdentifierExpression>(
|
|
||||||
Source{}, mod->RegisterSymbol("lhs"), "lhs");
|
|
||||||
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,43 +144,17 @@ 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();
|
||||||
|
|
||||||
ast::LoopStatement outer(Source{}, body, continuing);
|
ast::LoopStatement outer(Source{}, body, continuing);
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body);
|
||||||
auto* def =
|
|
||||||
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();
|
||||||
|
|
|
@ -48,13 +48,11 @@ 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(
|
ast::FunctionDecorationList{
|
||||||
"my_func", ast::VariableList{}, &void_type, ast::StatementList{},
|
create<ast::StageDecoration>(ast::PipelineStage::kCompute),
|
||||||
ast::FunctionDecorationList{
|
});
|
||||||
create<ast::StageDecoration>(Source{}, ast::PipelineStage::kCompute),
|
|
||||||
});
|
|
||||||
mod->AddFunction(func);
|
mod->AddFunction(func);
|
||||||
|
|
||||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||||
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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::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::CallStatement expr(
|
ast::CallStatement expr(Source{}, Call("a_func", 1.f, 1.f));
|
||||||
Source{}, create<ast::CallExpression>(
|
|
||||||
Source{},
|
|
||||||
create<ast::IdentifierExpression>(
|
|
||||||
Source{}, mod->RegisterSymbol("a_func"), "a_func"),
|
|
||||||
call_params));
|
|
||||||
|
|
||||||
ASSERT_TRUE(td.DetermineFunction(&func)) << td.error();
|
ASSERT_TRUE(td.DetermineFunction(func)) << td.error();
|
||||||
ASSERT_TRUE(td.DetermineFunction(&a_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"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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::FunctionDecorationList{
|
||||||
|
create<ast::StageDecoration>(Source{}, params.stage),
|
||||||
|
});
|
||||||
|
|
||||||
ast::Function func(
|
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||||
Source{}, mod->RegisterSymbol("main"), "main", {}, &void_type,
|
|
||||||
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
|
|
||||||
ast::FunctionDecorationList{
|
|
||||||
create<ast::StageDecoration>(Source{}, params.stage),
|
|
||||||
});
|
|
||||||
|
|
||||||
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{}, Expr("my_wg"), Expr("my_wg")),
|
||||||
Source{},
|
// Add duplicate usages so we show they don't get
|
||||||
create<ast::IdentifierExpression>(
|
// output multiple times.
|
||||||
Source{}, mod->RegisterSymbol("my_out"), "my_out"),
|
create<ast::AssignmentStatement>(
|
||||||
create<ast::IdentifierExpression>(
|
Source{}, Expr("my_out"), Expr("my_in"))},
|
||||||
Source{}, mod->RegisterSymbol("my_in"), "my_in")),
|
|
||||||
create<ast::AssignmentStatement>(
|
|
||||||
Source{},
|
|
||||||
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)),
|
||||||
},
|
},
|
||||||
|
|
|
@ -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(
|
ast::FunctionDecorationList{});
|
||||||
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, &void_type,
|
|
||||||
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
|
|
||||||
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{
|
||||||
|
create<ast::ReturnStatement>(Source{}),
|
||||||
|
},
|
||||||
|
ast::FunctionDecorationList{});
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>(
|
ASSERT_TRUE(b.GenerateFunction(func));
|
||||||
Source{}, ast::StatementList{
|
|
||||||
create<ast::ReturnStatement>(Source{}),
|
|
||||||
});
|
|
||||||
ast::Function func(Source{}, mod->RegisterSymbol("a_func"), "a_func", {},
|
|
||||||
&void_type, body, ast::FunctionDecorationList{});
|
|
||||||
|
|
||||||
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{
|
||||||
|
create<ast::DiscardStatement>(Source{}),
|
||||||
|
},
|
||||||
|
ast::FunctionDecorationList{});
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>(
|
ASSERT_TRUE(b.GenerateFunction(func));
|
||||||
Source{}, ast::StatementList{
|
|
||||||
create<ast::DiscardStatement>(Source{}),
|
|
||||||
});
|
|
||||||
ast::Function func(Source{}, mod->RegisterSymbol("a_func"), "a_func", {},
|
|
||||||
&void_type, body, ast::FunctionDecorationList{});
|
|
||||||
|
|
||||||
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{
|
||||||
|
create<ast::ReturnStatement>(Source{}),
|
||||||
|
},
|
||||||
|
ast::FunctionDecorationList{});
|
||||||
|
|
||||||
auto* body = create<ast::BlockStatement>(
|
ASSERT_TRUE(b.GenerateFunction(func));
|
||||||
Source{}, ast::StatementList{
|
|
||||||
create<ast::ReturnStatement>(Source{}),
|
|
||||||
});
|
|
||||||
ast::Function func(Source{}, mod->RegisterSymbol("a_func"), "a_func", {},
|
|
||||||
&void_type, body, ast::FunctionDecorationList{});
|
|
||||||
|
|
||||||
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(
|
ast::FunctionDecorationList{});
|
||||||
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, &void_type,
|
|
||||||
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
|
|
||||||
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(
|
ast::FunctionDecorationList{});
|
||||||
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, &void_type,
|
auto* func2 = Func("b_func", {}, ty.void_, ast::StatementList{},
|
||||||
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
|
ast::FunctionDecorationList{});
|
||||||
ast::FunctionDecorationList{});
|
|
||||||
ast::Function func2(
|
|
||||||
Source{}, mod->RegisterSymbol("b_func"), "b_func", {}, &void_type,
|
|
||||||
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
|
|
||||||
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
|
ast::VariableDecorationList{
|
||||||
"data", // name
|
create<ast::BindingDecoration>(Source{}, 0),
|
||||||
ast::StorageClass::kStorageBuffer, // storage_class
|
create<ast::SetDecoration>(Source{}, 0),
|
||||||
&ac, // type
|
});
|
||||||
false, // is_const
|
|
||||||
nullptr, // constructor
|
|
||||||
ast::VariableDecorationList{
|
|
||||||
// decorations
|
|
||||||
create<ast::BindingDecoration>(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{}),
|
||||||
|
|
|
@ -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),
|
||||||
|
ast::VariableDecorationList{});
|
||||||
|
td.RegisterVariableForTesting(v);
|
||||||
|
|
||||||
auto* init = create<ast::ScalarConstructorExpression>(
|
auto* v2 = Var("v2", ast::StorageClass::kFunction, ty.f32, Expr("v"),
|
||||||
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f));
|
ast::VariableDecorationList{});
|
||||||
|
td.RegisterVariableForTesting(v2);
|
||||||
|
|
||||||
ASSERT_TRUE(td.DetermineResultType(init)) << td.error();
|
ASSERT_TRUE(td.DetermineResultType(v->constructor())) << td.error();
|
||||||
|
ASSERT_TRUE(td.DetermineResultType(v2->constructor())) << 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{});
|
|
||||||
td.RegisterVariableForTesting(&v2);
|
|
||||||
|
|
||||||
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),
|
||||||
|
ast::VariableDecorationList{});
|
||||||
|
td.RegisterVariableForTesting(v);
|
||||||
|
|
||||||
auto* init = create<ast::ScalarConstructorExpression>(
|
auto* v2 = Var("v2", ast::StorageClass::kFunction, ty.f32, Expr("v"),
|
||||||
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 1.0f));
|
ast::VariableDecorationList{});
|
||||||
|
td.RegisterVariableForTesting(v2);
|
||||||
|
|
||||||
EXPECT_TRUE(td.DetermineResultType(init)) << td.error();
|
ASSERT_TRUE(td.DetermineResultType(v->constructor())) << td.error();
|
||||||
|
ASSERT_TRUE(td.DetermineResultType(v2->constructor())) << 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{});
|
|
||||||
td.RegisterVariableForTesting(&v2);
|
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -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,18 +187,10 @@ 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 =
|
ast::VariableDecorationList{
|
||||||
create<ast::Variable>(Source{}, // source
|
create<ast::LocationDecoration>(Source{}, 5),
|
||||||
"var", // name
|
});
|
||||||
ast::StorageClass::kOutput, // storage_class
|
|
||||||
&f32, // type
|
|
||||||
false, // is_const
|
|
||||||
nullptr, // constructor
|
|
||||||
ast::VariableDecorationList{
|
|
||||||
// decorations
|
|
||||||
create<ast::LocationDecoration>(Source{}, 5),
|
|
||||||
});
|
|
||||||
|
|
||||||
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"
|
||||||
|
@ -267,19 +205,11 @@ 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 =
|
ast::VariableDecorationList{
|
||||||
create<ast::Variable>(Source{}, // source
|
create<ast::BindingDecoration>(Source{}, 2),
|
||||||
"var", // name
|
create<ast::SetDecoration>(Source{}, 3),
|
||||||
ast::StorageClass::kOutput, // storage_class
|
});
|
||||||
&f32, // type
|
|
||||||
false, // is_const
|
|
||||||
nullptr, // constructor
|
|
||||||
ast::VariableDecorationList{
|
|
||||||
// decorations
|
|
||||||
create<ast::BindingDecoration>(Source{}, 2),
|
|
||||||
create<ast::SetDecoration>(Source{}, 3),
|
|
||||||
});
|
|
||||||
|
|
||||||
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"
|
||||||
|
@ -295,18 +225,11 @@ 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
|
ast::VariableDecorationList{
|
||||||
"var", // name
|
create<ast::BuiltinDecoration>(Source{}, ast::Builtin::kPosition),
|
||||||
ast::StorageClass::kOutput, // storage_class
|
});
|
||||||
&f32, // type
|
|
||||||
false, // is_const
|
|
||||||
nullptr, // constructor
|
|
||||||
ast::VariableDecorationList{
|
|
||||||
// decorations
|
|
||||||
create<ast::BuiltinDecoration>(Source{}, ast::Builtin::kPosition),
|
|
||||||
});
|
|
||||||
|
|
||||||
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"
|
||||||
|
@ -321,21 +244,10 @@ 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),
|
||||||
|
ast::VariableDecorationList{
|
||||||
auto* v = create<ast::Variable>(
|
create<ast::ConstantIdDecoration>(Source{}, 1200),
|
||||||
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{
|
|
||||||
// decorations
|
|
||||||
create<ast::ConstantIdDecoration>(Source{}, 1200),
|
|
||||||
});
|
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "var"
|
||||||
|
@ -350,19 +262,10 @@ 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,
|
||||||
|
ast::VariableDecorationList{
|
||||||
auto* v = create<ast::Variable>(
|
create<ast::ConstantIdDecoration>(Source{}, 1200),
|
||||||
Source{}, // source
|
});
|
||||||
"var", // name
|
|
||||||
ast::StorageClass::kNone, // storage_class
|
|
||||||
&bool_type, // type
|
|
||||||
false, // is_const
|
|
||||||
nullptr, // constructor
|
|
||||||
ast::VariableDecorationList{
|
|
||||||
// decorations
|
|
||||||
create<ast::ConstantIdDecoration>(Source{}, 1200),
|
|
||||||
});
|
|
||||||
|
|
||||||
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"
|
||||||
|
@ -377,21 +280,10 @@ 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),
|
||||||
|
ast::VariableDecorationList{
|
||||||
auto* v = create<ast::Variable>(
|
create<ast::ConstantIdDecoration>(Source{}, 0),
|
||||||
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{
|
|
||||||
// decorations
|
|
||||||
create<ast::ConstantIdDecoration>(Source{}, 0),
|
|
||||||
});
|
|
||||||
|
|
||||||
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
|
||||||
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "var"
|
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "var"
|
||||||
|
@ -406,19 +298,10 @@ 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,
|
||||||
|
ast::VariableDecorationList{
|
||||||
auto* v =
|
create<ast::ConstantIdDecoration>(Source{}, 0),
|
||||||
create<ast::Variable>(Source{}, // source
|
});
|
||||||
"var", // name
|
|
||||||
ast::StorageClass::kNone, // storage_class
|
|
||||||
&f32, // type
|
|
||||||
false, // is_const
|
|
||||||
nullptr, // constructor
|
|
||||||
ast::VariableDecorationList{
|
|
||||||
// decorations
|
|
||||||
create<ast::ConstantIdDecoration>(Source{}, 0),
|
|
||||||
});
|
|
||||||
|
|
||||||
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"
|
||||||
|
@ -433,19 +316,10 @@ 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,
|
||||||
|
ast::VariableDecorationList{
|
||||||
auto* v =
|
create<ast::ConstantIdDecoration>(Source{}, 0),
|
||||||
create<ast::Variable>(Source{}, // source
|
});
|
||||||
"var", // name
|
|
||||||
ast::StorageClass::kNone, // storage_class
|
|
||||||
&i32, // type
|
|
||||||
false, // is_const
|
|
||||||
nullptr, // constructor
|
|
||||||
ast::VariableDecorationList{
|
|
||||||
// decorations
|
|
||||||
create<ast::ConstantIdDecoration>(Source{}, 0),
|
|
||||||
});
|
|
||||||
|
|
||||||
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"
|
||||||
|
@ -460,19 +334,10 @@ 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,
|
||||||
|
ast::VariableDecorationList{
|
||||||
auto* v =
|
create<ast::ConstantIdDecoration>(Source{}, 0),
|
||||||
create<ast::Variable>(Source{}, // source
|
});
|
||||||
"var", // name
|
|
||||||
ast::StorageClass::kNone, // storage_class
|
|
||||||
&u32, // type
|
|
||||||
false, // is_const
|
|
||||||
nullptr, // constructor
|
|
||||||
ast::VariableDecorationList{
|
|
||||||
// decorations
|
|
||||||
create<ast::ConstantIdDecoration>(Source{}, 0),
|
|
||||||
});
|
|
||||||
|
|
||||||
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"
|
||||||
|
@ -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{}));
|
auto* B = ty.alias("B", A);
|
||||||
ast::type::Alias B(mod->RegisterSymbol("B"), "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);
|
||||||
|
EXPECT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
|
||||||
ast::Variable var(Source{}, "b", ast::StorageClass::kStorageBuffer, &ac,
|
|
||||||
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};
|
auto* B = ty.alias("B", &ac);
|
||||||
ast::type::Alias B(mod->RegisterSymbol("B"), "B", &ac);
|
auto* var = Var("b", ast::StorageClass::kStorageBuffer, B);
|
||||||
|
EXPECT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
|
||||||
ast::Variable var(Source{}, "b", ast::StorageClass::kStorageBuffer, &B, 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
|
||||||
)");
|
)");
|
||||||
|
@ -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
|
||||||
)");
|
)");
|
||||||
|
|
|
@ -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
|
||||||
)");
|
)");
|
||||||
|
|
|
@ -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{});
|
||||||
|
|
||||||
|
|
|
@ -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")), {});
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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,
|
ast::FunctionDecorationList{});
|
||||||
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
|
|
||||||
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,
|
ast::FunctionDecorationList{});
|
||||||
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
|
|
||||||
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,
|
ast::FunctionDecorationList{});
|
||||||
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
|
|
||||||
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,
|
ast::FunctionDecorationList{});
|
||||||
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
|
|
||||||
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,
|
ast::FunctionDecorationList{});
|
||||||
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
|
|
||||||
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,
|
ast::FunctionDecorationList{});
|
||||||
create<ast::BlockStatement>(Source{}, ast::StatementList{}),
|
|
||||||
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();
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue