mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-06 14:43:31 +00:00
tint: Have ast::MemberAccessorExpression use ast::Identifier
Instead of ast::IdentifierExpression The member is not an expression, but a name. Fixed: tint:1257 Change-Id: I879ddf09c3e521a18cef85422bb2f8fe78cddf5b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/118343 Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Kokoro: Ben Clayton <bclayton@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
parent
6cba18b0fc
commit
a4117ca21b
@ -24,7 +24,7 @@ MemberAccessorExpression::MemberAccessorExpression(ProgramID pid,
|
|||||||
NodeID nid,
|
NodeID nid,
|
||||||
const Source& src,
|
const Source& src,
|
||||||
const Expression* str,
|
const Expression* str,
|
||||||
const IdentifierExpression* mem)
|
const Identifier* mem)
|
||||||
: Base(pid, nid, src), structure(str), member(mem) {
|
: Base(pid, nid, src), structure(str), member(mem) {
|
||||||
TINT_ASSERT(AST, structure);
|
TINT_ASSERT(AST, structure);
|
||||||
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, structure, program_id);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, structure, program_id);
|
||||||
|
@ -32,7 +32,7 @@ class MemberAccessorExpression final : public Castable<MemberAccessorExpression,
|
|||||||
NodeID nid,
|
NodeID nid,
|
||||||
const Source& source,
|
const Source& source,
|
||||||
const Expression* structure,
|
const Expression* structure,
|
||||||
const IdentifierExpression* member);
|
const Identifier* member);
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
MemberAccessorExpression(MemberAccessorExpression&&);
|
MemberAccessorExpression(MemberAccessorExpression&&);
|
||||||
~MemberAccessorExpression() override;
|
~MemberAccessorExpression() override;
|
||||||
@ -47,7 +47,7 @@ class MemberAccessorExpression final : public Castable<MemberAccessorExpression,
|
|||||||
const Expression* const structure;
|
const Expression* const structure;
|
||||||
|
|
||||||
/// The member expression
|
/// The member expression
|
||||||
const IdentifierExpression* const member;
|
const Identifier* const member;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::ast
|
} // namespace tint::ast
|
||||||
|
@ -22,7 +22,7 @@ using MemberAccessorExpressionTest = TestHelper;
|
|||||||
|
|
||||||
TEST_F(MemberAccessorExpressionTest, Creation) {
|
TEST_F(MemberAccessorExpressionTest, Creation) {
|
||||||
auto* str = Expr("structure");
|
auto* str = Expr("structure");
|
||||||
auto* mem = Expr("member");
|
auto* mem = Ident("member");
|
||||||
|
|
||||||
auto* stmt = create<MemberAccessorExpression>(str, mem);
|
auto* stmt = create<MemberAccessorExpression>(str, mem);
|
||||||
EXPECT_EQ(stmt->structure, str);
|
EXPECT_EQ(stmt->structure, str);
|
||||||
@ -31,14 +31,14 @@ TEST_F(MemberAccessorExpressionTest, Creation) {
|
|||||||
|
|
||||||
TEST_F(MemberAccessorExpressionTest, Creation_WithSource) {
|
TEST_F(MemberAccessorExpressionTest, Creation_WithSource) {
|
||||||
auto* stmt = create<MemberAccessorExpression>(Source{Source::Location{20, 2}},
|
auto* stmt = create<MemberAccessorExpression>(Source{Source::Location{20, 2}},
|
||||||
Expr("structure"), Expr("member"));
|
Expr("structure"), Ident("member"));
|
||||||
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* stmt = create<MemberAccessorExpression>(Expr("structure"), Expr("member"));
|
auto* stmt = create<MemberAccessorExpression>(Expr("structure"), Ident("member"));
|
||||||
EXPECT_TRUE(stmt->Is<MemberAccessorExpression>());
|
EXPECT_TRUE(stmt->Is<MemberAccessorExpression>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ TEST_F(MemberAccessorExpressionTest, Assert_Null_Struct) {
|
|||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
b.create<MemberAccessorExpression>(nullptr, b.Expr("member"));
|
b.create<MemberAccessorExpression>(nullptr, b.Ident("member"));
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ TEST_F(MemberAccessorExpressionTest, Assert_DifferentProgramID_Struct) {
|
|||||||
{
|
{
|
||||||
ProgramBuilder b1;
|
ProgramBuilder b1;
|
||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.create<MemberAccessorExpression>(b2.Expr("structure"), b1.Expr("member"));
|
b1.create<MemberAccessorExpression>(b2.Expr("structure"), b1.Ident("member"));
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ TEST_F(MemberAccessorExpressionTest, Assert_DifferentProgramID_Member) {
|
|||||||
{
|
{
|
||||||
ProgramBuilder b1;
|
ProgramBuilder b1;
|
||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.create<MemberAccessorExpression>(b1.Expr("structure"), b2.Expr("member"));
|
b1.create<MemberAccessorExpression>(b1.Expr("structure"), b2.Ident("member"));
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
@ -132,14 +132,10 @@ bool TraverseExpressions(const ast::Expression* root, diag::List& diags, CALLBAC
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&](const CallExpression* call) {
|
[&](const CallExpression* call) {
|
||||||
// TODO(crbug.com/tint/1257): Resolver breaks if we actually include
|
|
||||||
// the function name in the traversal. push_single(call->func);
|
|
||||||
push_list(call->args, p.depth + 1);
|
push_list(call->args, p.depth + 1);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&](const MemberAccessorExpression* member) {
|
[&](const MemberAccessorExpression* member) {
|
||||||
// TODO(crbug.com/tint/1257): Resolver breaks if we actually include
|
|
||||||
// the member name in the traversal. push_pair(member->member, p.depth + 1);
|
|
||||||
push_single(member->structure, p.depth + 1);
|
push_single(member->structure, p.depth + 1);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -140,12 +140,10 @@ TEST_F(TraverseExpressionsTest, DescendCallExpression) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1257): Test ignores member accessor 'member' field.
|
TEST_F(TraverseExpressionsTest, DescendMemberAccessorExpression) {
|
||||||
// Replace with the test below when fixed.
|
|
||||||
TEST_F(TraverseExpressionsTest, DescendMemberIndexExpression) {
|
|
||||||
auto* e = Expr(1_i);
|
auto* e = Expr(1_i);
|
||||||
auto* m = MemberAccessor(e, Expr("a"));
|
auto* m = MemberAccessor(e, "a");
|
||||||
auto* root = MemberAccessor(m, Expr("b"));
|
auto* root = MemberAccessor(m, "b");
|
||||||
{
|
{
|
||||||
std::vector<const ast::Expression*> l2r;
|
std::vector<const ast::Expression*> l2r;
|
||||||
TraverseExpressions<TraverseOrder::LeftToRight>(root, Diagnostics(),
|
TraverseExpressions<TraverseOrder::LeftToRight>(root, Diagnostics(),
|
||||||
@ -166,12 +164,14 @@ TEST_F(TraverseExpressionsTest, DescendMemberIndexExpression) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/tint/1257): The correct test for DescendMemberIndexExpression.
|
TEST_F(TraverseExpressionsTest, DescendMemberIndexExpression) {
|
||||||
TEST_F(TraverseExpressionsTest, DISABLED_DescendMemberIndexExpression) {
|
auto* a = Expr("a");
|
||||||
auto* e = Expr(1_i);
|
auto* b = Expr("b");
|
||||||
std::vector<const ast::IdentifierExpression*> i = {Expr("a"), Expr("b")};
|
auto* c = IndexAccessor(a, b);
|
||||||
auto* m = MemberAccessor(e, i[0]);
|
auto* d = Expr("d");
|
||||||
auto* root = MemberAccessor(m, i[1]);
|
auto* e = Expr("e");
|
||||||
|
auto* f = IndexAccessor(d, e);
|
||||||
|
auto* root = IndexAccessor(c, f);
|
||||||
{
|
{
|
||||||
std::vector<const ast::Expression*> l2r;
|
std::vector<const ast::Expression*> l2r;
|
||||||
TraverseExpressions<TraverseOrder::LeftToRight>(root, Diagnostics(),
|
TraverseExpressions<TraverseOrder::LeftToRight>(root, Diagnostics(),
|
||||||
@ -179,7 +179,7 @@ TEST_F(TraverseExpressionsTest, DISABLED_DescendMemberIndexExpression) {
|
|||||||
l2r.push_back(expr);
|
l2r.push_back(expr);
|
||||||
return ast::TraverseAction::Descend;
|
return ast::TraverseAction::Descend;
|
||||||
});
|
});
|
||||||
EXPECT_THAT(l2r, ElementsAre(root, m, e, i[0], i[1]));
|
EXPECT_THAT(l2r, ElementsAre(root, c, a, b, f, d, e));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::vector<const ast::Expression*> r2l;
|
std::vector<const ast::Expression*> r2l;
|
||||||
@ -188,7 +188,7 @@ TEST_F(TraverseExpressionsTest, DISABLED_DescendMemberIndexExpression) {
|
|||||||
r2l.push_back(expr);
|
r2l.push_back(expr);
|
||||||
return ast::TraverseAction::Descend;
|
return ast::TraverseAction::Descend;
|
||||||
});
|
});
|
||||||
EXPECT_THAT(r2l, ElementsAre(root, i[1], m, i[0], e));
|
EXPECT_THAT(r2l, ElementsAre(root, f, e, d, c, b, a));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2374,7 +2374,7 @@ class ProgramBuilder {
|
|||||||
OBJ&& obj,
|
OBJ&& obj,
|
||||||
IDX&& idx) {
|
IDX&& idx) {
|
||||||
return create<ast::MemberAccessorExpression>(source, Expr(std::forward<OBJ>(obj)),
|
return create<ast::MemberAccessorExpression>(source, Expr(std::forward<OBJ>(obj)),
|
||||||
Expr(std::forward<IDX>(idx)));
|
Ident(std::forward<IDX>(idx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @param obj the object for the member accessor expression
|
/// @param obj the object for the member accessor expression
|
||||||
@ -2383,7 +2383,7 @@ class ProgramBuilder {
|
|||||||
template <typename OBJ, typename IDX>
|
template <typename OBJ, typename IDX>
|
||||||
const ast::MemberAccessorExpression* MemberAccessor(OBJ&& obj, IDX&& idx) {
|
const ast::MemberAccessorExpression* MemberAccessor(OBJ&& obj, IDX&& idx) {
|
||||||
return create<ast::MemberAccessorExpression>(Expr(std::forward<OBJ>(obj)),
|
return create<ast::MemberAccessorExpression>(Expr(std::forward<OBJ>(obj)),
|
||||||
Expr(std::forward<IDX>(idx)));
|
Ident(std::forward<IDX>(idx)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a ast::StructMemberOffsetAttribute
|
/// Creates a ast::StructMemberOffsetAttribute
|
||||||
|
@ -1096,8 +1096,7 @@ bool FunctionEmitter::EmitPipelineInput(std::string var_name,
|
|||||||
},
|
},
|
||||||
[&](const Struct* struct_type) {
|
[&](const Struct* struct_type) {
|
||||||
store_dest = builder_.MemberAccessor(
|
store_dest = builder_.MemberAccessor(
|
||||||
store_dest,
|
store_dest, parser_impl_.GetMemberName(*struct_type, index));
|
||||||
builder_.Expr(parser_impl_.GetMemberName(*struct_type, index)));
|
|
||||||
current_type = struct_type->members[static_cast<size_t>(index)];
|
current_type = struct_type->members[static_cast<size_t>(index)];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1224,19 +1223,16 @@ bool FunctionEmitter::EmitPipelineOutput(std::string var_name,
|
|||||||
Switch(
|
Switch(
|
||||||
current_type,
|
current_type,
|
||||||
[&](const Matrix* matrix_type) {
|
[&](const Matrix* matrix_type) {
|
||||||
load_source =
|
load_source = builder_.IndexAccessor(load_source, i32(index));
|
||||||
builder_.IndexAccessor(load_source, builder_.Expr(i32(index)));
|
|
||||||
current_type = ty_.Vector(matrix_type->type, matrix_type->rows);
|
current_type = ty_.Vector(matrix_type->type, matrix_type->rows);
|
||||||
},
|
},
|
||||||
[&](const Array* array_type) {
|
[&](const Array* array_type) {
|
||||||
load_source =
|
load_source = builder_.IndexAccessor(load_source, i32(index));
|
||||||
builder_.IndexAccessor(load_source, builder_.Expr(i32(index)));
|
|
||||||
current_type = array_type->type->UnwrapAlias();
|
current_type = array_type->type->UnwrapAlias();
|
||||||
},
|
},
|
||||||
[&](const Struct* struct_type) {
|
[&](const Struct* struct_type) {
|
||||||
load_source = builder_.MemberAccessor(
|
load_source = builder_.MemberAccessor(
|
||||||
load_source,
|
load_source, parser_impl_.GetMemberName(*struct_type, index));
|
||||||
builder_.Expr(parser_impl_.GetMemberName(*struct_type, index)));
|
|
||||||
current_type = struct_type->members[static_cast<size_t>(index)];
|
current_type = struct_type->members[static_cast<size_t>(index)];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -4290,23 +4286,23 @@ TypedExpression FunctionEmitter::EmitGlslStd450MatrixInverse(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::IdentifierExpression* FunctionEmitter::Swizzle(uint32_t i) {
|
const ast::Identifier* FunctionEmitter::Swizzle(uint32_t i) {
|
||||||
if (i >= kMaxVectorLen) {
|
if (i >= kMaxVectorLen) {
|
||||||
Fail() << "vector component index is larger than " << kMaxVectorLen - 1 << ": " << i;
|
Fail() << "vector component index is larger than " << kMaxVectorLen - 1 << ": " << i;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const char* names[] = {"x", "y", "z", "w"};
|
const char* names[] = {"x", "y", "z", "w"};
|
||||||
return builder_.Expr(names[i & 3]);
|
return builder_.Ident(names[i & 3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::IdentifierExpression* FunctionEmitter::PrefixSwizzle(uint32_t n) {
|
const ast::Identifier* FunctionEmitter::PrefixSwizzle(uint32_t n) {
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 1:
|
case 1:
|
||||||
return builder_.Expr("x");
|
return builder_.Ident("x");
|
||||||
case 2:
|
case 2:
|
||||||
return builder_.Expr("xy");
|
return builder_.Ident("xy");
|
||||||
case 3:
|
case 3:
|
||||||
return builder_.Expr("xyz");
|
return builder_.Ident("xyz");
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -4510,10 +4506,8 @@ TypedExpression FunctionEmitter::MakeAccessChain(const spvtools::opt::Instructio
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto name = namer_.GetMemberName(pointee_type_id, uint32_t(index_const_val));
|
auto name = namer_.GetMemberName(pointee_type_id, uint32_t(index_const_val));
|
||||||
auto* member_access = builder_.Expr(name);
|
|
||||||
|
|
||||||
next_expr = create<ast::MemberAccessorExpression>(Source{}, current_expr.expr,
|
next_expr = builder_.MemberAccessor(Source{}, current_expr.expr, name);
|
||||||
member_access);
|
|
||||||
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(
|
pointee_type_id = pointee_type_inst->GetSingleWordInOperand(
|
||||||
static_cast<uint32_t>(index_const_val));
|
static_cast<uint32_t>(index_const_val));
|
||||||
break;
|
break;
|
||||||
@ -4673,10 +4667,8 @@ TypedExpression FunctionEmitter::MakeCompositeValueDecomposition(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto name = namer_.GetMemberName(current_type_id, uint32_t(index_val));
|
auto name = namer_.GetMemberName(current_type_id, uint32_t(index_val));
|
||||||
auto* member_access = builder_.Expr(name);
|
|
||||||
|
|
||||||
next_expr = create<ast::MemberAccessorExpression>(Source{}, current_expr.expr,
|
next_expr = builder_.MemberAccessor(Source{}, current_expr.expr, name);
|
||||||
member_access);
|
|
||||||
current_type_id = current_type_inst->GetSingleWordInOperand(index_val);
|
current_type_id = current_type_inst->GetSingleWordInOperand(index_val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -6122,9 +6114,7 @@ TypedExpression FunctionEmitter::MakeArrayLength(const spvtools::opt::Instructio
|
|||||||
if (member_expr.type->Is<Pointer>()) {
|
if (member_expr.type->Is<Pointer>()) {
|
||||||
member_expr = Dereference(member_expr);
|
member_expr = Dereference(member_expr);
|
||||||
}
|
}
|
||||||
auto* member_ident = builder_.Expr(field_name);
|
auto* member_access = builder_.MemberAccessor(Source{}, member_expr.expr, field_name);
|
||||||
auto* member_access =
|
|
||||||
create<ast::MemberAccessorExpression>(Source{}, member_expr.expr, member_ident);
|
|
||||||
|
|
||||||
// Generate the builtin function call.
|
// Generate the builtin function call.
|
||||||
auto* call_expr = builder_.Call(Source{}, "arrayLength", builder_.AddressOf(member_access));
|
auto* call_expr = builder_.Call(Source{}, "arrayLength", builder_.AddressOf(member_access));
|
||||||
|
@ -916,14 +916,14 @@ class FunctionEmitter {
|
|||||||
/// index is out of range, i.e. 4 or higher.
|
/// index is out of range, i.e. 4 or higher.
|
||||||
/// @param i index of the subcomponent
|
/// @param i index of the subcomponent
|
||||||
/// @returns the identifier expression for the `i`'th component
|
/// @returns the identifier expression for the `i`'th component
|
||||||
const ast::IdentifierExpression* Swizzle(uint32_t i);
|
const ast::Identifier* Swizzle(uint32_t i);
|
||||||
|
|
||||||
/// Returns an identifier expression for the swizzle name of the first
|
/// Returns an identifier expression for the swizzle name of the first
|
||||||
/// `n` elements of a vector. Emits an error and returns nullptr if `n`
|
/// `n` elements of a vector. Emits an error and returns nullptr if `n`
|
||||||
/// is out of range, i.e. 4 or higher.
|
/// is out of range, i.e. 4 or higher.
|
||||||
/// @param n the number of components in the swizzle
|
/// @param n the number of components in the swizzle
|
||||||
/// @returns the swizzle identifier for the first n elements of a vector
|
/// @returns the swizzle identifier for the first n elements of a vector
|
||||||
const ast::IdentifierExpression* PrefixSwizzle(uint32_t n);
|
const ast::Identifier* PrefixSwizzle(uint32_t n);
|
||||||
|
|
||||||
/// Converts SPIR-V image coordinates from an image access instruction
|
/// Converts SPIR-V image coordinates from an image access instruction
|
||||||
/// (e.g. OpImageSampledImplicitLod) into an expression list consisting of
|
/// (e.g. OpImageSampledImplicitLod) into an expression list consisting of
|
||||||
|
@ -51,26 +51,32 @@ std::string ToString(const Program& program, utils::VectorRef<const ast::Stateme
|
|||||||
|
|
||||||
std::string ToString(const Program& program, const ast::Node* node) {
|
std::string ToString(const Program& program, const ast::Node* node) {
|
||||||
writer::wgsl::GeneratorImpl writer(&program);
|
writer::wgsl::GeneratorImpl writer(&program);
|
||||||
if (auto* expr = node->As<ast::Expression>()) {
|
return Switch(
|
||||||
std::stringstream out;
|
node,
|
||||||
if (!writer.EmitExpression(out, expr)) {
|
[&](const ast::Expression* expr) {
|
||||||
return "WGSL writer error: " + writer.error();
|
std::stringstream out;
|
||||||
}
|
if (!writer.EmitExpression(out, expr)) {
|
||||||
return out.str();
|
return "WGSL writer error: " + writer.error();
|
||||||
} else if (auto* stmt = node->As<ast::Statement>()) {
|
}
|
||||||
if (!writer.EmitStatement(stmt)) {
|
return out.str();
|
||||||
return "WGSL writer error: " + writer.error();
|
},
|
||||||
}
|
[&](const ast::Statement* stmt) {
|
||||||
} else if (auto* ty = node->As<ast::Type>()) {
|
if (!writer.EmitStatement(stmt)) {
|
||||||
std::stringstream out;
|
return "WGSL writer error: " + writer.error();
|
||||||
if (!writer.EmitType(out, ty)) {
|
}
|
||||||
return "WGSL writer error: " + writer.error();
|
return writer.result();
|
||||||
}
|
},
|
||||||
return out.str();
|
[&](const ast::Type* ty) {
|
||||||
} else {
|
std::stringstream out;
|
||||||
return "<unhandled AST node type " + std::string(node->TypeInfo().name) + ">";
|
if (!writer.EmitType(out, ty)) {
|
||||||
}
|
return "WGSL writer error: " + writer.error();
|
||||||
return writer.result();
|
}
|
||||||
|
return out.str();
|
||||||
|
},
|
||||||
|
[&](const ast::Identifier* ident) { return program.Symbols().NameFor(ident->symbol); },
|
||||||
|
[&](Default) {
|
||||||
|
return "<unhandled AST node type " + std::string(node->TypeInfo().name) + ">";
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tint::reader::spirv::test
|
} // namespace tint::reader::spirv::test
|
||||||
|
@ -2707,7 +2707,7 @@ Maybe<const ast::Expression*> ParserImpl::component_or_swizzle_specifier(
|
|||||||
}
|
}
|
||||||
|
|
||||||
prefix = builder_.MemberAccessor(ident.source, prefix,
|
prefix = builder_.MemberAccessor(ident.source, prefix,
|
||||||
builder_.Expr(ident.source, ident.value));
|
builder_.Ident(ident.source, ident.value));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,9 +71,7 @@ TEST_F(ParserImplTest, AssignmentStmt_Parses_ToMember) {
|
|||||||
ASSERT_TRUE(a->lhs->Is<ast::MemberAccessorExpression>());
|
ASSERT_TRUE(a->lhs->Is<ast::MemberAccessorExpression>());
|
||||||
auto* mem = a->lhs->As<ast::MemberAccessorExpression>();
|
auto* mem = a->lhs->As<ast::MemberAccessorExpression>();
|
||||||
|
|
||||||
ASSERT_TRUE(mem->member->Is<ast::IdentifierExpression>());
|
EXPECT_EQ(mem->member->symbol, p->builder().Symbols().Get("d"));
|
||||||
auto* ident_expr = mem->member->As<ast::IdentifierExpression>();
|
|
||||||
EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("d"));
|
|
||||||
|
|
||||||
ASSERT_TRUE(mem->structure->Is<ast::IndexAccessorExpression>());
|
ASSERT_TRUE(mem->structure->Is<ast::IndexAccessorExpression>());
|
||||||
auto* idx = mem->structure->As<ast::IndexAccessorExpression>();
|
auto* idx = mem->structure->As<ast::IndexAccessorExpression>();
|
||||||
@ -84,20 +82,15 @@ TEST_F(ParserImplTest, AssignmentStmt_Parses_ToMember) {
|
|||||||
|
|
||||||
ASSERT_TRUE(idx->object->Is<ast::MemberAccessorExpression>());
|
ASSERT_TRUE(idx->object->Is<ast::MemberAccessorExpression>());
|
||||||
mem = idx->object->As<ast::MemberAccessorExpression>();
|
mem = idx->object->As<ast::MemberAccessorExpression>();
|
||||||
ASSERT_TRUE(mem->member->Is<ast::IdentifierExpression>());
|
EXPECT_EQ(mem->member->symbol, p->builder().Symbols().Get("c"));
|
||||||
ident_expr = mem->member->As<ast::IdentifierExpression>();
|
|
||||||
EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("c"));
|
|
||||||
|
|
||||||
ASSERT_TRUE(mem->structure->Is<ast::MemberAccessorExpression>());
|
ASSERT_TRUE(mem->structure->Is<ast::MemberAccessorExpression>());
|
||||||
|
|
||||||
mem = mem->structure->As<ast::MemberAccessorExpression>();
|
mem = mem->structure->As<ast::MemberAccessorExpression>();
|
||||||
|
|
||||||
ASSERT_TRUE(mem->structure->Is<ast::IdentifierExpression>());
|
ASSERT_TRUE(mem->structure->Is<ast::IdentifierExpression>());
|
||||||
ident_expr = mem->structure->As<ast::IdentifierExpression>();
|
auto* ident_expr = mem->structure->As<ast::IdentifierExpression>();
|
||||||
EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("a"));
|
EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("a"));
|
||||||
|
EXPECT_EQ(mem->member->symbol, p->builder().Symbols().Get("b"));
|
||||||
ASSERT_TRUE(mem->member->Is<ast::IdentifierExpression>());
|
|
||||||
ident_expr = mem->member->As<ast::IdentifierExpression>();
|
|
||||||
EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, AssignmentStmt_Parses_ToPhony) {
|
TEST_F(ParserImplTest, AssignmentStmt_Parses_ToPhony) {
|
||||||
|
@ -90,9 +90,7 @@ TEST_F(ParserImplTest, IncrementDecrementStmt_ToMember) {
|
|||||||
ASSERT_TRUE(i->lhs->Is<ast::MemberAccessorExpression>());
|
ASSERT_TRUE(i->lhs->Is<ast::MemberAccessorExpression>());
|
||||||
auto* mem = i->lhs->As<ast::MemberAccessorExpression>();
|
auto* mem = i->lhs->As<ast::MemberAccessorExpression>();
|
||||||
|
|
||||||
ASSERT_TRUE(mem->member->Is<ast::IdentifierExpression>());
|
EXPECT_EQ(mem->member->symbol, p->builder().Symbols().Get("d"));
|
||||||
auto* ident_expr = mem->member->As<ast::IdentifierExpression>();
|
|
||||||
EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("d"));
|
|
||||||
|
|
||||||
ASSERT_TRUE(mem->structure->Is<ast::IndexAccessorExpression>());
|
ASSERT_TRUE(mem->structure->Is<ast::IndexAccessorExpression>());
|
||||||
auto* idx = mem->structure->As<ast::IndexAccessorExpression>();
|
auto* idx = mem->structure->As<ast::IndexAccessorExpression>();
|
||||||
@ -103,20 +101,15 @@ TEST_F(ParserImplTest, IncrementDecrementStmt_ToMember) {
|
|||||||
|
|
||||||
ASSERT_TRUE(idx->object->Is<ast::MemberAccessorExpression>());
|
ASSERT_TRUE(idx->object->Is<ast::MemberAccessorExpression>());
|
||||||
mem = idx->object->As<ast::MemberAccessorExpression>();
|
mem = idx->object->As<ast::MemberAccessorExpression>();
|
||||||
ASSERT_TRUE(mem->member->Is<ast::IdentifierExpression>());
|
EXPECT_EQ(mem->member->symbol, p->builder().Symbols().Get("c"));
|
||||||
ident_expr = mem->member->As<ast::IdentifierExpression>();
|
|
||||||
EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("c"));
|
|
||||||
|
|
||||||
ASSERT_TRUE(mem->structure->Is<ast::MemberAccessorExpression>());
|
ASSERT_TRUE(mem->structure->Is<ast::MemberAccessorExpression>());
|
||||||
mem = mem->structure->As<ast::MemberAccessorExpression>();
|
mem = mem->structure->As<ast::MemberAccessorExpression>();
|
||||||
|
|
||||||
ASSERT_TRUE(mem->structure->Is<ast::IdentifierExpression>());
|
ASSERT_TRUE(mem->structure->Is<ast::IdentifierExpression>());
|
||||||
ident_expr = mem->structure->As<ast::IdentifierExpression>();
|
auto* ident_expr = mem->structure->As<ast::IdentifierExpression>();
|
||||||
EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("a"));
|
EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("a"));
|
||||||
|
EXPECT_EQ(mem->member->symbol, p->builder().Symbols().Get("b"));
|
||||||
ASSERT_TRUE(mem->member->Is<ast::IdentifierExpression>());
|
|
||||||
ident_expr = mem->member->As<ast::IdentifierExpression>();
|
|
||||||
EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, IncrementDecrementStmt_InvalidLHS) {
|
TEST_F(ParserImplTest, IncrementDecrementStmt_InvalidLHS) {
|
||||||
|
@ -147,10 +147,7 @@ TEST_F(ParserImplTest, LHSExpression_PostfixExpression) {
|
|||||||
|
|
||||||
auto* struct_ident = access->structure->As<ast::IdentifierExpression>();
|
auto* struct_ident = access->structure->As<ast::IdentifierExpression>();
|
||||||
EXPECT_EQ(struct_ident->identifier->symbol, p->builder().Symbols().Get("a"));
|
EXPECT_EQ(struct_ident->identifier->symbol, p->builder().Symbols().Get("a"));
|
||||||
|
EXPECT_EQ(access->member->symbol, p->builder().Symbols().Get("foo"));
|
||||||
ASSERT_TRUE(access->member->Is<ast::IdentifierExpression>());
|
|
||||||
auto* member_ident = access->member->As<ast::IdentifierExpression>();
|
|
||||||
EXPECT_EQ(member_ident->identifier->symbol, p->builder().Symbols().Get("foo"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, LHSExpression_InvalidPostfixExpression) {
|
TEST_F(ParserImplTest, LHSExpression_InvalidPostfixExpression) {
|
||||||
|
@ -167,7 +167,7 @@ TEST_F(ParserImplTest, SingularExpression_MemberAccessor) {
|
|||||||
EXPECT_EQ(m->structure->As<ast::IdentifierExpression>()->identifier->symbol,
|
EXPECT_EQ(m->structure->As<ast::IdentifierExpression>()->identifier->symbol,
|
||||||
p->builder().Symbols().Get("a"));
|
p->builder().Symbols().Get("a"));
|
||||||
|
|
||||||
EXPECT_EQ(m->member->identifier->symbol, p->builder().Symbols().Get("b"));
|
EXPECT_EQ(m->member->symbol, p->builder().Symbols().Get("b"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ParserImplTest, SingularExpression_MemberAccesssor_InvalidIdent) {
|
TEST_F(ParserImplTest, SingularExpression_MemberAccesssor_InvalidIdent) {
|
||||||
|
@ -2151,7 +2151,7 @@ TEST_F(ResolverConstEvalTest, ShortCircuit_And_Error_MemberAccess) {
|
|||||||
GlobalConst("s", Construct(ty.type_name("S"), Expr(1_a), Expr(2.0_a)));
|
GlobalConst("s", Construct(ty.type_name("S"), Expr(1_a), Expr(2.0_a)));
|
||||||
GlobalConst("one", Expr(1_a));
|
GlobalConst("one", Expr(1_a));
|
||||||
auto* lhs = Equal("one", 0_a);
|
auto* lhs = Equal("one", 0_a);
|
||||||
auto* rhs = Equal(MemberAccessor(Source{{12, 34}}, "s", Expr("c")), 0_a);
|
auto* rhs = Equal(MemberAccessor(Source{{12, 34}}, "s", "c"), 0_a);
|
||||||
GlobalConst("result", LogicalAnd(lhs, rhs));
|
GlobalConst("result", LogicalAnd(lhs, rhs));
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
@ -2170,7 +2170,7 @@ TEST_F(ResolverConstEvalTest, ShortCircuit_Or_Error_MemberAccess) {
|
|||||||
GlobalConst("s", Construct(ty.type_name("S"), Expr(1_a), Expr(2.0_a)));
|
GlobalConst("s", Construct(ty.type_name("S"), Expr(1_a), Expr(2.0_a)));
|
||||||
GlobalConst("one", Expr(1_a));
|
GlobalConst("one", Expr(1_a));
|
||||||
auto* lhs = Equal("one", 1_a);
|
auto* lhs = Equal("one", 1_a);
|
||||||
auto* rhs = Equal(MemberAccessor(Source{{12, 34}}, "s", Expr("c")), 0_a);
|
auto* rhs = Equal(MemberAccessor(Source{{12, 34}}, "s", "c"), 0_a);
|
||||||
GlobalConst("result", LogicalOr(lhs, rhs));
|
GlobalConst("result", LogicalOr(lhs, rhs));
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
@ -2189,7 +2189,7 @@ TEST_F(ResolverConstEvalTest, ShortCircuit_And_Error_Swizzle) {
|
|||||||
// const result = (one == 0) && (vec2(1, 2).z == 0);
|
// const result = (one == 0) && (vec2(1, 2).z == 0);
|
||||||
GlobalConst("one", Expr(1_a));
|
GlobalConst("one", Expr(1_a));
|
||||||
auto* lhs = Equal("one", 0_a);
|
auto* lhs = Equal("one", 0_a);
|
||||||
auto* rhs = Equal(MemberAccessor(vec2<AInt>(1_a, 2_a), Expr(Source{{12, 34}}, "z")), 0_a);
|
auto* rhs = Equal(MemberAccessor(vec2<AInt>(1_a, 2_a), Ident(Source{{12, 34}}, "z")), 0_a);
|
||||||
GlobalConst("result", LogicalAnd(lhs, rhs));
|
GlobalConst("result", LogicalAnd(lhs, rhs));
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
@ -2201,7 +2201,7 @@ TEST_F(ResolverConstEvalTest, ShortCircuit_Or_Error_Swizzle) {
|
|||||||
// const result = (one == 1) || (vec2(1, 2).z == 0);
|
// const result = (one == 1) || (vec2(1, 2).z == 0);
|
||||||
GlobalConst("one", Expr(1_a));
|
GlobalConst("one", Expr(1_a));
|
||||||
auto* lhs = Equal("one", 1_a);
|
auto* lhs = Equal("one", 1_a);
|
||||||
auto* rhs = Equal(MemberAccessor(vec2<AInt>(1_a, 2_a), Expr(Source{{12, 34}}, "z")), 0_a);
|
auto* rhs = Equal(MemberAccessor(vec2<AInt>(1_a, 2_a), Ident(Source{{12, 34}}, "z")), 0_a);
|
||||||
GlobalConst("result", LogicalOr(lhs, rhs));
|
GlobalConst("result", LogicalOr(lhs, rhs));
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
@ -2767,12 +2767,11 @@ sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* e
|
|||||||
bool has_side_effects = object && object->HasSideEffects();
|
bool has_side_effects = object && object->HasSideEffects();
|
||||||
|
|
||||||
Mark(expr->member);
|
Mark(expr->member);
|
||||||
Mark(expr->member->identifier);
|
|
||||||
|
|
||||||
return Switch(
|
return Switch(
|
||||||
storage_ty, //
|
storage_ty, //
|
||||||
[&](const sem::Struct* str) -> sem::Expression* {
|
[&](const sem::Struct* str) -> sem::Expression* {
|
||||||
auto symbol = expr->member->identifier->symbol;
|
auto symbol = expr->member->symbol;
|
||||||
|
|
||||||
const sem::StructMember* member = nullptr;
|
const sem::StructMember* member = nullptr;
|
||||||
for (auto* m : str->Members()) {
|
for (auto* m : str->Members()) {
|
||||||
@ -2805,7 +2804,7 @@ sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* e
|
|||||||
},
|
},
|
||||||
|
|
||||||
[&](const type::Vector* vec) -> sem::Expression* {
|
[&](const type::Vector* vec) -> sem::Expression* {
|
||||||
std::string s = builder_->Symbols().NameFor(expr->member->identifier->symbol);
|
std::string s = builder_->Symbols().NameFor(expr->member->symbol);
|
||||||
auto size = s.size();
|
auto size = s.size();
|
||||||
utils::Vector<uint32_t, 4> swizzle;
|
utils::Vector<uint32_t, 4> swizzle;
|
||||||
swizzle.Reserve(s.size());
|
swizzle.Reserve(s.size());
|
||||||
|
@ -358,9 +358,7 @@ TEST_F(ResolverValidationTest, AddressSpace_TextureExplicitAddressSpace) {
|
|||||||
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadChar) {
|
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadChar) {
|
||||||
GlobalVar("my_vec", ty.vec3<f32>(), type::AddressSpace::kPrivate);
|
GlobalVar("my_vec", ty.vec3<f32>(), type::AddressSpace::kPrivate);
|
||||||
|
|
||||||
auto* ident = Expr(Source{{{3, 3}, {3, 7}}}, "xyqz");
|
auto* mem = MemberAccessor("my_vec", Ident(Source{{{3, 3}, {3, 7}}}, "xyqz"));
|
||||||
|
|
||||||
auto* mem = MemberAccessor("my_vec", ident);
|
|
||||||
WrapInFunction(mem);
|
WrapInFunction(mem);
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
@ -370,9 +368,7 @@ TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadChar) {
|
|||||||
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_MixedChars) {
|
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_MixedChars) {
|
||||||
GlobalVar("my_vec", ty.vec4<f32>(), type::AddressSpace::kPrivate);
|
GlobalVar("my_vec", ty.vec4<f32>(), type::AddressSpace::kPrivate);
|
||||||
|
|
||||||
auto* ident = Expr(Source{{{3, 3}, {3, 7}}}, "rgyw");
|
auto* mem = MemberAccessor("my_vec", Ident(Source{{{3, 3}, {3, 7}}}, "rgyw"));
|
||||||
|
|
||||||
auto* mem = MemberAccessor("my_vec", ident);
|
|
||||||
WrapInFunction(mem);
|
WrapInFunction(mem);
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
@ -383,8 +379,7 @@ TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_MixedChars) {
|
|||||||
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadLength) {
|
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadLength) {
|
||||||
GlobalVar("my_vec", ty.vec3<f32>(), type::AddressSpace::kPrivate);
|
GlobalVar("my_vec", ty.vec3<f32>(), type::AddressSpace::kPrivate);
|
||||||
|
|
||||||
auto* ident = Expr(Source{{{3, 3}, {3, 8}}}, "zzzzz");
|
auto* mem = MemberAccessor("my_vec", Ident(Source{{{3, 3}, {3, 8}}}, "zzzzz"));
|
||||||
auto* mem = MemberAccessor("my_vec", ident);
|
|
||||||
WrapInFunction(mem);
|
WrapInFunction(mem);
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
@ -394,8 +389,7 @@ TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadLength) {
|
|||||||
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadIndex) {
|
TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadIndex) {
|
||||||
GlobalVar("my_vec", ty.vec2<f32>(), type::AddressSpace::kPrivate);
|
GlobalVar("my_vec", ty.vec2<f32>(), type::AddressSpace::kPrivate);
|
||||||
|
|
||||||
auto* ident = Expr(Source{{3, 3}}, "z");
|
auto* mem = MemberAccessor("my_vec", Ident(Source{{3, 3}}, "z"));
|
||||||
auto* mem = MemberAccessor("my_vec", ident);
|
|
||||||
WrapInFunction(mem);
|
WrapInFunction(mem);
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
@ -406,10 +400,9 @@ TEST_F(ResolverValidationTest, Expr_MemberAccessor_BadParent) {
|
|||||||
// var param: vec4<f32>
|
// var param: vec4<f32>
|
||||||
// let ret: f32 = *(¶m).x;
|
// let ret: f32 = *(¶m).x;
|
||||||
auto* param = Var("param", ty.vec4<f32>());
|
auto* param = Var("param", ty.vec4<f32>());
|
||||||
auto* x = Expr(Source{{12, 34}}, "x");
|
|
||||||
|
|
||||||
auto* addressOf_expr = AddressOf(param);
|
auto* addressOf_expr = AddressOf(param);
|
||||||
auto* accessor_expr = MemberAccessor(addressOf_expr, x);
|
auto* accessor_expr = MemberAccessor(addressOf_expr, Ident(Source{{12, 34}}, "x"));
|
||||||
auto* star_p = Deref(accessor_expr);
|
auto* star_p = Deref(accessor_expr);
|
||||||
auto* ret = Var("r", ty.f32(), star_p);
|
auto* ret = Var("r", ty.f32(), star_p);
|
||||||
WrapInFunction(Decl(param), Decl(ret));
|
WrapInFunction(Decl(param), Decl(ret));
|
||||||
@ -427,8 +420,7 @@ TEST_F(ResolverValidationTest, EXpr_MemberAccessor_FuncGoodParent) {
|
|||||||
// }
|
// }
|
||||||
auto* p = Param("p", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction));
|
auto* p = Param("p", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction));
|
||||||
auto* star_p = Deref(p);
|
auto* star_p = Deref(p);
|
||||||
auto* z = Expr("z");
|
auto* accessor_expr = MemberAccessor(star_p, "z");
|
||||||
auto* accessor_expr = MemberAccessor(star_p, z);
|
|
||||||
auto* x = Var("x", ty.f32(), accessor_expr);
|
auto* x = Var("x", ty.f32(), accessor_expr);
|
||||||
Func("func", utils::Vector{p}, ty.f32(),
|
Func("func", utils::Vector{p}, ty.f32(),
|
||||||
utils::Vector{
|
utils::Vector{
|
||||||
@ -444,8 +436,7 @@ TEST_F(ResolverValidationTest, EXpr_MemberAccessor_FuncBadParent) {
|
|||||||
// return x;
|
// return x;
|
||||||
// }
|
// }
|
||||||
auto* p = Param("p", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction));
|
auto* p = Param("p", ty.pointer(ty.vec4<f32>(), type::AddressSpace::kFunction));
|
||||||
auto* z = Expr(Source{{12, 34}}, "z");
|
auto* accessor_expr = MemberAccessor(p, Ident(Source{{12, 34}}, "z"));
|
||||||
auto* accessor_expr = MemberAccessor(p, z);
|
|
||||||
auto* star_p = Deref(accessor_expr);
|
auto* star_p = Deref(accessor_expr);
|
||||||
auto* x = Var("x", ty.f32(), star_p);
|
auto* x = Var("x", ty.f32(), star_p);
|
||||||
Func("func", utils::Vector{p}, ty.f32(),
|
Func("func", utils::Vector{p}, ty.f32(),
|
||||||
|
@ -439,7 +439,7 @@ struct CanonicalizeEntryPointIO::State {
|
|||||||
const ast::Expression* GLPosition(const char* component) {
|
const ast::Expression* GLPosition(const char* component) {
|
||||||
Symbol pos = ctx.dst->Symbols().Register("gl_Position");
|
Symbol pos = ctx.dst->Symbols().Register("gl_Position");
|
||||||
Symbol c = ctx.dst->Symbols().Register(component);
|
Symbol c = ctx.dst->Symbols().Register(component);
|
||||||
return ctx.dst->MemberAccessor(ctx.dst->Expr(pos), ctx.dst->Expr(c));
|
return ctx.dst->MemberAccessor(ctx.dst->Expr(pos), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create the wrapper function's struct parameter and type objects.
|
/// Create the wrapper function's struct parameter and type objects.
|
||||||
|
@ -915,7 +915,7 @@ Transform::ApplyResult DecomposeMemoryAccess::Apply(const Program* src,
|
|||||||
} else {
|
} else {
|
||||||
if (auto access = state.TakeAccess(accessor->structure)) {
|
if (auto access = state.TakeAccess(accessor->structure)) {
|
||||||
auto* str_ty = access.type->As<sem::Struct>();
|
auto* str_ty = access.type->As<sem::Struct>();
|
||||||
auto* member = str_ty->FindMember(accessor->member->identifier->symbol);
|
auto* member = str_ty->FindMember(accessor->member->symbol);
|
||||||
auto offset = member->Offset();
|
auto offset = member->Offset();
|
||||||
state.AddAccess(accessor, {
|
state.AddAccess(accessor, {
|
||||||
access.var,
|
access.var,
|
||||||
|
@ -177,7 +177,7 @@ Transform::ApplyResult NumWorkgroupsFromUniform::Apply(const Program* src,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to_replace.count({ident->identifier->symbol, accessor->member->identifier->symbol})) {
|
if (to_replace.count({ident->identifier->symbol, accessor->member->symbol})) {
|
||||||
ctx.Replace(accessor, b.MemberAccessor(get_ubo()->symbol, kNumWorkgroupsMemberName));
|
ctx.Replace(accessor, b.MemberAccessor(get_ubo()->symbol, kNumWorkgroupsMemberName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ class DecomposeSideEffects::CollectHoistsState : public StateBase {
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
[&](const ast::MemberAccessorExpression* e) {
|
[&](const ast::MemberAccessorExpression* e) {
|
||||||
if (HasSideEffects(e->structure) || HasSideEffects(e->member)) {
|
if (HasSideEffects(e->structure)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
no_side_effects.insert(e);
|
no_side_effects.insert(e);
|
||||||
@ -216,7 +216,7 @@ class DecomposeSideEffects::CollectHoistsState : public StateBase {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto binary_process = [&](auto* lhs, auto* rhs) {
|
auto binary_process = [&](const ast::Expression* lhs, const ast::Expression* rhs) {
|
||||||
// If neither side causes side-effects, but at least one receives them,
|
// If neither side causes side-effects, but at least one receives them,
|
||||||
// let parent node hoist. This avoids over-hoisting side-effect receivers
|
// let parent node hoist. This avoids over-hoisting side-effect receivers
|
||||||
// of compound binary expressions (e.g. for "((a && b) && c) && f()", we
|
// of compound binary expressions (e.g. for "((a && b) && c) && f()", we
|
||||||
@ -236,7 +236,8 @@ class DecomposeSideEffects::CollectHoistsState : public StateBase {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto accessor_process = [&](auto* lhs, auto* rhs) {
|
auto accessor_process = [&](const ast::Expression* lhs,
|
||||||
|
const ast::Expression* rhs = nullptr) {
|
||||||
auto maybe = process(lhs);
|
auto maybe = process(lhs);
|
||||||
// If lhs is a variable, let parent node hoist otherwise flush it right
|
// If lhs is a variable, let parent node hoist otherwise flush it right
|
||||||
// away. This is to avoid over-hoisting the lhs of accessor chains (e.g.
|
// away. This is to avoid over-hoisting the lhs of accessor chains (e.g.
|
||||||
@ -247,7 +248,9 @@ class DecomposeSideEffects::CollectHoistsState : public StateBase {
|
|||||||
Flush(maybe_hoist);
|
Flush(maybe_hoist);
|
||||||
maybe = false;
|
maybe = false;
|
||||||
}
|
}
|
||||||
default_process(rhs);
|
if (rhs) {
|
||||||
|
default_process(rhs);
|
||||||
|
}
|
||||||
return maybe;
|
return maybe;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -320,9 +323,7 @@ class DecomposeSideEffects::CollectHoistsState : public StateBase {
|
|||||||
[&](const ast::IndexAccessorExpression* e) {
|
[&](const ast::IndexAccessorExpression* e) {
|
||||||
return accessor_process(e->object, e->index);
|
return accessor_process(e->object, e->index);
|
||||||
},
|
},
|
||||||
[&](const ast::MemberAccessorExpression* e) {
|
[&](const ast::MemberAccessorExpression* e) { return accessor_process(e->structure); },
|
||||||
return accessor_process(e->structure, e->member);
|
|
||||||
},
|
|
||||||
[&](const ast::LiteralExpression*) {
|
[&](const ast::LiteralExpression*) {
|
||||||
// Leaf
|
// Leaf
|
||||||
return false;
|
return false;
|
||||||
@ -519,7 +520,6 @@ class DecomposeSideEffects::DecomposeState : public StateBase {
|
|||||||
},
|
},
|
||||||
[&](const ast::MemberAccessorExpression* member) {
|
[&](const ast::MemberAccessorExpression* member) {
|
||||||
ctx.Replace(member->structure, decompose(member->structure));
|
ctx.Replace(member->structure, decompose(member->structure));
|
||||||
ctx.Replace(member->member, decompose(member->member));
|
|
||||||
return clone_maybe_hoisted(member);
|
return clone_maybe_hoisted(member);
|
||||||
},
|
},
|
||||||
[&](const ast::UnaryOpExpression* unary) {
|
[&](const ast::UnaryOpExpression* unary) {
|
||||||
|
@ -1287,11 +1287,11 @@ Transform::ApplyResult Renamer::Apply(const Program* src,
|
|||||||
[&](const ast::MemberAccessorExpression* accessor) {
|
[&](const ast::MemberAccessorExpression* accessor) {
|
||||||
auto* sem = src->Sem().Get(accessor)->UnwrapLoad();
|
auto* sem = src->Sem().Get(accessor)->UnwrapLoad();
|
||||||
if (sem->Is<sem::Swizzle>()) {
|
if (sem->Is<sem::Swizzle>()) {
|
||||||
preserved_identifiers.Add(accessor->member->identifier);
|
preserved_identifiers.Add(accessor->member);
|
||||||
} else if (auto* str_expr = src->Sem().Get(accessor->structure)) {
|
} else if (auto* str_expr = src->Sem().Get(accessor->structure)) {
|
||||||
if (auto* ty = str_expr->Type()->UnwrapRef()->As<sem::Struct>()) {
|
if (auto* ty = str_expr->Type()->UnwrapRef()->As<sem::Struct>()) {
|
||||||
if (ty->Declaration() == nullptr) { // Builtin structure
|
if (ty->Declaration() == nullptr) { // Builtin structure
|
||||||
preserved_identifiers.Add(accessor->member->identifier);
|
preserved_identifiers.Add(accessor->member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ struct SpirvAtomic::State {
|
|||||||
auto old_value_decl = b.Decl(b.Let(
|
auto old_value_decl = b.Decl(b.Let(
|
||||||
old_value,
|
old_value,
|
||||||
b.MemberAccessor(b.Call(sem::str(stub->builtin), std::move(out_args)),
|
b.MemberAccessor(b.Call(sem::str(stub->builtin), std::move(out_args)),
|
||||||
b.Expr("old_value"))));
|
"old_value")));
|
||||||
ctx.InsertBefore(block->statements, call->Stmt()->Declaration(),
|
ctx.InsertBefore(block->statements, call->Stmt()->Declaration(),
|
||||||
old_value_decl);
|
old_value_decl);
|
||||||
ctx.Replace(call->Declaration(), b.Expr(old_value));
|
ctx.Replace(call->Declaration(), b.Expr(old_value));
|
||||||
|
@ -2731,7 +2731,7 @@ bool GeneratorImpl::EmitMemberAccessor(std::ostream& out,
|
|||||||
sem,
|
sem,
|
||||||
[&](const sem::Swizzle*) {
|
[&](const sem::Swizzle*) {
|
||||||
// Swizzles output the name directly
|
// Swizzles output the name directly
|
||||||
out << builder_.Symbols().NameFor(expr->member->identifier->symbol);
|
out << builder_.Symbols().NameFor(expr->member->symbol);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&](const sem::StructMemberAccess* member_access) {
|
[&](const sem::StructMemberAccess* member_access) {
|
||||||
|
@ -3753,7 +3753,7 @@ bool GeneratorImpl::EmitMemberAccessor(std::ostream& out,
|
|||||||
sem,
|
sem,
|
||||||
[&](const sem::Swizzle*) {
|
[&](const sem::Swizzle*) {
|
||||||
// Swizzles output the name directly
|
// Swizzles output the name directly
|
||||||
out << builder_.Symbols().NameFor(expr->member->identifier->symbol);
|
out << builder_.Symbols().NameFor(expr->member->symbol);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[&](const sem::StructMemberAccess* member_access) {
|
[&](const sem::StructMemberAccess* member_access) {
|
||||||
|
@ -2369,7 +2369,7 @@ bool GeneratorImpl::EmitMemberAccessor(std::ostream& out,
|
|||||||
if (!write_lhs()) {
|
if (!write_lhs()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
out << ")." << program_->Symbols().NameFor(expr->member->identifier->symbol);
|
out << ")." << program_->Symbols().NameFor(expr->member->symbol);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
@ -217,9 +217,8 @@ bool GeneratorImpl::EmitMemberAccessor(std::ostream& out,
|
|||||||
out << ")";
|
out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
out << ".";
|
out << "." << program_->Symbols().NameFor(expr->member->symbol);
|
||||||
|
return true;
|
||||||
return EmitExpression(out, expr->member);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratorImpl::EmitBitcast(std::ostream& out, const ast::BitcastExpression* expr) {
|
bool GeneratorImpl::EmitBitcast(std::ostream& out, const ast::BitcastExpression* expr) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user