tint: Rename SourceVariable() to RootIdentifier()
This is now a well-defined term in the WGSL spec, so we should use it. Change-Id: Icc46a77f0a465afbfd39cdaec84e506b143c8c0c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/109220 Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Auto-Submit: James Price <jrprice@google.com>
This commit is contained in:
parent
bb8d7341d6
commit
a7cd3aeff0
|
@ -1160,7 +1160,7 @@ if (tint_build_unittests) {
|
||||||
"resolver/resolver_test_helper.cc",
|
"resolver/resolver_test_helper.cc",
|
||||||
"resolver/resolver_test_helper.h",
|
"resolver/resolver_test_helper.h",
|
||||||
"resolver/side_effects_test.cc",
|
"resolver/side_effects_test.cc",
|
||||||
"resolver/source_variable_test.cc",
|
"resolver/root_identifier_test.cc",
|
||||||
"resolver/static_assert_test.cc",
|
"resolver/static_assert_test.cc",
|
||||||
"resolver/struct_address_space_use_test.cc",
|
"resolver/struct_address_space_use_test.cc",
|
||||||
"resolver/struct_layout_test.cc",
|
"resolver/struct_layout_test.cc",
|
||||||
|
|
|
@ -885,7 +885,7 @@ if(TINT_BUILD_TESTS)
|
||||||
resolver/resolver_test.cc
|
resolver/resolver_test.cc
|
||||||
resolver/side_effects_test.cc
|
resolver/side_effects_test.cc
|
||||||
resolver/static_assert_test.cc
|
resolver/static_assert_test.cc
|
||||||
resolver/source_variable_test.cc
|
resolver/root_identifier_test.cc
|
||||||
resolver/address_space_layout_validation_test.cc
|
resolver/address_space_layout_validation_test.cc
|
||||||
resolver/address_space_validation_test.cc
|
resolver/address_space_validation_test.cc
|
||||||
resolver/struct_layout_test.cc
|
resolver/struct_layout_test.cc
|
||||||
|
|
|
@ -892,10 +892,10 @@ void Inspector::GetOriginatingResources(std::array<const ast::Expression*, N> ex
|
||||||
utils::UniqueVector<const ast::CallExpression*, 8> callsites;
|
utils::UniqueVector<const ast::CallExpression*, 8> callsites;
|
||||||
|
|
||||||
for (size_t i = 0; i < N; i++) {
|
for (size_t i = 0; i < N; i++) {
|
||||||
const sem::Variable* source_var = sem.Get(exprs[i])->SourceVariable();
|
const sem::Variable* root_ident = sem.Get(exprs[i])->RootIdentifier();
|
||||||
if (auto* global = source_var->As<sem::GlobalVariable>()) {
|
if (auto* global = root_ident->As<sem::GlobalVariable>()) {
|
||||||
globals[i] = global;
|
globals[i] = global;
|
||||||
} else if (auto* param = source_var->As<sem::Parameter>()) {
|
} else if (auto* param = root_ident->As<sem::Parameter>()) {
|
||||||
auto* func = tint::As<sem::Function>(param->Owner());
|
auto* func = tint::As<sem::Function>(param->Owner());
|
||||||
if (func->CallSites().empty()) {
|
if (func->CallSites().empty()) {
|
||||||
// One or more of the expressions is a parameter, but this function
|
// One or more of the expressions is a parameter, but this function
|
||||||
|
|
|
@ -1712,7 +1712,7 @@ sem::Expression* Resolver::IndexAccessor(const ast::IndexAccessorExpression* exp
|
||||||
bool has_side_effects = idx->HasSideEffects() || obj->HasSideEffects();
|
bool has_side_effects = idx->HasSideEffects() || obj->HasSideEffects();
|
||||||
auto* sem = builder_->create<sem::IndexAccessorExpression>(
|
auto* sem = builder_->create<sem::IndexAccessorExpression>(
|
||||||
expr, ty, stage, obj, idx, current_statement_, std::move(val), has_side_effects,
|
expr, ty, stage, obj, idx, current_statement_, std::move(val), has_side_effects,
|
||||||
obj->SourceVariable());
|
obj->RootIdentifier());
|
||||||
sem->Behaviors() = idx->Behaviors() + obj->Behaviors();
|
sem->Behaviors() = idx->Behaviors() + obj->Behaviors();
|
||||||
return sem;
|
return sem;
|
||||||
}
|
}
|
||||||
|
@ -2365,7 +2365,7 @@ sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* e
|
||||||
auto* structure = sem_.TypeOf(expr->structure);
|
auto* structure = sem_.TypeOf(expr->structure);
|
||||||
auto* storage_ty = structure->UnwrapRef();
|
auto* storage_ty = structure->UnwrapRef();
|
||||||
auto* object = sem_.Get(expr->structure);
|
auto* object = sem_.Get(expr->structure);
|
||||||
auto* source_var = object->SourceVariable();
|
auto* root_ident = object->RootIdentifier();
|
||||||
|
|
||||||
const sem::Type* ty = nullptr;
|
const sem::Type* ty = nullptr;
|
||||||
|
|
||||||
|
@ -2404,7 +2404,7 @@ sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* e
|
||||||
}
|
}
|
||||||
return builder_->create<sem::StructMemberAccess>(expr, ty, current_statement_,
|
return builder_->create<sem::StructMemberAccess>(expr, ty, current_statement_,
|
||||||
val.Get(), object, member,
|
val.Get(), object, member,
|
||||||
has_side_effects, source_var);
|
has_side_effects, root_ident);
|
||||||
},
|
},
|
||||||
|
|
||||||
[&](const sem::Vector* vec) -> sem::Expression* {
|
[&](const sem::Vector* vec) -> sem::Expression* {
|
||||||
|
@ -2476,7 +2476,7 @@ sem::Expression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* e
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return builder_->create<sem::Swizzle>(expr, ty, current_statement_, val.Get(), object,
|
return builder_->create<sem::Swizzle>(expr, ty, current_statement_, val.Get(), object,
|
||||||
std::move(swizzle), has_side_effects, source_var);
|
std::move(swizzle), has_side_effects, root_ident);
|
||||||
},
|
},
|
||||||
|
|
||||||
[&](Default) {
|
[&](Default) {
|
||||||
|
@ -2549,7 +2549,7 @@ sem::Expression* Resolver::UnaryOp(const ast::UnaryOpExpression* unary) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Type* ty = nullptr;
|
const sem::Type* ty = nullptr;
|
||||||
const sem::Variable* source_var = nullptr;
|
const sem::Variable* root_ident = nullptr;
|
||||||
const sem::Constant* value = nullptr;
|
const sem::Constant* value = nullptr;
|
||||||
auto stage = sem::EvaluationStage::kRuntime;
|
auto stage = sem::EvaluationStage::kRuntime;
|
||||||
|
|
||||||
|
@ -2573,7 +2573,7 @@ sem::Expression* Resolver::UnaryOp(const ast::UnaryOpExpression* unary) {
|
||||||
ty = builder_->create<sem::Pointer>(ref->StoreType(), ref->AddressSpace(),
|
ty = builder_->create<sem::Pointer>(ref->StoreType(), ref->AddressSpace(),
|
||||||
ref->Access());
|
ref->Access());
|
||||||
|
|
||||||
source_var = expr->SourceVariable();
|
root_ident = expr->RootIdentifier();
|
||||||
} else {
|
} else {
|
||||||
AddError("cannot take the address of expression", unary->expr->source);
|
AddError("cannot take the address of expression", unary->expr->source);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -2584,7 +2584,7 @@ sem::Expression* Resolver::UnaryOp(const ast::UnaryOpExpression* unary) {
|
||||||
if (auto* ptr = expr_ty->As<sem::Pointer>()) {
|
if (auto* ptr = expr_ty->As<sem::Pointer>()) {
|
||||||
ty = builder_->create<sem::Reference>(ptr->StoreType(), ptr->AddressSpace(),
|
ty = builder_->create<sem::Reference>(ptr->StoreType(), ptr->AddressSpace(),
|
||||||
ptr->Access());
|
ptr->Access());
|
||||||
source_var = expr->SourceVariable();
|
root_ident = expr->RootIdentifier();
|
||||||
} else {
|
} else {
|
||||||
AddError("cannot dereference expression of type '" + sem_.TypeNameOf(expr_ty) + "'",
|
AddError("cannot dereference expression of type '" + sem_.TypeNameOf(expr_ty) + "'",
|
||||||
unary->expr->source);
|
unary->expr->source);
|
||||||
|
@ -2623,7 +2623,7 @@ sem::Expression* Resolver::UnaryOp(const ast::UnaryOpExpression* unary) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* sem = builder_->create<sem::Expression>(unary, ty, stage, current_statement_, value,
|
auto* sem = builder_->create<sem::Expression>(unary, ty, stage, current_statement_, value,
|
||||||
expr->HasSideEffects(), source_var);
|
expr->HasSideEffects(), root_ident);
|
||||||
sem->Behaviors() = expr->Behaviors();
|
sem->Behaviors() = expr->Behaviors();
|
||||||
return sem;
|
return sem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,9 @@ using namespace tint::number_suffixes; // NOLINT
|
||||||
namespace tint::resolver {
|
namespace tint::resolver {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class ResolverSourceVariableTest : public ResolverTest {};
|
class ResolverRootIdentifierTest : public ResolverTest {};
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, GlobalPrivateVar) {
|
TEST_F(ResolverRootIdentifierTest, GlobalPrivateVar) {
|
||||||
auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
|
auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
|
||||||
auto* expr = Expr(a);
|
auto* expr = Expr(a);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
@ -33,10 +33,10 @@ TEST_F(ResolverSourceVariableTest, GlobalPrivateVar) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, GlobalWorkgroupVar) {
|
TEST_F(ResolverRootIdentifierTest, GlobalWorkgroupVar) {
|
||||||
auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kWorkgroup);
|
auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kWorkgroup);
|
||||||
auto* expr = Expr(a);
|
auto* expr = Expr(a);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
@ -44,10 +44,10 @@ TEST_F(ResolverSourceVariableTest, GlobalWorkgroupVar) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, GlobalStorageVar) {
|
TEST_F(ResolverRootIdentifierTest, GlobalStorageVar) {
|
||||||
auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kStorage, Group(0_a), Binding(0_a));
|
auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kStorage, Group(0_a), Binding(0_a));
|
||||||
auto* expr = Expr(a);
|
auto* expr = Expr(a);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
@ -55,10 +55,10 @@ TEST_F(ResolverSourceVariableTest, GlobalStorageVar) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, GlobalUniformVar) {
|
TEST_F(ResolverRootIdentifierTest, GlobalUniformVar) {
|
||||||
auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
|
auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
|
||||||
auto* expr = Expr(a);
|
auto* expr = Expr(a);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
@ -66,10 +66,10 @@ TEST_F(ResolverSourceVariableTest, GlobalUniformVar) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, GlobalTextureVar) {
|
TEST_F(ResolverRootIdentifierTest, GlobalTextureVar) {
|
||||||
auto* a = GlobalVar("a", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
|
auto* a = GlobalVar("a", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
|
||||||
ast::AddressSpace::kNone, Group(0_a), Binding(0_a));
|
ast::AddressSpace::kNone, Group(0_a), Binding(0_a));
|
||||||
auto* expr = Expr(a);
|
auto* expr = Expr(a);
|
||||||
|
@ -78,10 +78,10 @@ TEST_F(ResolverSourceVariableTest, GlobalTextureVar) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, GlobalOverride) {
|
TEST_F(ResolverRootIdentifierTest, GlobalOverride) {
|
||||||
auto* a = Override("a", ty.f32(), Expr(1_f));
|
auto* a = Override("a", ty.f32(), Expr(1_f));
|
||||||
auto* expr = Expr(a);
|
auto* expr = Expr(a);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
@ -89,10 +89,10 @@ TEST_F(ResolverSourceVariableTest, GlobalOverride) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, GlobalConst) {
|
TEST_F(ResolverRootIdentifierTest, GlobalConst) {
|
||||||
auto* a = GlobalConst("a", ty.f32(), Expr(1_f));
|
auto* a = GlobalConst("a", ty.f32(), Expr(1_f));
|
||||||
auto* expr = Expr(a);
|
auto* expr = Expr(a);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
@ -100,10 +100,10 @@ TEST_F(ResolverSourceVariableTest, GlobalConst) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, FunctionVar) {
|
TEST_F(ResolverRootIdentifierTest, FunctionVar) {
|
||||||
auto* a = Var("a", ty.f32());
|
auto* a = Var("a", ty.f32());
|
||||||
auto* expr = Expr(a);
|
auto* expr = Expr(a);
|
||||||
WrapInFunction(a, expr);
|
WrapInFunction(a, expr);
|
||||||
|
@ -111,10 +111,10 @@ TEST_F(ResolverSourceVariableTest, FunctionVar) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, FunctionLet) {
|
TEST_F(ResolverRootIdentifierTest, FunctionLet) {
|
||||||
auto* a = Let("a", ty.f32(), Expr(1_f));
|
auto* a = Let("a", ty.f32(), Expr(1_f));
|
||||||
auto* expr = Expr(a);
|
auto* expr = Expr(a);
|
||||||
WrapInFunction(a, expr);
|
WrapInFunction(a, expr);
|
||||||
|
@ -122,10 +122,10 @@ TEST_F(ResolverSourceVariableTest, FunctionLet) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, Parameter) {
|
TEST_F(ResolverRootIdentifierTest, Parameter) {
|
||||||
auto* a = Param("a", ty.f32());
|
auto* a = Param("a", ty.f32());
|
||||||
auto* expr = Expr(a);
|
auto* expr = Expr(a);
|
||||||
Func("foo", utils::Vector{a}, ty.void_(), utils::Vector{WrapInStatement(expr)});
|
Func("foo", utils::Vector{a}, ty.void_(), utils::Vector{WrapInStatement(expr)});
|
||||||
|
@ -133,10 +133,10 @@ TEST_F(ResolverSourceVariableTest, Parameter) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, PointerParameter) {
|
TEST_F(ResolverRootIdentifierTest, PointerParameter) {
|
||||||
// fn foo(a : ptr<function, f32>)
|
// fn foo(a : ptr<function, f32>)
|
||||||
// {
|
// {
|
||||||
// let b = a;
|
// let b = a;
|
||||||
|
@ -151,11 +151,11 @@ TEST_F(ResolverSourceVariableTest, PointerParameter) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_param = Sem().Get(param);
|
auto* sem_param = Sem().Get(param);
|
||||||
EXPECT_EQ(Sem().Get(expr_param)->SourceVariable(), sem_param);
|
EXPECT_EQ(Sem().Get(expr_param)->RootIdentifier(), sem_param);
|
||||||
EXPECT_EQ(Sem().Get(expr_let)->SourceVariable(), sem_param);
|
EXPECT_EQ(Sem().Get(expr_let)->RootIdentifier(), sem_param);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, VarCopyVar) {
|
TEST_F(ResolverRootIdentifierTest, VarCopyVar) {
|
||||||
// {
|
// {
|
||||||
// var a : f32;
|
// var a : f32;
|
||||||
// var b = a;
|
// var b = a;
|
||||||
|
@ -170,11 +170,11 @@ TEST_F(ResolverSourceVariableTest, VarCopyVar) {
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
auto* sem_b = Sem().Get(b);
|
auto* sem_b = Sem().Get(b);
|
||||||
EXPECT_EQ(Sem().Get(expr_a)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr_a)->RootIdentifier(), sem_a);
|
||||||
EXPECT_EQ(Sem().Get(expr_b)->SourceVariable(), sem_b);
|
EXPECT_EQ(Sem().Get(expr_b)->RootIdentifier(), sem_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, LetCopyVar) {
|
TEST_F(ResolverRootIdentifierTest, LetCopyVar) {
|
||||||
// {
|
// {
|
||||||
// var a : f32;
|
// var a : f32;
|
||||||
// let b = a;
|
// let b = a;
|
||||||
|
@ -189,11 +189,11 @@ TEST_F(ResolverSourceVariableTest, LetCopyVar) {
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
auto* sem_b = Sem().Get(b);
|
auto* sem_b = Sem().Get(b);
|
||||||
EXPECT_EQ(Sem().Get(expr_a)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr_a)->RootIdentifier(), sem_a);
|
||||||
EXPECT_EQ(Sem().Get(expr_b)->SourceVariable(), sem_b);
|
EXPECT_EQ(Sem().Get(expr_b)->RootIdentifier(), sem_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, ThroughIndexAccessor) {
|
TEST_F(ResolverRootIdentifierTest, ThroughIndexAccessor) {
|
||||||
// var<private> a : array<f32, 4u>;
|
// var<private> a : array<f32, 4u>;
|
||||||
// {
|
// {
|
||||||
// a[2i]
|
// a[2i]
|
||||||
|
@ -205,10 +205,10 @@ TEST_F(ResolverSourceVariableTest, ThroughIndexAccessor) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, ThroughMemberAccessor) {
|
TEST_F(ResolverRootIdentifierTest, ThroughMemberAccessor) {
|
||||||
// struct S { f : f32 }
|
// struct S { f : f32 }
|
||||||
// var<private> a : S;
|
// var<private> a : S;
|
||||||
// {
|
// {
|
||||||
|
@ -222,10 +222,10 @@ TEST_F(ResolverSourceVariableTest, ThroughMemberAccessor) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, ThroughPointers) {
|
TEST_F(ResolverRootIdentifierTest, ThroughPointers) {
|
||||||
// var<private> a : f32;
|
// var<private> a : f32;
|
||||||
// {
|
// {
|
||||||
// let a_ptr1 = &*&a;
|
// let a_ptr1 = &*&a;
|
||||||
|
@ -244,49 +244,49 @@ TEST_F(ResolverSourceVariableTest, ThroughPointers) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* sem_a = Sem().Get(a);
|
auto* sem_a = Sem().Get(a);
|
||||||
EXPECT_EQ(Sem().Get(address_of_1)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(address_of_1)->RootIdentifier(), sem_a);
|
||||||
EXPECT_EQ(Sem().Get(address_of_2)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(address_of_2)->RootIdentifier(), sem_a);
|
||||||
EXPECT_EQ(Sem().Get(address_of_3)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(address_of_3)->RootIdentifier(), sem_a);
|
||||||
EXPECT_EQ(Sem().Get(deref_1)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(deref_1)->RootIdentifier(), sem_a);
|
||||||
EXPECT_EQ(Sem().Get(deref_2)->SourceVariable(), sem_a);
|
EXPECT_EQ(Sem().Get(deref_2)->RootIdentifier(), sem_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, Literal) {
|
TEST_F(ResolverRootIdentifierTest, Literal) {
|
||||||
auto* expr = Expr(1_f);
|
auto* expr = Expr(1_f);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), nullptr);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, FunctionReturnValue) {
|
TEST_F(ResolverRootIdentifierTest, FunctionReturnValue) {
|
||||||
auto* expr = Call("min", 1_f, 2_f);
|
auto* expr = Call("min", 1_f, 2_f);
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), nullptr);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, BinaryExpression) {
|
TEST_F(ResolverRootIdentifierTest, BinaryExpression) {
|
||||||
auto* a = Var("a", ty.f32());
|
auto* a = Var("a", ty.f32());
|
||||||
auto* expr = Add(a, Expr(1_f));
|
auto* expr = Add(a, Expr(1_f));
|
||||||
WrapInFunction(a, expr);
|
WrapInFunction(a, expr);
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), nullptr);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverSourceVariableTest, UnaryExpression) {
|
TEST_F(ResolverRootIdentifierTest, UnaryExpression) {
|
||||||
auto* a = Var("a", ty.f32());
|
auto* a = Var("a", ty.f32());
|
||||||
auto* expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr(a));
|
auto* expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr(a));
|
||||||
WrapInFunction(a, expr);
|
WrapInFunction(a, expr);
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
EXPECT_EQ(Sem().Get(expr)->SourceVariable(), nullptr);
|
EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
|
@ -1157,8 +1157,8 @@ class UniformityGraph {
|
||||||
if (u->op == ast::UnaryOp::kIndirection) {
|
if (u->op == ast::UnaryOp::kIndirection) {
|
||||||
// Cut the analysis short, since we only need to know the originating variable
|
// Cut the analysis short, since we only need to know the originating variable
|
||||||
// which is being accessed.
|
// which is being accessed.
|
||||||
auto* source_var = sem_.Get(u)->SourceVariable();
|
auto* root_ident = sem_.Get(u)->RootIdentifier();
|
||||||
auto* value = current_function_->variables.Get(source_var);
|
auto* value = current_function_->variables.Get(root_ident);
|
||||||
if (!value) {
|
if (!value) {
|
||||||
value = cf;
|
value = cf;
|
||||||
}
|
}
|
||||||
|
@ -1251,10 +1251,10 @@ class UniformityGraph {
|
||||||
if (u->op == ast::UnaryOp::kIndirection) {
|
if (u->op == ast::UnaryOp::kIndirection) {
|
||||||
// Cut the analysis short, since we only need to know the originating variable
|
// Cut the analysis short, since we only need to know the originating variable
|
||||||
// that is being written to.
|
// that is being written to.
|
||||||
auto* source_var = sem_.Get(u)->SourceVariable();
|
auto* root_ident = sem_.Get(u)->RootIdentifier();
|
||||||
auto name = builder_->Symbols().NameFor(source_var->Declaration()->symbol);
|
auto name = builder_->Symbols().NameFor(root_ident->Declaration()->symbol);
|
||||||
auto* deref = CreateNode(name + "_deref");
|
auto* deref = CreateNode(name + "_deref");
|
||||||
auto* old_value = current_function_->variables.Set(source_var, deref);
|
auto* old_value = current_function_->variables.Set(root_ident, deref);
|
||||||
|
|
||||||
if (old_value) {
|
if (old_value) {
|
||||||
// If derefercing a partial reference or partial pointer, we link back to
|
// If derefercing a partial reference or partial pointer, we link back to
|
||||||
|
@ -1405,9 +1405,9 @@ class UniformityGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the current stored value for this pointer argument.
|
// Update the current stored value for this pointer argument.
|
||||||
auto* source_var = sem_arg->SourceVariable();
|
auto* root_ident = sem_arg->RootIdentifier();
|
||||||
TINT_ASSERT(Resolver, source_var);
|
TINT_ASSERT(Resolver, root_ident);
|
||||||
current_function_->variables.Set(source_var, ptr_result);
|
current_function_->variables.Set(root_ident, ptr_result);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// All builtin function parameters are RequiredToBeUniformForReturnValue, as are
|
// All builtin function parameters are RequiredToBeUniformForReturnValue, as are
|
||||||
|
|
|
@ -28,9 +28,9 @@ Expression::Expression(const ast::Expression* declaration,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* source_var /* = nullptr */)
|
const Variable* root_ident /* = nullptr */)
|
||||||
: declaration_(declaration),
|
: declaration_(declaration),
|
||||||
source_variable_(source_var),
|
root_identifier_(root_ident),
|
||||||
type_(type),
|
type_(type),
|
||||||
stage_(stage),
|
stage_(stage),
|
||||||
statement_(statement),
|
statement_(statement),
|
||||||
|
|
|
@ -40,14 +40,14 @@ class Expression : public Castable<Expression, Node> {
|
||||||
/// @param statement the statement that owns this expression
|
/// @param statement the statement that owns this expression
|
||||||
/// @param constant the constant value of the expression. May be null
|
/// @param constant the constant value of the expression. May be null
|
||||||
/// @param has_side_effects true if this expression may have side-effects
|
/// @param has_side_effects true if this expression may have side-effects
|
||||||
/// @param source_var the (optional) source variable for this expression
|
/// @param root_ident the (optional) root identifier for this expression
|
||||||
Expression(const ast::Expression* declaration,
|
Expression(const ast::Expression* declaration,
|
||||||
const sem::Type* type,
|
const sem::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* source_var = nullptr);
|
const Variable* root_ident = nullptr);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Expression() override;
|
~Expression() override;
|
||||||
|
@ -71,8 +71,8 @@ class Expression : public Castable<Expression, Node> {
|
||||||
/// For reference and pointer expressions, this will either be the originating
|
/// For reference and pointer expressions, this will either be the originating
|
||||||
/// variable or a function parameter. For other types of expressions, it will
|
/// variable or a function parameter. For other types of expressions, it will
|
||||||
/// either be the parameter or constant declaration, or nullptr.
|
/// either be the parameter or constant declaration, or nullptr.
|
||||||
/// @return the source variable of this expression, or nullptr
|
/// @return the root identifier of this expression, or nullptr
|
||||||
const Variable* SourceVariable() const { return source_variable_; }
|
const Variable* RootIdentifier() const { return root_identifier_; }
|
||||||
|
|
||||||
/// @return the behaviors of this statement
|
/// @return the behaviors of this statement
|
||||||
const sem::Behaviors& Behaviors() const { return behaviors_; }
|
const sem::Behaviors& Behaviors() const { return behaviors_; }
|
||||||
|
@ -89,8 +89,8 @@ class Expression : public Castable<Expression, Node> {
|
||||||
protected:
|
protected:
|
||||||
/// The AST expression node for this semantic expression
|
/// The AST expression node for this semantic expression
|
||||||
const ast::Expression* const declaration_;
|
const ast::Expression* const declaration_;
|
||||||
/// The source variable for this semantic expression, or nullptr
|
/// The root identifier for this semantic expression, or nullptr
|
||||||
const Variable* source_variable_;
|
const Variable* root_identifier_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const sem::Type* const type_;
|
const sem::Type* const type_;
|
||||||
|
|
|
@ -46,7 +46,7 @@ TEST_F(ExpressionTest, UnwrapMaterialize) {
|
||||||
auto* a = create<Expression>(/* declaration */ nullptr, create<I32>(),
|
auto* a = create<Expression>(/* declaration */ nullptr, create<I32>(),
|
||||||
sem::EvaluationStage::kRuntime, /* statement */ nullptr,
|
sem::EvaluationStage::kRuntime, /* statement */ nullptr,
|
||||||
/* constant_value */ nullptr,
|
/* constant_value */ nullptr,
|
||||||
/* has_side_effects */ false, /* source_var */ nullptr);
|
/* has_side_effects */ false, /* root_ident */ nullptr);
|
||||||
auto* b = create<Materialize>(a, /* statement */ nullptr, &c);
|
auto* b = create<Materialize>(a, /* statement */ nullptr, &c);
|
||||||
|
|
||||||
EXPECT_EQ(a, a->UnwrapMaterialize());
|
EXPECT_EQ(a, a->UnwrapMaterialize());
|
||||||
|
|
|
@ -30,8 +30,8 @@ IndexAccessorExpression::IndexAccessorExpression(const ast::IndexAccessorExpress
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* source_var /* = nullptr */)
|
const Variable* root_ident /* = nullptr */)
|
||||||
: Base(declaration, type, stage, statement, constant, has_side_effects, source_var),
|
: Base(declaration, type, stage, statement, constant, has_side_effects, root_ident),
|
||||||
object_(object),
|
object_(object),
|
||||||
index_(index) {}
|
index_(index) {}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ class IndexAccessorExpression final : public Castable<IndexAccessorExpression, E
|
||||||
/// @param statement the statement that owns this expression
|
/// @param statement the statement that owns this expression
|
||||||
/// @param constant the constant value of the expression. May be null
|
/// @param constant the constant value of the expression. May be null
|
||||||
/// @param has_side_effects whether this expression may have side effects
|
/// @param has_side_effects whether this expression may have side effects
|
||||||
/// @param source_var the (optional) source variable for this expression
|
/// @param root_ident the (optional) root identifier for this expression
|
||||||
IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
|
IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
|
||||||
const sem::Type* type,
|
const sem::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
|
@ -47,7 +47,7 @@ class IndexAccessorExpression final : public Castable<IndexAccessorExpression, E
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* source_var = nullptr);
|
const Variable* root_ident = nullptr);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~IndexAccessorExpression() override;
|
~IndexAccessorExpression() override;
|
||||||
|
|
|
@ -26,7 +26,7 @@ Materialize::Materialize(const Expression* expr,
|
||||||
/* statement */ statement,
|
/* statement */ statement,
|
||||||
/* constant */ constant,
|
/* constant */ constant,
|
||||||
/* has_side_effects */ false,
|
/* has_side_effects */ false,
|
||||||
/* source_var */ expr->SourceVariable()),
|
/* root_ident */ expr->RootIdentifier()),
|
||||||
expr_(expr) {}
|
expr_(expr) {}
|
||||||
|
|
||||||
Materialize::~Materialize() = default;
|
Materialize::~Materialize() = default;
|
||||||
|
|
|
@ -30,8 +30,8 @@ MemberAccessorExpression::MemberAccessorExpression(const ast::MemberAccessorExpr
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
const Expression* object,
|
const Expression* object,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* source_var /* = nullptr */)
|
const Variable* root_ident /* = nullptr */)
|
||||||
: Base(declaration, type, stage, statement, constant, has_side_effects, source_var),
|
: Base(declaration, type, stage, statement, constant, has_side_effects, root_ident),
|
||||||
object_(object) {}
|
object_(object) {}
|
||||||
|
|
||||||
MemberAccessorExpression::~MemberAccessorExpression() = default;
|
MemberAccessorExpression::~MemberAccessorExpression() = default;
|
||||||
|
@ -43,7 +43,7 @@ StructMemberAccess::StructMemberAccess(const ast::MemberAccessorExpression* decl
|
||||||
const Expression* object,
|
const Expression* object,
|
||||||
const StructMember* member,
|
const StructMember* member,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* source_var /* = nullptr */)
|
const Variable* root_ident /* = nullptr */)
|
||||||
: Base(declaration,
|
: Base(declaration,
|
||||||
type,
|
type,
|
||||||
object->Stage(),
|
object->Stage(),
|
||||||
|
@ -51,7 +51,7 @@ StructMemberAccess::StructMemberAccess(const ast::MemberAccessorExpression* decl
|
||||||
constant,
|
constant,
|
||||||
object,
|
object,
|
||||||
has_side_effects,
|
has_side_effects,
|
||||||
source_var),
|
root_ident),
|
||||||
member_(member) {}
|
member_(member) {}
|
||||||
|
|
||||||
StructMemberAccess::~StructMemberAccess() = default;
|
StructMemberAccess::~StructMemberAccess() = default;
|
||||||
|
@ -63,7 +63,7 @@ Swizzle::Swizzle(const ast::MemberAccessorExpression* declaration,
|
||||||
const Expression* object,
|
const Expression* object,
|
||||||
utils::VectorRef<uint32_t> indices,
|
utils::VectorRef<uint32_t> indices,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* source_var /* = nullptr */)
|
const Variable* root_ident /* = nullptr */)
|
||||||
: Base(declaration,
|
: Base(declaration,
|
||||||
type,
|
type,
|
||||||
object->Stage(),
|
object->Stage(),
|
||||||
|
@ -71,7 +71,7 @@ Swizzle::Swizzle(const ast::MemberAccessorExpression* declaration,
|
||||||
constant,
|
constant,
|
||||||
object,
|
object,
|
||||||
has_side_effects,
|
has_side_effects,
|
||||||
source_var),
|
root_ident),
|
||||||
indices_(std::move(indices)) {}
|
indices_(std::move(indices)) {}
|
||||||
|
|
||||||
Swizzle::~Swizzle() = default;
|
Swizzle::~Swizzle() = default;
|
||||||
|
|
|
@ -48,7 +48,7 @@ class MemberAccessorExpression : public Castable<MemberAccessorExpression, Expre
|
||||||
/// @param constant the constant value of the expression. May be null.
|
/// @param constant the constant value of the expression. May be null.
|
||||||
/// @param object the object that holds the member being accessed
|
/// @param object the object that holds the member being accessed
|
||||||
/// @param has_side_effects whether this expression may have side effects
|
/// @param has_side_effects whether this expression may have side effects
|
||||||
/// @param source_var the (optional) source variable for this expression
|
/// @param root_ident the (optional) root identifier for this expression
|
||||||
MemberAccessorExpression(const ast::MemberAccessorExpression* declaration,
|
MemberAccessorExpression(const ast::MemberAccessorExpression* declaration,
|
||||||
const sem::Type* type,
|
const sem::Type* type,
|
||||||
EvaluationStage stage,
|
EvaluationStage stage,
|
||||||
|
@ -56,7 +56,7 @@ class MemberAccessorExpression : public Castable<MemberAccessorExpression, Expre
|
||||||
const Constant* constant,
|
const Constant* constant,
|
||||||
const Expression* object,
|
const Expression* object,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* source_var = nullptr);
|
const Variable* root_ident = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Expression const* const object_;
|
Expression const* const object_;
|
||||||
|
@ -75,7 +75,7 @@ class StructMemberAccess final : public Castable<StructMemberAccess, MemberAcces
|
||||||
/// @param object the object that holds the member being accessed
|
/// @param object the object that holds the member being accessed
|
||||||
/// @param member the structure member
|
/// @param member the structure member
|
||||||
/// @param has_side_effects whether this expression may have side effects
|
/// @param has_side_effects whether this expression may have side effects
|
||||||
/// @param source_var the (optional) source variable for this expression
|
/// @param root_ident the (optional) root identifier for this expression
|
||||||
StructMemberAccess(const ast::MemberAccessorExpression* declaration,
|
StructMemberAccess(const ast::MemberAccessorExpression* declaration,
|
||||||
const sem::Type* type,
|
const sem::Type* type,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
|
@ -83,7 +83,7 @@ class StructMemberAccess final : public Castable<StructMemberAccess, MemberAcces
|
||||||
const Expression* object,
|
const Expression* object,
|
||||||
const StructMember* member,
|
const StructMember* member,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* source_var = nullptr);
|
const Variable* root_ident = nullptr);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~StructMemberAccess() override;
|
~StructMemberAccess() override;
|
||||||
|
@ -107,7 +107,7 @@ class Swizzle final : public Castable<Swizzle, MemberAccessorExpression> {
|
||||||
/// @param object the object that holds the member being accessed
|
/// @param object the object that holds the member being accessed
|
||||||
/// @param indices the swizzle indices
|
/// @param indices the swizzle indices
|
||||||
/// @param has_side_effects whether this expression may have side effects
|
/// @param has_side_effects whether this expression may have side effects
|
||||||
/// @param source_var the (optional) source variable for this expression
|
/// @param root_ident the (optional) root identifier for this expression
|
||||||
Swizzle(const ast::MemberAccessorExpression* declaration,
|
Swizzle(const ast::MemberAccessorExpression* declaration,
|
||||||
const sem::Type* type,
|
const sem::Type* type,
|
||||||
const Statement* statement,
|
const Statement* statement,
|
||||||
|
@ -115,7 +115,7 @@ class Swizzle final : public Castable<Swizzle, MemberAccessorExpression> {
|
||||||
const Expression* object,
|
const Expression* object,
|
||||||
utils::VectorRef<uint32_t> indices,
|
utils::VectorRef<uint32_t> indices,
|
||||||
bool has_side_effects,
|
bool has_side_effects,
|
||||||
const Variable* source_var = nullptr);
|
const Variable* root_ident = nullptr);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Swizzle() override;
|
~Swizzle() override;
|
||||||
|
|
|
@ -97,9 +97,9 @@ VariableUser::VariableUser(const ast::IdentifierExpression* declaration,
|
||||||
variable_(variable) {
|
variable_(variable) {
|
||||||
auto* type = variable->Type();
|
auto* type = variable->Type();
|
||||||
if (type->Is<sem::Pointer>() && variable->Initializer()) {
|
if (type->Is<sem::Pointer>() && variable->Initializer()) {
|
||||||
source_variable_ = variable->Initializer()->SourceVariable();
|
root_identifier_ = variable->Initializer()->RootIdentifier();
|
||||||
} else {
|
} else {
|
||||||
source_variable_ = variable;
|
root_identifier_ = variable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -174,15 +174,15 @@ struct LocalizeStructArrayAssignment::State {
|
||||||
// See https://www.w3.org/TR/WGSL/#originating-variable-section
|
// See https://www.w3.org/TR/WGSL/#originating-variable-section
|
||||||
std::pair<const sem::Type*, ast::AddressSpace> GetOriginatingTypeAndAddressSpace(
|
std::pair<const sem::Type*, ast::AddressSpace> GetOriginatingTypeAndAddressSpace(
|
||||||
const ast::AssignmentStatement* assign_stmt) {
|
const ast::AssignmentStatement* assign_stmt) {
|
||||||
auto* source_var = src->Sem().Get(assign_stmt->lhs)->SourceVariable();
|
auto* root_ident = src->Sem().Get(assign_stmt->lhs)->RootIdentifier();
|
||||||
if (!source_var) {
|
if (!root_ident) {
|
||||||
TINT_ICE(Transform, b.Diagnostics())
|
TINT_ICE(Transform, b.Diagnostics())
|
||||||
<< "Unable to determine originating variable for lhs of assignment "
|
<< "Unable to determine originating variable for lhs of assignment "
|
||||||
"statement";
|
"statement";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* type = source_var->Type();
|
auto* type = root_ident->Type();
|
||||||
if (auto* ref = type->As<sem::Reference>()) {
|
if (auto* ref = type->As<sem::Reference>()) {
|
||||||
return {ref->StoreType(), ref->AddressSpace()};
|
return {ref->StoreType(), ref->AddressSpace()};
|
||||||
} else if (auto* ptr = type->As<sem::Pointer>()) {
|
} else if (auto* ptr = type->As<sem::Pointer>()) {
|
||||||
|
|
|
@ -97,7 +97,7 @@ struct SpirvAtomic::State {
|
||||||
b.Call(sem::str(stub->builtin), std::move(out_args)));
|
b.Call(sem::str(stub->builtin), std::move(out_args)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep track of this expression. We'll need to modify the source variable /
|
// Keep track of this expression. We'll need to modify the root identifier /
|
||||||
// structure to be atomic.
|
// structure to be atomic.
|
||||||
atomic_expressions.Add(ctx.src->Sem().Get(args[0]));
|
atomic_expressions.Add(ctx.src->Sem().Get(args[0]));
|
||||||
}
|
}
|
||||||
|
@ -230,8 +230,8 @@ struct SpirvAtomic::State {
|
||||||
void ReplaceLoadsAndStores() {
|
void ReplaceLoadsAndStores() {
|
||||||
// Returns true if 'e' is a reference to an atomic variable or struct member
|
// Returns true if 'e' is a reference to an atomic variable or struct member
|
||||||
auto is_ref_to_atomic_var = [&](const sem::Expression* e) {
|
auto is_ref_to_atomic_var = [&](const sem::Expression* e) {
|
||||||
if (tint::Is<sem::Reference>(e->Type()) && e->SourceVariable() &&
|
if (tint::Is<sem::Reference>(e->Type()) && e->RootIdentifier() &&
|
||||||
(atomic_variables.count(e->SourceVariable()) != 0)) {
|
(atomic_variables.count(e->RootIdentifier()) != 0)) {
|
||||||
// If it's a struct member, make sure it's one we marked as atomic
|
// If it's a struct member, make sure it's one we marked as atomic
|
||||||
if (auto* ma = e->As<sem::StructMemberAccess>()) {
|
if (auto* ma = e->As<sem::StructMemberAccess>()) {
|
||||||
auto it = forked_structs.find(ma->Member()->Struct()->Declaration());
|
auto it = forked_structs.find(ma->Member()->Struct()->Declaration());
|
||||||
|
|
|
@ -498,26 +498,26 @@ struct Std140::State {
|
||||||
|
|
||||||
AccessChain access;
|
AccessChain access;
|
||||||
|
|
||||||
// Start by looking at the source variable. This must be a std140-forked uniform buffer.
|
// Start by looking at the root identifier. This must be a std140-forked uniform buffer.
|
||||||
access.var = tint::As<sem::GlobalVariable>(expr->SourceVariable());
|
access.var = tint::As<sem::GlobalVariable>(expr->RootIdentifier());
|
||||||
if (!access.var || !std140_uniforms.Contains(access.var)) {
|
if (!access.var || !std140_uniforms.Contains(access.var)) {
|
||||||
// Not at std140-forked uniform buffer access chain.
|
// Not at std140-forked uniform buffer access chain.
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk from the outer-most expression, inwards towards the source variable.
|
// Walk from the outer-most expression, inwards towards the root identifier.
|
||||||
while (true) {
|
while (true) {
|
||||||
enum class Action { kStop, kContinue, kError };
|
enum class Action { kStop, kContinue, kError };
|
||||||
Action action = Switch(
|
Action action = Switch(
|
||||||
expr, //
|
expr, //
|
||||||
[&](const sem::VariableUser* user) {
|
[&](const sem::VariableUser* user) {
|
||||||
if (user->Variable() == access.var) {
|
if (user->Variable() == access.var) {
|
||||||
// Walked all the way to the source variable. We're done traversing.
|
// Walked all the way to the root identifier. We're done traversing.
|
||||||
access.indices.Push(UniformVariable{});
|
access.indices.Push(UniformVariable{});
|
||||||
return Action::kStop;
|
return Action::kStop;
|
||||||
}
|
}
|
||||||
if (user->Variable()->Type()->Is<sem::Pointer>()) {
|
if (user->Variable()->Type()->Is<sem::Pointer>()) {
|
||||||
// Found a pointer. As the source variable is a uniform buffer variable,
|
// Found a pointer. As the root identifier is a uniform buffer variable,
|
||||||
// this must be a pointer-let. Continue traversing from the let
|
// this must be a pointer-let. Continue traversing from the let
|
||||||
// initializer.
|
// initializer.
|
||||||
expr = user->Variable()->Initializer();
|
expr = user->Variable()->Initializer();
|
||||||
|
|
Loading…
Reference in New Issue