Start cleaning up tests (1/N)

Remove Source{} with ast::Builder::create<>
Use Builder helpers where possible

Change-Id: Ie404f3a963ed8c40e056590ebb4ae36f67a92753
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/35505
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton 2020-12-14 22:08:27 +00:00 committed by Commit Bot service account
parent f4daa505ec
commit 7eaf4b57ae
10 changed files with 1230 additions and 3944 deletions

View File

@ -26,6 +26,7 @@
#include "src/ast/expression.h" #include "src/ast/expression.h"
#include "src/ast/float_literal.h" #include "src/ast/float_literal.h"
#include "src/ast/identifier_expression.h" #include "src/ast/identifier_expression.h"
#include "src/ast/member_accessor_expression.h"
#include "src/ast/module.h" #include "src/ast/module.h"
#include "src/ast/scalar_constructor_expression.h" #include "src/ast/scalar_constructor_expression.h"
#include "src/ast/sint_literal.h" #include "src/ast/sint_literal.h"
@ -259,7 +260,7 @@ class Builder {
Append(list, std::forward<ARGS>(args)...); Append(list, std::forward<ARGS>(args)...);
} }
/// @return an empty list of expressions, /// @return an empty list of expressions
ExpressionList ExprList() { return {}; } ExpressionList ExprList() { return {}; }
/// @param args the list of expressions /// @param args the list of expressions
@ -273,6 +274,10 @@ class Builder {
return list; return list;
} }
/// @param list the list of expressions
/// @return `list`
ExpressionList ExprList(ExpressionList list) { return list; }
/// @param val the boolan value /// @param val the boolan value
/// @return a boolean literal with the given value /// @return a boolean literal with the given value
BoolLiteral* Literal(bool val) { return create<BoolLiteral>(ty.bool_, val); } BoolLiteral* Literal(bool val) { return create<BoolLiteral>(ty.bool_, val); }
@ -471,8 +476,8 @@ class Builder {
/// @param args the function call arguments /// @param args the function call arguments
/// @returns a `CallExpression` to the function `func`, with the /// @returns a `CallExpression` to the function `func`, with the
/// arguments of `args` converted to `Expression`s using `Expr()`. /// arguments of `args` converted to `Expression`s using `Expr()`.
template <typename... ARGS> template <typename NAME, typename... ARGS>
CallExpression* Call(const std::string& func, ARGS&&... args) { CallExpression* Call(NAME&& func, ARGS&&... args) {
return create<CallExpression>(Expr(func), return create<CallExpression>(Expr(func),
ExprList(std::forward<ARGS>(args)...)); ExprList(std::forward<ARGS>(args)...));
} }
@ -482,7 +487,7 @@ class Builder {
/// @returns a `BinaryExpression` summing the arguments `lhs` and `rhs` /// @returns a `BinaryExpression` summing the arguments `lhs` and `rhs`
template <typename LHS, typename RHS> template <typename LHS, typename RHS>
Expression* Add(LHS&& lhs, RHS&& rhs) { Expression* Add(LHS&& lhs, RHS&& rhs) {
return create<BinaryExpression>(ast::BinaryOp::kAdd, return create<BinaryExpression>(BinaryOp::kAdd,
Expr(std::forward<LHS>(lhs)), Expr(std::forward<LHS>(lhs)),
Expr(std::forward<RHS>(rhs))); Expr(std::forward<RHS>(rhs)));
} }
@ -492,7 +497,17 @@ class Builder {
/// @returns a `BinaryExpression` subtracting `rhs` from `lhs` /// @returns a `BinaryExpression` subtracting `rhs` from `lhs`
template <typename LHS, typename RHS> template <typename LHS, typename RHS>
Expression* Sub(LHS&& lhs, RHS&& rhs) { Expression* Sub(LHS&& lhs, RHS&& rhs) {
return create<BinaryExpression>(ast::BinaryOp::kSubtract, return create<BinaryExpression>(BinaryOp::kSubtract,
Expr(std::forward<LHS>(lhs)),
Expr(std::forward<RHS>(rhs)));
}
/// @param lhs the left hand argument to the multiplication operation
/// @param rhs the right hand argument to the multiplication operation
/// @returns a `BinaryExpression` multiplying `rhs` from `lhs`
template <typename LHS, typename RHS>
Expression* Mul(LHS&& lhs, RHS&& rhs) {
return create<BinaryExpression>(BinaryOp::kMultiply,
Expr(std::forward<LHS>(lhs)), Expr(std::forward<LHS>(lhs)),
Expr(std::forward<RHS>(rhs))); Expr(std::forward<RHS>(rhs)));
} }
@ -506,35 +521,43 @@ class Builder {
Source{}, Expr(std::forward<ARR>(arr)), Expr(std::forward<IDX>(idx))); Source{}, Expr(std::forward<ARR>(arr)), Expr(std::forward<IDX>(idx)));
} }
/// Creates a new ast::Node owned by the Module, with the explicit Source. /// @param obj the object for the member accessor expression
/// @param idx the index argument for the array accessor expression
/// @returns a `MemberAccessorExpression` that indexes `obj` with `idx`
template <typename OBJ, typename IDX>
Expression* Member(OBJ&& obj, IDX&& idx) {
return create<MemberAccessorExpression>(
Source{}, Expr(std::forward<OBJ>(obj)), Expr(std::forward<IDX>(idx)));
}
/// Creates a new Node owned by the Module, with the explicit Source.
/// When the Module is destructed, the `Node` will also be destructed. /// When the Module is destructed, the `Node` will also be destructed.
/// @param source the source to apply to the Node /// @param source the source to apply to the Node
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
ast::traits::EnableIfIsType<T, ast::Node>* create(const Source& source, traits::EnableIfIsType<T, Node>* create(const Source& source,
ARGS&&... args) { ARGS&&... args) {
return mod->create<T>(source, std::forward<ARGS>(args)...); return mod->create<T>(source, std::forward<ARGS>(args)...);
} }
/// Creates a new ast::Node owned by the Module, with the explicit Source. /// Creates a new Node owned by the Module, with the explicit Source.
/// When the Module is destructed, the `Node` will also be destructed. /// When the Module is destructed, the `Node` will also be destructed.
/// @param source the source to apply to the Node /// @param source the source to apply to the Node
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
ast::traits::EnableIfIsType<T, ast::Node>* create(Source&& source, traits::EnableIfIsType<T, Node>* create(Source&& source, ARGS&&... args) {
ARGS&&... args) {
return mod->create<T>(std::move(source), std::forward<ARGS>(args)...); return mod->create<T>(std::move(source), std::forward<ARGS>(args)...);
} }
/// Creates a new ast::type::Type owned by the Module, using the Builder's /// Creates a new type::Type owned by the Module, using the Builder's
/// current Source. When the Module is destructed, the `Node` will also be /// current Source. When the Module is destructed, the `Node` will also be
/// destructed. /// destructed.
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the node pointer /// @returns the node pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
ast::traits::EnableIfIsType<T, ast::Node>* create(ARGS&&... args) { traits::EnableIfIsType<T, Node>* create(ARGS&&... args) {
return mod->create<T>(source_, std::forward<ARGS>(args)...); return mod->create<T>(source_, std::forward<ARGS>(args)...);
} }
@ -550,12 +573,20 @@ class Builder {
/// @param args the arguments to pass to the type constructor /// @param args the arguments to pass to the type constructor
/// @returns the de-aliased type pointer /// @returns the de-aliased type pointer
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
traits::EnableIfIsType<T, ast::type::Type>* create(ARGS&&... args) { traits::EnableIfIsType<T, type::Type>* create(ARGS&&... args) {
static_assert(std::is_base_of<type::Type, T>::value, static_assert(std::is_base_of<type::Type, T>::value,
"T does not derive from type::Type"); "T does not derive from type::Type");
return mod->create<T>(std::forward<ARGS>(args)...); return mod->create<T>(std::forward<ARGS>(args)...);
} }
/// Sets the current builder source to `src`
/// @param src the Source used for future create() calls
void SetSource(const Source& src) { source_ = src; }
/// Sets the current builder source to `loc`
/// @param loc the Source used for future create() calls
void SetSource(const Source::Location& loc) { source_ = Source(loc); }
/// The builder module /// The builder module
Module* const mod; Module* const mod;
/// The builder types /// The builder types

View File

@ -93,17 +93,17 @@ class BoundArrayAccessorsTest : public testing::Test {
struct ModuleBuilder : public ast::BuilderWithModule { struct ModuleBuilder : public ast::BuilderWithModule {
ast::Module Module() { ast::Module Module() {
Build(); Build();
auto* body = create<ast::BlockStatement>(Source{}, statements); auto* body = create<ast::BlockStatement>(statements);
mod->AddFunction(create<ast::Function>( mod->AddFunction(create<ast::Function>(mod->RegisterSymbol("func"), "func",
Source{}, mod->RegisterSymbol("func"), "func", ast::VariableList{}, ast::VariableList{}, ty.void_, body,
ty.void_, body, ast::FunctionDecorationList{})); ast::FunctionDecorationList{}));
return std::move(*mod); return std::move(*mod);
} }
protected: protected:
virtual void Build() = 0; virtual void Build() = 0;
void OnVariableBuilt(ast::Variable* var) override { void OnVariableBuilt(ast::Variable* var) override {
statements.emplace_back(create<ast::VariableDeclStatement>(Source{}, var)); statements.emplace_back(create<ast::VariableDeclStatement>(var));
} }
ast::StatementList statements; ast::StatementList statements;
}; };

View File

@ -53,33 +53,30 @@ struct ModuleBuilder : public ast::BuilderWithModule {
TEST_F(EmitVertexPointSizeTest, VertexStageBasic) { TEST_F(EmitVertexPointSizeTest, VertexStageBasic) {
struct Builder : ModuleBuilder { struct Builder : ModuleBuilder {
void Build() override { void Build() override {
auto* block = create<ast::BlockStatement>( auto* block = create<ast::BlockStatement>(ast::StatementList{
Source{}, create<ast::VariableDeclStatement>(
ast::StatementList{ Var("builtin_assignments_should_happen_before_this",
create<ast::VariableDeclStatement>( tint::ast::StorageClass::kFunction, ty.f32)),
Source{}, Var("builtin_assignments_should_happen_before_this", });
tint::ast::StorageClass::kFunction, ty.f32)),
});
auto a_sym = mod->RegisterSymbol("non_entry_a"); auto a_sym = mod->RegisterSymbol("non_entry_a");
mod->AddFunction(create<ast::Function>( mod->AddFunction(create<ast::Function>(
Source{}, a_sym, "non_entry_a", ast::VariableList{}, ty.void_, a_sym, "non_entry_a", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{})); ast::FunctionDecorationList{}));
auto entry_sym = mod->RegisterSymbol("entry"); auto entry_sym = mod->RegisterSymbol("entry");
auto* entry = create<ast::Function>( auto* entry = create<ast::Function>(
Source{}, entry_sym, "entry", ast::VariableList{}, ty.void_, block, entry_sym, "entry", ast::VariableList{}, ty.void_, block,
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, create<ast::StageDecoration>(ast::PipelineStage::kVertex),
ast::PipelineStage::kVertex),
}); });
mod->AddFunction(entry); mod->AddFunction(entry);
auto b_sym = mod->RegisterSymbol("non_entry_b"); auto b_sym = mod->RegisterSymbol("non_entry_b");
mod->AddFunction(create<ast::Function>( mod->AddFunction(create<ast::Function>(
Source{}, b_sym, "non_entry_b", ast::VariableList{}, ty.void_, b_sym, "non_entry_b", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{})); ast::FunctionDecorationList{}));
} }
}; };
@ -132,23 +129,22 @@ TEST_F(EmitVertexPointSizeTest, VertexStageEmpty) {
void Build() override { void Build() override {
auto a_sym = mod->RegisterSymbol("non_entry_a"); auto a_sym = mod->RegisterSymbol("non_entry_a");
mod->AddFunction(create<ast::Function>( mod->AddFunction(create<ast::Function>(
Source{}, a_sym, "non_entry_a", ast::VariableList{}, ty.void_, a_sym, "non_entry_a", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{})); ast::FunctionDecorationList{}));
auto entry_sym = mod->RegisterSymbol("entry"); auto entry_sym = mod->RegisterSymbol("entry");
mod->AddFunction(create<ast::Function>( mod->AddFunction(create<ast::Function>(
Source{}, entry_sym, "entry", ast::VariableList{}, ty.void_, entry_sym, "entry", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, create<ast::StageDecoration>(ast::PipelineStage::kVertex),
ast::PipelineStage::kVertex),
})); }));
auto b_sym = mod->RegisterSymbol("non_entry_b"); auto b_sym = mod->RegisterSymbol("non_entry_b");
mod->AddFunction(create<ast::Function>( mod->AddFunction(create<ast::Function>(
Source{}, b_sym, "non_entry_b", ast::VariableList{}, ty.void_, b_sym, "non_entry_b", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{})); ast::FunctionDecorationList{}));
} }
}; };
@ -194,21 +190,19 @@ TEST_F(EmitVertexPointSizeTest, NonVertexStage) {
void Build() override { void Build() override {
auto frag_sym = mod->RegisterSymbol("fragment_entry"); auto frag_sym = mod->RegisterSymbol("fragment_entry");
auto* fragment_entry = create<ast::Function>( auto* fragment_entry = create<ast::Function>(
Source{}, frag_sym, "fragment_entry", ast::VariableList{}, ty.void_, frag_sym, "fragment_entry", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, create<ast::StageDecoration>(ast::PipelineStage::kFragment),
ast::PipelineStage::kFragment),
}); });
mod->AddFunction(fragment_entry); mod->AddFunction(fragment_entry);
auto comp_sym = mod->RegisterSymbol("compute_entry"); auto comp_sym = mod->RegisterSymbol("compute_entry");
auto* compute_entry = create<ast::Function>( auto* compute_entry = create<ast::Function>(
Source{}, comp_sym, "compute_entry", ast::VariableList{}, ty.void_, comp_sym, "compute_entry", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{ ast::FunctionDecorationList{
create<ast::StageDecoration>(Source{}, create<ast::StageDecoration>(ast::PipelineStage::kCompute),
ast::PipelineStage::kCompute),
}); });
mod->AddFunction(compute_entry); mod->AddFunction(compute_entry);
} }

