Add ast::Variable::BindingPoint

Use this to simplify a bunch of code in semantic::Function.

Change-Id: Ia3f8a270ec576660eab00bcfa4df9a96138bd31e
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/46261
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
Ben Clayton
2021-03-29 21:21:35 +00:00
committed by Commit Bot service account
parent af8a8ac3d6
commit a864f24c6f
5 changed files with 87 additions and 67 deletions

View File

@@ -45,6 +45,19 @@ Variable::Variable(Variable&&) = default;
Variable::~Variable() = default;
Variable::BindingPoint Variable::binding_point() const {
GroupDecoration* group = nullptr;
BindingDecoration* binding = nullptr;
for (auto* deco : decorations()) {
if (auto* g = deco->As<GroupDecoration>()) {
group = g;
} else if (auto* b = deco->As<BindingDecoration>()) {
binding = b;
}
}
return BindingPoint{group, binding};
}
bool Variable::HasLocationDecoration() const {
for (auto* deco : decorations_) {
if (deco->Is<LocationDecoration>()) {

View File

@@ -25,6 +25,8 @@
namespace tint {
namespace ast {
class BindingDecoration;
class GroupDecoration;
class LocationDecoration;
/// A Variable statement.
@@ -76,6 +78,18 @@ class LocationDecoration;
/// The storage class for a formal parameter is always StorageClass::kNone.
class Variable : public Castable<Variable, Node> {
public:
/// BindingPoint holds a group and binding decoration.
struct BindingPoint {
/// The `[[group]]` part of the binding point
GroupDecoration* group = nullptr;
/// The `[[binding]]` part of the binding point
BindingDecoration* binding = nullptr;
/// @returns true if the BindingPoint has a valid group and binding
/// decoration.
inline operator bool() const { return group && binding; }
};
/// Create a variable
/// @param source the variable source
/// @param sym the variable symbol
@@ -117,6 +131,9 @@ class Variable : public Castable<Variable, Node> {
/// @returns the decorations attached to this variable
const DecorationList& decorations() const { return decorations_; }
/// @returns the binding point information for the variable
BindingPoint binding_point() const;
/// @returns true if the decorations include a LocationDecoration
bool HasLocationDecoration() const;
/// @returns true if the decorations include a BuiltinDecoration

View File

@@ -107,6 +107,47 @@ TEST_F(VariableTest, WithDecorations) {
EXPECT_EQ(1u, location->value());
}
TEST_F(VariableTest, BindingPoint) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
DecorationList{
create<BindingDecoration>(2),
create<GroupDecoration>(1),
});
EXPECT_TRUE(var->binding_point());
ASSERT_NE(var->binding_point().binding, nullptr);
ASSERT_NE(var->binding_point().group, nullptr);
EXPECT_EQ(var->binding_point().binding->value(), 2u);
EXPECT_EQ(var->binding_point().group->value(), 1u);
}
TEST_F(VariableTest, BindingPointoDecorations) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
DecorationList{});
EXPECT_FALSE(var->binding_point());
EXPECT_EQ(var->binding_point().group, nullptr);
EXPECT_EQ(var->binding_point().binding, nullptr);
}
TEST_F(VariableTest, BindingPointMissingGroupDecoration) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
DecorationList{
create<BindingDecoration>(2),
});
EXPECT_FALSE(var->binding_point());
ASSERT_NE(var->binding_point().binding, nullptr);
EXPECT_EQ(var->binding_point().binding->value(), 2u);
EXPECT_EQ(var->binding_point().group, nullptr);
}
TEST_F(VariableTest, BindingPointMissingBindingDecoration) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
DecorationList{create<GroupDecoration>(1)});
EXPECT_FALSE(var->binding_point());
ASSERT_NE(var->binding_point().group, nullptr);
EXPECT_EQ(var->binding_point().group->value(), 1u);
EXPECT_EQ(var->binding_point().binding, nullptr);
}
TEST_F(VariableTest, ConstantId) {
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
DecorationList{