View File

@ -52,17 +52,15 @@ struct ModuleBuilder : public ast::BuilderWithModule {
protected: protected:
void AddBuiltinInput(const std::string& name, ast::Builtin builtin) { void AddBuiltinInput(const std::string& name, ast::Builtin builtin) {
mod->AddGlobalVariable( mod->AddGlobalVariable(Var(name, ast::StorageClass::kInput, ty.u32, nullptr,
Var(name, ast::StorageClass::kInput, ty.u32, nullptr, {create<ast::BuiltinDecoration>(builtin)}));
{create<ast::BuiltinDecoration>(Source{}, builtin)}));
} }
ast::Function* AddFunction(const std::string& name, ast::Function* AddFunction(const std::string& name,
ast::StatementList stmts) { ast::StatementList stmts) {
auto* func = create<ast::Function>( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol(name), name, ast::VariableList{}, ty.u32, mod->RegisterSymbol(name), name, ast::VariableList{}, ty.u32,
create<ast::BlockStatement>(Source{}, stmts), create<ast::BlockStatement>(stmts), ast::FunctionDecorationList{});
ast::FunctionDecorationList{});
mod->AddFunction(func); mod->AddFunction(func);
return func; return func;
} }
@ -77,10 +75,8 @@ TEST_F(FirstIndexOffsetTest, Error_AlreadyTransformed) {
AddFunction( AddFunction(
"test", "test",
{ {
create<ast::ReturnStatement>( create<ast::ReturnStatement>(create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("vert_idx"), "vert_idx")),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("vert_idx"), "vert_idx")),
}); });
} }
}; };
@ -124,10 +120,8 @@ TEST_F(FirstIndexOffsetTest, BasicModuleVertexIndex) {
AddFunction( AddFunction(
"test", "test",
{ {
create<ast::ReturnStatement>( create<ast::ReturnStatement>(create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("vert_idx"), "vert_idx")),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("vert_idx"), "vert_idx")),
}); });
} }
}; };
@ -206,10 +200,8 @@ TEST_F(FirstIndexOffsetTest, BasicModuleInstanceIndex) {
AddFunction( AddFunction(
"test", "test",
{ {
create<ast::ReturnStatement>( create<ast::ReturnStatement>(create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("inst_idx"), "inst_idx")),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("inst_idx"), "inst_idx")),
}); });
} }
}; };
@ -286,7 +278,7 @@ TEST_F(FirstIndexOffsetTest, BasicModuleBothIndex) {
AddBuiltinInput("inst_idx", ast::Builtin::kInstanceIdx); AddBuiltinInput("inst_idx", ast::Builtin::kInstanceIdx);
AddBuiltinInput("vert_idx", ast::Builtin::kVertexIdx); AddBuiltinInput("vert_idx", ast::Builtin::kVertexIdx);
AddFunction("test", { AddFunction("test", {
create<ast::ReturnStatement>(Source{}, Expr(1u)), create<ast::ReturnStatement>(Expr(1u)),
}); });
} }
}; };
@ -365,22 +357,16 @@ TEST_F(FirstIndexOffsetTest, NestedCalls) {
AddFunction( AddFunction(
"func1", "func1",
{ {
create<ast::ReturnStatement>( create<ast::ReturnStatement>(create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("vert_idx"), "vert_idx")),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("vert_idx"), "vert_idx")),
});
AddFunction(
"func2",
{
create<ast::ReturnStatement>(
Source{},
create<ast::CallExpression>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("func1"), "func1"),
ast::ExpressionList{})),
}); });
AddFunction("func2",
{
create<ast::ReturnStatement>(create<ast::CallExpression>(
create<ast::IdentifierExpression>(
mod->RegisterSymbol("func1"), "func1"),
ast::ExpressionList{})),
});
} }
}; };

File diff suppressed because it is too large Load Diff

View File

@ -272,12 +272,13 @@ TEST_P(HlslGeneratorIntrinsicTextureTest, Call) {
param.buildTextureVariable(this); param.buildTextureVariable(this);
param.buildSamplerVariable(this); param.buildSamplerVariable(this);
ast::CallExpression call{Source{}, Expr(param.function), param.args(this)}; auto* call =
create<ast::CallExpression>(Expr(param.function), param.args(this));
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();
ASSERT_TRUE(gen.EmitExpression(pre, out, &call)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(pre, out, call)) << gen.error();
EXPECT_TRUE(pre_result().empty()); EXPECT_TRUE(pre_result().empty());

View File

@ -263,12 +263,13 @@ TEST_P(MslGeneratorIntrinsicTextureTest, Call) {
param.buildTextureVariable(this); param.buildTextureVariable(this);
param.buildSamplerVariable(this); param.buildSamplerVariable(this);
ast::CallExpression call{Source{}, Expr(param.function), param.args(this)}; auto* call =
create<ast::CallExpression>(Expr(param.function), param.args(this));
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();
ASSERT_TRUE(gen.EmitExpression(&call)) << gen.error(); ASSERT_TRUE(gen.EmitExpression(call)) << gen.error();
auto expected = expected_texture_overload(param.overload); auto expected = expected_texture_overload(param.overload);
EXPECT_EQ(gen.result(), expected); EXPECT_EQ(gen.result(), expected);

View File

@ -46,30 +46,23 @@ namespace {
using BuilderTest = TestHelper; using BuilderTest = TestHelper;
TEST_F(BuilderTest, ArrayAccessor) { TEST_F(BuilderTest, ArrayAccessor) {
ast::type::I32 i32;
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
// vec3<f32> ary; // vec3<f32> ary;
// ary[1] -> ptr<f32> // ary[1] -> ptr<f32>
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3, false, auto* var = Var("ary", ast::StorageClass::kFunction, ty.vec3<f32>());
nullptr, ast::VariableDecorationList{});
auto* ary = create<ast::IdentifierExpression>( auto* ary = Expr("ary");
Source{}, mod->RegisterSymbol("ary"), "ary"); auto* idx_expr = Expr(1);
auto* idx_expr = create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1));
ast::ArrayAccessorExpression expr(Source{}, ary, idx_expr); auto* expr = Index(ary, idx_expr);
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 9u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3 %3 = OpTypeVector %4 3
@ -88,35 +81,27 @@ TEST_F(BuilderTest, ArrayAccessor) {
} }
TEST_F(BuilderTest, Accessor_Array_LoadIndex) { TEST_F(BuilderTest, Accessor_Array_LoadIndex) {
ast::type::I32 i32;
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
// ary : vec3<f32>; // ary : vec3<f32>;
// idx : i32; // idx : i32;
// ary[idx] -> ptr<f32> // ary[idx] -> ptr<f32>
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3, false, auto* var = Var("ary", ast::StorageClass::kFunction, ty.vec3<f32>());
nullptr, ast::VariableDecorationList{}); auto* idx = Var("idx", ast::StorageClass::kFunction, ty.i32);
ast::Variable idx(Source{}, "idx", ast::StorageClass::kFunction, &i32, false,
nullptr, ast::VariableDecorationList{});
auto* ary = create<ast::IdentifierExpression>( auto* ary = Expr("ary");
Source{}, mod->RegisterSymbol("ary"), "ary"); auto* idx_expr = Expr("idx");
auto* idx_expr = create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("idx"), "idx");
ast::ArrayAccessorExpression expr(Source{}, ary, idx_expr); auto* expr = Index(ary, idx_expr);
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
td.RegisterVariableForTesting(&idx); td.RegisterVariableForTesting(idx);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
ASSERT_TRUE(b.GenerateFunctionVariable(&idx)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(idx)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 12u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 12u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3 %3 = OpTypeVector %4 3
@ -138,35 +123,22 @@ TEST_F(BuilderTest, Accessor_Array_LoadIndex) {
} }
TEST_F(BuilderTest, ArrayAccessor_Dynamic) { TEST_F(BuilderTest, ArrayAccessor_Dynamic) {
ast::type::I32 i32;
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
// vec3<f32> ary; // vec3<f32> ary;
// ary[1 + 2] -> ptr<f32> // ary[1 + 2] -> ptr<f32>
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &vec3, false, auto* var = Var("ary", ast::StorageClass::kFunction, ty.vec3<f32>());
nullptr, ast::VariableDecorationList{});
auto* ary = create<ast::IdentifierExpression>( auto* ary = Expr("ary");
Source{}, mod->RegisterSymbol("ary"), "ary");
ast::ArrayAccessorExpression expr( auto* expr = Index(ary, Add(1, 2));
Source{}, ary,
create<ast::BinaryExpression>(
Source{}, ast::BinaryOp::kAdd,
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2))));
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 11u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 11u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3 %3 = OpTypeVector %4 3
@ -187,35 +159,22 @@ TEST_F(BuilderTest, ArrayAccessor_Dynamic) {
} }
TEST_F(BuilderTest, ArrayAccessor_MultiLevel) { TEST_F(BuilderTest, ArrayAccessor_MultiLevel) {
ast::type::I32 i32; ast::type::Array ary4(ty.vec3<f32>(), 4, ast::ArrayDecorationList{});
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
ast::type::Array ary4(&vec3, 4, ast::ArrayDecorationList{});
// ary = array<vec3<f32>, 4> // ary = array<vec3<f32>, 4>
// ary[3][2]; // ary[3][2];
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &ary4, false, auto* var = Var("ary", ast::StorageClass::kFunction, &ary4);
nullptr, ast::VariableDecorationList{});
ast::ArrayAccessorExpression expr( auto* expr = Index(Index("ary", 3), 2);
Source{},
create<ast::ArrayAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("ary"), "ary"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 3))),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2)));
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 13u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 13u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
%4 = OpTypeVector %5 3 %4 = OpTypeVector %5 3
@ -238,34 +197,21 @@ TEST_F(BuilderTest, ArrayAccessor_MultiLevel) {
} }
TEST_F(BuilderTest, Accessor_ArrayWithSwizzle) { TEST_F(BuilderTest, Accessor_ArrayWithSwizzle) {
ast::type::I32 i32; ast::type::Array ary4(ty.vec3<f32>(), 4, ast::ArrayDecorationList{});
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
ast::type::Array ary4(&vec3, 4, ast::ArrayDecorationList{});
// var a : array<vec3<f32>, 4>; // var a : array<vec3<f32>, 4>;
// a[2].xy; // a[2].xy;
ast::Variable var(Source{}, "ary", ast::StorageClass::kFunction, &ary4, false, auto* var = Var("ary", ast::StorageClass::kFunction, &ary4);
nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( auto* expr = Member(Index("ary", 2), "xy");
Source{},
create<ast::ArrayAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("ary"), "ary"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2))),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("xy"),
"xy"));
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 15u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 15u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
%4 = OpTypeVector %5 3 %4 = OpTypeVector %5 3
@ -290,8 +236,6 @@ TEST_F(BuilderTest, Accessor_ArrayWithSwizzle) {
} }
TEST_F(BuilderTest, MemberAccessor) { TEST_F(BuilderTest, MemberAccessor) {
ast::type::F32 f32;
// my_struct { // my_struct {
// a : f32 // a : f32
// b : f32 // b : f32
@ -301,29 +245,23 @@ TEST_F(BuilderTest, MemberAccessor) {
ast::StructMemberDecorationList decos; ast::StructMemberDecorationList decos;
ast::StructMemberList members; ast::StructMemberList members;
members.push_back(create<ast::StructMember>(Source{}, "a", &f32, decos)); members.push_back(create<ast::StructMember>("a", ty.f32, decos));
members.push_back(create<ast::StructMember>(Source{}, "b", &f32, decos)); members.push_back(create<ast::StructMember>("b", ty.f32, decos));
auto* s = create<ast::Struct>(Source{}, members, ast::StructDecorationList{}); auto* s = create<ast::Struct>(members, ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s);
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type, auto* var = Var("ident", ast::StorageClass::kFunction, &s_type);
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( auto* expr = Member("ident", "b");
Source{},
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("ident"),
"ident"),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("b"),
"b"));
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 9u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeStruct %4 %4 %3 = OpTypeStruct %4 %4
@ -342,8 +280,6 @@ TEST_F(BuilderTest, MemberAccessor) {
} }
TEST_F(BuilderTest, MemberAccessor_Nested) { TEST_F(BuilderTest, MemberAccessor_Nested) {
ast::type::F32 f32;
// inner_struct { // inner_struct {
// a : f32 // a : f32
// } // }
@ -355,45 +291,32 @@ TEST_F(BuilderTest, MemberAccessor_Nested) {
// ident.inner.a // ident.inner.a
ast::StructMemberDecorationList decos; ast::StructMemberDecorationList decos;
ast::StructMemberList inner_members; ast::StructMemberList inner_members;
inner_members.push_back( inner_members.push_back(create<ast::StructMember>("a", ty.f32, decos));
create<ast::StructMember>(Source{}, "a", &f32, decos)); inner_members.push_back(create<ast::StructMember>("b", ty.f32, decos));
inner_members.push_back(
create<ast::StructMember>(Source{}, "b", &f32, decos));
ast::type::Struct inner_struct( ast::type::Struct inner_struct(
mod->RegisterSymbol("Inner"), "Inner", mod->RegisterSymbol("Inner"), "Inner",
create<ast::Struct>(Source{}, inner_members, create<ast::Struct>(inner_members, ast::StructDecorationList{}));
ast::StructDecorationList{}));
ast::StructMemberList outer_members; ast::StructMemberList outer_members;
outer_members.push_back( outer_members.push_back(
create<ast::StructMember>(Source{}, "inner", &inner_struct, decos)); create<ast::StructMember>("inner", &inner_struct, decos));
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", ast::type::Struct s_type(
create<ast::Struct>(Source{}, outer_members, mod->RegisterSymbol("my_struct"), "my_struct",
ast::StructDecorationList{})); create<ast::Struct>(outer_members, ast::StructDecorationList{}));
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type, auto* var = Var("ident", ast::StorageClass::kFunction, &s_type);
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( auto* expr = Member(Member("ident", "inner"), "a");
Source{},
create<ast::MemberAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("ident"), "ident"),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("inner"), "inner")),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("a"),
"a"));
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 10u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
%4 = OpTypeStruct %5 %5 %4 = OpTypeStruct %5 %5
@ -413,8 +336,6 @@ TEST_F(BuilderTest, MemberAccessor_Nested) {
} }
TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) { TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) {
ast::type::F32 f32;
// type Inner = struct { // type Inner = struct {
// a : f32 // a : f32
// b : f32 // b : f32
@ -427,47 +348,33 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) {
// ident.inner.a // ident.inner.a
ast::StructMemberDecorationList decos; ast::StructMemberDecorationList decos;
ast::StructMemberList inner_members; ast::StructMemberList inner_members;
inner_members.push_back( inner_members.push_back(create<ast::StructMember>("a", ty.f32, decos));
create<ast::StructMember>(Source{}, "a", &f32, decos)); inner_members.push_back(create<ast::StructMember>("b", ty.f32, decos));
inner_members.push_back(
create<ast::StructMember>(Source{}, "b", &f32, decos));
ast::type::Struct inner_struct( ast::type::Struct inner_struct(
mod->RegisterSymbol("Inner"), "Inner", mod->RegisterSymbol("Inner"), "Inner",
create<ast::Struct>(Source{}, inner_members, create<ast::Struct>(inner_members, ast::StructDecorationList{}));
ast::StructDecorationList{}));
ast::type::Alias alias(mod->RegisterSymbol("Inner"), "Inner", &inner_struct); ast::type::Alias alias(mod->RegisterSymbol("Inner"), "Inner", &inner_struct);
ast::StructMemberList outer_members; ast::StructMemberList outer_members;
outer_members.push_back( outer_members.push_back(create<ast::StructMember>("inner", &alias, decos));
create<ast::StructMember>(Source{}, "inner", &alias, decos));
ast::type::Struct s_type(mod->RegisterSymbol("Outer"), "Outer", ast::type::Struct s_type(
create<ast::Struct>(Source{}, outer_members, mod->RegisterSymbol("Outer"), "Outer",
ast::StructDecorationList{})); create<ast::Struct>(outer_members, ast::StructDecorationList{}));
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type, auto* var = Var("ident", ast::StorageClass::kFunction, &s_type);
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( auto* expr = Member(Member("ident", "inner"), "a");
Source{},
create<ast::MemberAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("ident"), "ident"),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("inner"), "inner")),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("a"),
"a"));
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 10u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
%4 = OpTypeStruct %5 %5 %4 = OpTypeStruct %5 %5
@ -487,8 +394,6 @@ TEST_F(BuilderTest, MemberAccessor_Nested_WithAlias) {
} }
TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_LHS) { TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_LHS) {
ast::type::F32 f32;
// inner_struct { // inner_struct {
// a : f32 // a : f32
// } // }
@ -501,50 +406,36 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_LHS) {
ast::StructMemberDecorationList decos; ast::StructMemberDecorationList decos;
ast::StructMemberList inner_members; ast::StructMemberList inner_members;
inner_members.push_back( inner_members.push_back(create<ast::StructMember>("a", ty.f32, decos));
create<ast::StructMember>(Source{}, "a", &f32, decos)); inner_members.push_back(create<ast::StructMember>("b", ty.f32, decos));
inner_members.push_back(
create<ast::StructMember>(Source{}, "b", &f32, decos));
ast::type::Struct inner_struct( ast::type::Struct inner_struct(
mod->RegisterSymbol("Inner"), "Inner", mod->RegisterSymbol("Inner"), "Inner",
create<ast::Struct>(Source{}, inner_members, create<ast::Struct>(inner_members, ast::StructDecorationList{}));
ast::StructDecorationList{}));
ast::StructMemberList outer_members; ast::StructMemberList outer_members;
outer_members.push_back( outer_members.push_back(
create<ast::StructMember>(Source{}, "inner", &inner_struct, decos)); create<ast::StructMember>("inner", &inner_struct, decos));
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", ast::type::Struct s_type(
create<ast::Struct>(Source{}, outer_members, mod->RegisterSymbol("my_struct"), "my_struct",
ast::StructDecorationList{})); create<ast::Struct>(outer_members, ast::StructDecorationList{}));
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type, auto* var = Var("ident", ast::StorageClass::kFunction, &s_type);
false, nullptr, ast::VariableDecorationList{});
auto* lhs = create<ast::MemberAccessorExpression>( auto* lhs = Member(Member("ident", "inner"), "a");
Source{},
create<ast::MemberAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("ident"), "ident"),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("inner"), "inner")),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("a"),
"a"));
auto* rhs = create<ast::ScalarConstructorExpression>( auto* rhs = Expr(2.0f);
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 2.f));
ast::AssignmentStatement expr(Source{}, lhs, rhs); 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();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_TRUE(b.GenerateAssignStatement(&expr)) << b.error(); EXPECT_TRUE(b.GenerateAssignStatement(expr)) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
%4 = OpTypeStruct %5 %5 %4 = OpTypeStruct %5 %5
@ -566,8 +457,6 @@ OpStore %10 %11
} }
TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_RHS) { TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_RHS) {
ast::type::F32 f32;
// inner_struct { // inner_struct {
// a : f32 // a : f32
// } // }
@ -580,54 +469,38 @@ TEST_F(BuilderTest, MemberAccessor_Nested_Assignment_RHS) {
ast::StructMemberDecorationList decos; ast::StructMemberDecorationList decos;
ast::StructMemberList inner_members; ast::StructMemberList inner_members;
inner_members.push_back( inner_members.push_back(create<ast::StructMember>("a", ty.f32, decos));
create<ast::StructMember>(Source{}, "a", &f32, decos)); inner_members.push_back(create<ast::StructMember>("b", ty.f32, decos));
inner_members.push_back(
create<ast::StructMember>(Source{}, "b", &f32, decos));
ast::type::Struct inner_struct( ast::type::Struct inner_struct(
mod->RegisterSymbol("Inner"), "Inner", mod->RegisterSymbol("Inner"), "Inner",
create<ast::Struct>(Source{}, inner_members, create<ast::Struct>(inner_members, ast::StructDecorationList{}));
ast::StructDecorationList{}));
ast::StructMemberList outer_members; ast::StructMemberList outer_members;
outer_members.push_back( outer_members.push_back(
create<ast::StructMember>(Source{}, "inner", &inner_struct, decos)); create<ast::StructMember>("inner", &inner_struct, decos));
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", ast::type::Struct s_type(
create<ast::Struct>(Source{}, outer_members, mod->RegisterSymbol("my_struct"), "my_struct",
ast::StructDecorationList{})); create<ast::Struct>(outer_members, ast::StructDecorationList{}));
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &s_type, auto* var = Var("ident", ast::StorageClass::kFunction, &s_type);
false, nullptr, ast::VariableDecorationList{}); auto* store = Var("store", ast::StorageClass::kFunction, ty.f32);
ast::Variable store(Source{}, "store", ast::StorageClass::kFunction, &f32,
false, nullptr, ast::VariableDecorationList{});
auto* lhs = create<ast::IdentifierExpression>( auto* lhs = Expr("store");
Source{}, mod->RegisterSymbol("store"), "store"); auto* rhs = Member(Member("ident", "inner"), "a");
auto* rhs = create<ast::MemberAccessorExpression>( auto* expr = create<ast::AssignmentStatement>(lhs, rhs);
Source{},
create<ast::MemberAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("ident"), "ident"),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("inner"), "inner")),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("a"),
"a"));
ast::AssignmentStatement expr(Source{}, lhs, rhs); td.RegisterVariableForTesting(var);
td.RegisterVariableForTesting(store);
td.RegisterVariableForTesting(&var); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
td.RegisterVariableForTesting(&store);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
ASSERT_TRUE(b.GenerateFunctionVariable(&store)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(store)) << b.error();
EXPECT_TRUE(b.GenerateAssignStatement(&expr)) << b.error(); EXPECT_TRUE(b.GenerateAssignStatement(expr)) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
%4 = OpTypeStruct %5 %5 %4 = OpTypeStruct %5 %5
@ -651,28 +524,19 @@ OpStore %7 %13
} }
TEST_F(BuilderTest, MemberAccessor_Swizzle_Single) { TEST_F(BuilderTest, MemberAccessor_Swizzle_Single) {
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
// ident.y // ident.y
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3, auto* var = Var("ident", ast::StorageClass::kFunction, ty.vec3<f32>());
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( auto* expr = Member("ident", "y");
Source{},
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("ident"),
"ident"),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("y"),
"y"));
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 9u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3 %3 = OpTypeVector %4 3
@ -691,28 +555,19 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_Single) {
} }
TEST_F(BuilderTest, MemberAccessor_Swizzle_MultipleNames) { TEST_F(BuilderTest, MemberAccessor_Swizzle_MultipleNames) {
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
// ident.yx // ident.yx
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3, auto* var = Var("ident", ast::StorageClass::kFunction, ty.vec3<f32>());
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( auto* expr = Member("ident", "yx");
Source{},
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("ident"),
"ident"),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("yx"),
"yx"));
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 8u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3 %3 = OpTypeVector %4 3
@ -730,32 +585,19 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_MultipleNames) {
} }
TEST_F(BuilderTest, MemberAccessor_Swizzle_of_Swizzle) { TEST_F(BuilderTest, MemberAccessor_Swizzle_of_Swizzle) {
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
// ident.yxz.xz // ident.yxz.xz
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3, auto* var = Var("ident", ast::StorageClass::kFunction, ty.vec3<f32>());
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( auto* expr = Member(Member("ident", "yxz"), "xz");
Source{},
create<ast::MemberAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("ident"), "ident"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("yxz"), "yxz")),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("xz"),
"xz"));
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 9u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 9u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3 %3 = OpTypeVector %4 3
@ -774,32 +616,19 @@ TEST_F(BuilderTest, MemberAccessor_Swizzle_of_Swizzle) {
} }
TEST_F(BuilderTest, MemberAccessor_Member_of_Swizzle) { TEST_F(BuilderTest, MemberAccessor_Member_of_Swizzle) {
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
// ident.yxz.x // ident.yxz.x
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3, auto* var = Var("ident", ast::StorageClass::kFunction, ty.vec3<f32>());
false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( auto* expr = Member(Member("ident", "yxz"), "x");
Source{},
create<ast::MemberAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("ident"), "ident"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("yxz"), "yxz")),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("x"),
"x"));
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 8u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3 %3 = OpTypeVector %4 3
@ -817,33 +646,19 @@ TEST_F(BuilderTest, MemberAccessor_Member_of_Swizzle) {
} }
TEST_F(BuilderTest, MemberAccessor_Array_of_Swizzle) { TEST_F(BuilderTest, MemberAccessor_Array_of_Swizzle) {
ast::type::I32 i32;
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
// index.yxz[1] // index.yxz[1]
ast::Variable var(Source{}, "ident", ast::StorageClass::kFunction, &vec3, auto* var = Var("ident", ast::StorageClass::kFunction, ty.vec3<f32>());
false, nullptr, ast::VariableDecorationList{});
ast::ArrayAccessorExpression expr( auto* expr = Index(Member("ident", "yxz"), 1);
Source{},
create<ast::MemberAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("ident"), "ident"),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("yxz"), "yxz")),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 1)));
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 10u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 10u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3 %3 = OpTypeVector %4 3
@ -863,10 +678,6 @@ TEST_F(BuilderTest, MemberAccessor_Array_of_Swizzle) {
} }
TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) { TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) {
ast::type::I32 i32;
ast::type::F32 f32;
ast::type::Vector vec3(&f32, 3);
// type C = struct { // type C = struct {
// baz : vec3<f32> // baz : vec3<f32>
// } // }
@ -881,66 +692,38 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) {
ast::StructMemberDecorationList decos; ast::StructMemberDecorationList decos;
auto* s = create<ast::Struct>(Source{}, auto* s = create<ast::Struct>(ast::StructMemberList{create<ast::StructMember>(
ast::StructMemberList{create<ast::StructMember>( "baz", ty.vec3<f32>(), decos)},
Source{}, "baz", &vec3, decos)},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct c_type(mod->RegisterSymbol("C"), "C", s); ast::type::Struct c_type(mod->RegisterSymbol("C"), "C", s);
s = create<ast::Struct>(Source{}, s = create<ast::Struct>(
ast::StructMemberList{create<ast::StructMember>( ast::StructMemberList{create<ast::StructMember>("bar", &c_type, decos)},
Source{}, "bar", &c_type, decos)}, ast::StructDecorationList{});
ast::StructDecorationList{});
ast::type::Struct b_type(mod->RegisterSymbol("B"), "B", s); ast::type::Struct b_type(mod->RegisterSymbol("B"), "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>(Source{}, s = create<ast::Struct>(ast::StructMemberList{create<ast::StructMember>(
ast::StructMemberList{create<ast::StructMember>( "foo", &b_ary_type, decos)},
Source{}, "foo", &b_ary_type, decos)},
ast::StructDecorationList{}); ast::StructDecorationList{});
ast::type::Struct a_type(mod->RegisterSymbol("A"), "A", s); ast::type::Struct a_type(mod->RegisterSymbol("A"), "A", s);
ast::type::Array a_ary_type(&a_type, 2, ast::ArrayDecorationList{}); ast::type::Array a_ary_type(&a_type, 2, ast::ArrayDecorationList{});
ast::Variable var(Source{}, "index", ast::StorageClass::kFunction, auto* var = Var("index", ast::StorageClass::kFunction, &a_ary_type);
&a_ary_type, false, nullptr, ast::VariableDecorationList{});
ast::MemberAccessorExpression expr( auto* expr = Member(
Source{}, Member(Member(Index(Member(Index("index", 0), "foo"), 2), "bar"), "baz"),
create<ast::MemberAccessorExpression>( "yx");
Source{},
create<ast::MemberAccessorExpression>(
Source{},
create<ast::ArrayAccessorExpression>(
Source{},
create<ast::MemberAccessorExpression>(
Source{},
create<ast::ArrayAccessorExpression>(
Source{},
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("index"), "index"),
create<ast::ScalarConstructorExpression>(
Source{},
create<ast::SintLiteral>(Source{}, &i32, 0))),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("foo"), "foo")),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::SintLiteral>(Source{}, &i32, 2))),
create<ast::IdentifierExpression>(
Source{}, mod->RegisterSymbol("bar"), "bar")),
create<ast::IdentifierExpression>(Source{},
mod->RegisterSymbol("baz"), "baz")),
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("yx"),
"yx"));
td.RegisterVariableForTesting(&var); td.RegisterVariableForTesting(var);
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 22u); EXPECT_EQ(b.GenerateAccessorExpression(expr), 22u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%9 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%9 = OpTypeFloat 32
%8 = OpTypeVector %9 3 %8 = OpTypeVector %9 3
@ -978,58 +761,23 @@ TEST_F(BuilderTest, Accessor_Array_Of_Vec) {
// vec2<f32>(0.5, -0.5)); // vec2<f32>(0.5, -0.5));
// pos[1] // pos[1]
ast::type::F32 f32;
ast::type::U32 u32; ast::type::U32 u32;
ast::type::Vector vec(&f32, 2); ast::type::Array arr(ty.vec2<f32>(), 3, ast::ArrayDecorationList{});
ast::type::Array arr(&vec, 3, ast::ArrayDecorationList{});
ast::ExpressionList ary_params; auto* var = Const("pos", ast::StorageClass::kPrivate, &arr,
ary_params.push_back(create<ast::TypeConstructorExpression>( Construct(&arr, vec2<f32>(0.0f, 0.5f),
Source{}, &vec, vec2<f32>(-0.5f, -0.5f), vec2<f32>(0.5f, -0.5f)),
ast::ExpressionList{ {});
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 0.0)),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 0.5)),
}));
ary_params.push_back(create<ast::TypeConstructorExpression>( auto* expr = Index("pos", 1u);
Source{}, &vec,
ast::ExpressionList{
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, -0.5)),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, -0.5)),
}));
ary_params.push_back(create<ast::TypeConstructorExpression>( td.RegisterVariableForTesting(var);
Source{}, &vec, ASSERT_TRUE(td.DetermineResultType(var->constructor())) << td.error();
ast::ExpressionList{ ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 0.5)),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, -0.5)),
}));
ast::Variable var(
Source{}, "pos", ast::StorageClass::kPrivate, &arr, true,
create<ast::TypeConstructorExpression>(Source{}, &arr, ary_params),
ast::VariableDecorationList{});
ast::ArrayAccessorExpression expr(
Source{},
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("pos"),
"pos"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
td.RegisterVariableForTesting(&var);
ASSERT_TRUE(td.DetermineResultType(var.constructor())) << td.error();
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 18u) << b.error(); EXPECT_EQ(b.GenerateAccessorExpression(expr), 18u) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 2 %2 = OpTypeVector %3 2
@ -1061,35 +809,18 @@ TEST_F(BuilderTest, Accessor_Const_Vec) {
// const pos : vec2<f32> = vec2<f32>(0.0, 0.5); // const pos : vec2<f32> = vec2<f32>(0.0, 0.5);
// pos[1] // pos[1]
ast::type::F32 f32; auto* var = Const("pos", ast::StorageClass::kPrivate, ty.vec2<f32>(),
ast::type::U32 u32; vec2<f32>(0.0f, 0.5f), {});
ast::type::Vector vec(&f32, 2);
ast::ExpressionList vec_params; auto* expr = Index("pos", 1u);
vec_params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 0.0)));
vec_params.push_back(create<ast::ScalarConstructorExpression>(
Source{}, create<ast::FloatLiteral>(Source{}, &f32, 0.5)));
ast::Variable var(Source{}, "pos", ast::StorageClass::kPrivate, &vec, true, td.RegisterVariableForTesting(var);
create<ast::TypeConstructorExpression>( ASSERT_TRUE(td.DetermineResultType(var->constructor())) << td.error();
Source{}, &vec, std::move(vec_params)), ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::VariableDecorationList{});
ast::ArrayAccessorExpression expr(
Source{},
create<ast::IdentifierExpression>(Source{}, mod->RegisterSymbol("pos"),
"pos"),
create<ast::ScalarConstructorExpression>(
Source{}, create<ast::UintLiteral>(Source{}, &u32, 1)));
td.RegisterVariableForTesting(&var);
ASSERT_TRUE(td.DetermineResultType(var.constructor())) << td.error();
ASSERT_TRUE(td.DetermineResultType(&expr)) << td.error();
b.push_function(Function{}); b.push_function(Function{});
ASSERT_TRUE(b.GenerateFunctionVariable(&var)) << b.error(); ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
EXPECT_EQ(b.GenerateAccessorExpression(&expr), 8u) << b.error(); EXPECT_EQ(b.GenerateAccessorExpression(expr), 8u) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32 EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2 %1 = OpTypeVector %2 2

View File

@ -471,13 +471,13 @@ TEST_F(IntrinsicBuilderTest, Call_GLSLMethod_WithLoad) {
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 9u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 9u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%10 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%10 = OpExtInstImport "GLSL.std.450"
@ -506,12 +506,12 @@ TEST_P(Intrinsic_Builtin_SingleParam_Float_Test, Call_Scalar) {
auto* expr = Call(param.name, 1.0f); auto* expr = Call(param.name, 1.0f);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -535,12 +535,12 @@ TEST_P(Intrinsic_Builtin_SingleParam_Float_Test, Call_Vector) {
auto* expr = Call(param.name, vec2<f32>(1.0f, 1.0f)); auto* expr = Call(param.name, vec2<f32>(1.0f, 1.0f));
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450"
@ -590,12 +590,12 @@ TEST_F(IntrinsicBuilderTest, Call_Length_Scalar) {
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -616,12 +616,12 @@ TEST_F(IntrinsicBuilderTest, Call_Length_Vector) {
auto* expr = Call("length", vec2<f32>(1.0f, 1.0f)); auto* expr = Call("length", vec2<f32>(1.0f, 1.0f));
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -644,12 +644,12 @@ TEST_F(IntrinsicBuilderTest, Call_Normalize) {
auto* expr = Call("normalize", vec2<f32>(1.0f, 1.0f)); auto* expr = Call("normalize", vec2<f32>(1.0f, 1.0f));
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450"
@ -677,12 +677,12 @@ TEST_P(Intrinsic_Builtin_DualParam_Float_Test, Call_Scalar) {
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -707,12 +707,12 @@ TEST_P(Intrinsic_Builtin_DualParam_Float_Test, Call_Vector) {
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450"
@ -745,12 +745,12 @@ TEST_F(IntrinsicBuilderTest, Call_Distance_Scalar) {
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -772,12 +772,12 @@ TEST_F(IntrinsicBuilderTest, Call_Distance_Vector) {
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -802,12 +802,12 @@ TEST_F(IntrinsicBuilderTest, Call_Cross) {
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450"
@ -834,12 +834,12 @@ TEST_P(Intrinsic_Builtin_ThreeParam_Float_Test, Call_Scalar) {
auto* expr = Call(param.name, 1.0f, 1.0f, 1.0f); auto* expr = Call(param.name, 1.0f, 1.0f, 1.0f);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -865,12 +865,12 @@ TEST_P(Intrinsic_Builtin_ThreeParam_Float_Test, Call_Vector) {
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450"
@ -907,12 +907,12 @@ TEST_P(Intrinsic_Builtin_SingleParam_Sint_Test, Call_Scalar) {
auto* expr = Call(param.name, 1); auto* expr = Call(param.name, 1);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -936,12 +936,12 @@ TEST_P(Intrinsic_Builtin_SingleParam_Sint_Test, Call_Vector) {
auto* expr = Call(param.name, vec2<i32>(1, 1)); auto* expr = Call(param.name, vec2<i32>(1, 1));
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450"
@ -972,12 +972,12 @@ TEST_P(Intrinsic_Builtin_SingleParam_Uint_Test, Call_Scalar) {
auto* expr = Call(param.name, 1u); auto* expr = Call(param.name, 1u);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -1001,12 +1001,12 @@ TEST_P(Intrinsic_Builtin_SingleParam_Uint_Test, Call_Vector) {
auto* expr = Call(param.name, vec2<u32>(1u, 1u)); auto* expr = Call(param.name, vec2<u32>(1u, 1u));
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450"
@ -1037,12 +1037,12 @@ TEST_P(Intrinsic_Builtin_DualParam_SInt_Test, Call_Scalar) {
auto* expr = Call(param.name, 1, 1); auto* expr = Call(param.name, 1, 1);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -1066,12 +1066,12 @@ TEST_P(Intrinsic_Builtin_DualParam_SInt_Test, Call_Vector) {
auto* expr = Call(param.name, vec2<i32>(1, 1), vec2<i32>(1, 1)); auto* expr = Call(param.name, vec2<i32>(1, 1), vec2<i32>(1, 1));
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450"
@ -1103,12 +1103,12 @@ TEST_P(Intrinsic_Builtin_DualParam_UInt_Test, Call_Scalar) {
auto* expr = Call(param.name, 1u, 1u); auto* expr = Call(param.name, 1u, 1u);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -1132,12 +1132,12 @@ TEST_P(Intrinsic_Builtin_DualParam_UInt_Test, Call_Vector) {
auto* expr = Call(param.name, vec2<u32>(1u, 1u), vec2<u32>(1u, 1u)); auto* expr = Call(param.name, vec2<u32>(1u, 1u), vec2<u32>(1u, 1u));
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450"
@ -1169,12 +1169,12 @@ TEST_P(Intrinsic_Builtin_ThreeParam_Sint_Test, Call_Scalar) {
auto* expr = Call(param.name, 1, 1, 1); auto* expr = Call(param.name, 1, 1, 1);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -1200,12 +1200,12 @@ TEST_P(Intrinsic_Builtin_ThreeParam_Sint_Test, Call_Vector) {
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450"
@ -1236,12 +1236,12 @@ TEST_P(Intrinsic_Builtin_ThreeParam_Uint_Test, Call_Scalar) {
auto* expr = Call(param.name, 1u, 1u, 1u); auto* expr = Call(param.name, 1u, 1u, 1u);
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%7 = OpExtInstImport "GLSL.std.450"
@ -1267,12 +1267,12 @@ TEST_P(Intrinsic_Builtin_ThreeParam_Uint_Test, Call_Vector) {
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 5u) << b.error();
EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450" EXPECT_EQ(DumpBuilder(b), R"(%8 = OpExtInstImport "GLSL.std.450"
@ -1301,12 +1301,12 @@ TEST_F(IntrinsicBuilderTest, Call_Determinant) {
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
EXPECT_EQ(b.GenerateCallExpression(expr), 11u) << b.error(); EXPECT_EQ(b.GenerateCallExpression(expr), 11u) << b.error();
@ -1334,25 +1334,24 @@ OpFunctionEnd
TEST_F(IntrinsicBuilderTest, Call_ArrayLength) { TEST_F(IntrinsicBuilderTest, Call_ArrayLength) {
ast::StructMemberDecorationList decos; ast::StructMemberDecorationList decos;
ast::StructMemberList members; ast::StructMemberList members;
members.push_back( members.push_back(create<ast::StructMember>("a", ty.array<f32>(), decos));
create<ast::StructMember>(Source{}, "a", ty.array<f32>(), decos));
auto* s = create<ast::Struct>(Source{}, members, ast::StructDecorationList{}); auto* s = create<ast::Struct>(members, ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); ast::type::Struct s_type(mod->RegisterSymbol("my_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>(
Source{}, Expr("b"), Expr("a"))); Expr("b"), Expr("a")));
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
EXPECT_EQ(b.GenerateExpression(expr), 11u) << b.error(); EXPECT_EQ(b.GenerateExpression(expr), 11u) << b.error();
@ -1376,25 +1375,24 @@ TEST_F(IntrinsicBuilderTest, Call_ArrayLength) {
TEST_F(IntrinsicBuilderTest, Call_ArrayLength_OtherMembersInStruct) { TEST_F(IntrinsicBuilderTest, Call_ArrayLength_OtherMembersInStruct) {
ast::StructMemberDecorationList decos; ast::StructMemberDecorationList decos;
ast::StructMemberList members; ast::StructMemberList members;
members.push_back(create<ast::StructMember>(Source{}, "z", ty.f32, decos)); members.push_back(create<ast::StructMember>("z", ty.f32, decos));
members.push_back( members.push_back(create<ast::StructMember>("a", ty.array<f32>(), decos));
create<ast::StructMember>(Source{}, "a", ty.array<f32>(), decos));
auto* s = create<ast::Struct>(Source{}, members, ast::StructDecorationList{}); auto* s = create<ast::Struct>(members, ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); ast::type::Struct s_type(mod->RegisterSymbol("my_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>(
Source{}, Expr("b"), Expr("a"))); Expr("b"), Expr("a")));
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
EXPECT_EQ(b.GenerateExpression(expr), 11u) << b.error(); EXPECT_EQ(b.GenerateExpression(expr), 11u) << b.error();
@ -1421,28 +1419,26 @@ TEST_F(IntrinsicBuilderTest, DISABLED_Call_ArrayLength_Ptr) {
ast::StructMemberDecorationList decos; ast::StructMemberDecorationList decos;
ast::StructMemberList members; ast::StructMemberList members;
members.push_back(create<ast::StructMember>(Source{}, "z", ty.f32, decos)); members.push_back(create<ast::StructMember>("z", ty.f32, decos));
members.push_back( members.push_back(create<ast::StructMember>("a", ty.array<f32>(), decos));
create<ast::StructMember>(Source{}, "a", ty.array<f32>(), decos));
auto* s = create<ast::Struct>(Source{}, members, ast::StructDecorationList{}); auto* s = create<ast::Struct>(members, ast::StructDecorationList{});
ast::type::Struct s_type(mod->RegisterSymbol("my_struct"), "my_struct", s); ast::type::Struct s_type(mod->RegisterSymbol("my_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>(Source{}, Expr("b"), Expr("a")), create<ast::MemberAccessorExpression>(Expr("b"), Expr("a")), {});
{});
auto* expr = Call("arrayLength", "ptr_var"); auto* expr = Call("arrayLength", "ptr_var");
ASSERT_TRUE(td.DetermineResultType(expr)) << td.error(); ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
ast::Function func( auto* func = create<ast::Function>(
Source{}, mod->RegisterSymbol("a_func"), "a_func", {}, ty.void_, mod->RegisterSymbol("a_func"), "a_func", ast::VariableList{}, ty.void_,
create<ast::BlockStatement>(Source{}, ast::StatementList{}), create<ast::BlockStatement>(ast::StatementList{}),
ast::FunctionDecorationList{}); ast::FunctionDecorationList{});
ASSERT_TRUE(b.GenerateFunction(&func)) << b.error(); ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
EXPECT_EQ(b.GenerateExpression(expr), 11u) << b.error(); EXPECT_EQ(b.GenerateExpression(expr), 11u) << b.error();

View File

@ -2723,15 +2723,16 @@ TEST_P(IntrinsicTextureTest, Call) {
auto* texture = param.buildTextureVariable(this); auto* texture = param.buildTextureVariable(this);
auto* sampler = param.buildSamplerVariable(this); auto* sampler = param.buildSamplerVariable(this);
ast::CallExpression call{Source{}, Expr(param.function), param.args(this)}; auto* call =
create<ast::CallExpression>(Expr(param.function), param.args(this));
EXPECT_TRUE(td.Determine()) << td.error(); EXPECT_TRUE(td.Determine()) << td.error();
EXPECT_TRUE(td.DetermineResultType(&call)) << td.error(); EXPECT_TRUE(td.DetermineResultType(call)) << td.error();
ASSERT_TRUE(b.GenerateGlobalVariable(texture)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(texture)) << b.error();
ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error(); ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
EXPECT_EQ(b.GenerateExpression(&call), 8u) << b.error(); EXPECT_EQ(b.GenerateExpression(call), 8u) << b.error();
auto expected = expected_texture_overload(param.overload); auto expected = expected_texture_overload(param.overload);
EXPECT_EQ(expected.types, "\n" + DumpInstructions(b.types())); EXPECT_EQ(expected.types, "\n" + DumpInstructions(b.types()));