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:
parent
af8a8ac3d6
commit
a864f24c6f
|
@ -45,6 +45,19 @@ Variable::Variable(Variable&&) = default;
|
||||||
|
|
||||||
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 {
|
bool Variable::HasLocationDecoration() const {
|
||||||
for (auto* deco : decorations_) {
|
for (auto* deco : decorations_) {
|
||||||
if (deco->Is<LocationDecoration>()) {
|
if (deco->Is<LocationDecoration>()) {
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
|
class BindingDecoration;
|
||||||
|
class GroupDecoration;
|
||||||
class LocationDecoration;
|
class LocationDecoration;
|
||||||
|
|
||||||
/// A Variable statement.
|
/// A Variable statement.
|
||||||
|
@ -76,6 +78,18 @@ class LocationDecoration;
|
||||||
/// The storage class for a formal parameter is always StorageClass::kNone.
|
/// The storage class for a formal parameter is always StorageClass::kNone.
|
||||||
class Variable : public Castable<Variable, Node> {
|
class Variable : public Castable<Variable, Node> {
|
||||||
public:
|
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
|
/// Create a variable
|
||||||
/// @param source the variable source
|
/// @param source the variable source
|
||||||
/// @param sym the variable symbol
|
/// @param sym the variable symbol
|
||||||
|
@ -117,6 +131,9 @@ class Variable : public Castable<Variable, Node> {
|
||||||
/// @returns the decorations attached to this variable
|
/// @returns the decorations attached to this variable
|
||||||
const DecorationList& decorations() const { return decorations_; }
|
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
|
/// @returns true if the decorations include a LocationDecoration
|
||||||
bool HasLocationDecoration() const;
|
bool HasLocationDecoration() const;
|
||||||
/// @returns true if the decorations include a BuiltinDecoration
|
/// @returns true if the decorations include a BuiltinDecoration
|
||||||
|
|
|
@ -107,6 +107,47 @@ TEST_F(VariableTest, WithDecorations) {
|
||||||
EXPECT_EQ(1u, location->value());
|
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) {
|
TEST_F(VariableTest, ConstantId) {
|
||||||
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, nullptr,
|
||||||
DecorationList{
|
DecorationList{
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/ast/variable.h"
|
||||||
#include "src/semantic/call_target.h"
|
#include "src/semantic/call_target.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -39,16 +40,9 @@ class Variable;
|
||||||
/// Function holds the semantic information for function nodes.
|
/// Function holds the semantic information for function nodes.
|
||||||
class Function : public Castable<Function, CallTarget> {
|
class Function : public Castable<Function, CallTarget> {
|
||||||
public:
|
public:
|
||||||
/// Information about a binding
|
/// A vector of [Variable*, ast::Variable::BindingPoint] pairs
|
||||||
struct BindingInfo {
|
using VariableBindings =
|
||||||
/// The binding decoration
|
std::vector<std::pair<const Variable*, ast::Variable::BindingPoint>>;
|
||||||
ast::BindingDecoration* binding = nullptr;
|
|
||||||
/// The group decoration
|
|
||||||
ast::GroupDecoration* group = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A vector of [Variable*, BindingInfo] pairs
|
|
||||||
using VariableBindings = std::vector<std::pair<const Variable*, BindingInfo>>;
|
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param declaration the ast::Function
|
/// @param declaration the ast::Function
|
||||||
|
|
|
@ -38,21 +38,6 @@ ParameterList GetParameters(ast::Function* ast) {
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<ast::BindingDecoration*, ast::GroupDecoration*> GetBindingAndGroup(
|
|
||||||
const Variable* var) {
|
|
||||||
ast::BindingDecoration* binding = nullptr;
|
|
||||||
ast::GroupDecoration* group = nullptr;
|
|
||||||
for (auto* deco : var->Declaration()->decorations()) {
|
|
||||||
if (auto* b = deco->As<ast::BindingDecoration>()) {
|
|
||||||
binding = b;
|
|
||||||
}
|
|
||||||
if (auto* s = deco->As<ast::GroupDecoration>()) {
|
|
||||||
group = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {binding, group};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Function::Function(ast::Function* declaration,
|
Function::Function(ast::Function* declaration,
|
||||||
|
@ -92,14 +77,9 @@ Function::VariableBindings Function::ReferencedUniformVariables() const {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::BindingDecoration* binding = nullptr;
|
if (auto binding_point = var->Declaration()->binding_point()) {
|
||||||
ast::GroupDecoration* group = nullptr;
|
ret.push_back({var, binding_point});
|
||||||
std::tie(binding, group) = GetBindingAndGroup(var);
|
|
||||||
if (binding == nullptr || group == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.push_back({var, BindingInfo{binding, group}});
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -112,14 +92,9 @@ Function::VariableBindings Function::ReferencedStorageBufferVariables() const {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::BindingDecoration* binding = nullptr;
|
if (auto binding_point = var->Declaration()->binding_point()) {
|
||||||
ast::GroupDecoration* group = nullptr;
|
ret.push_back({var, binding_point});
|
||||||
std::tie(binding, group) = GetBindingAndGroup(var);
|
|
||||||
if (binding == nullptr || group == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.push_back({var, BindingInfo{binding, group}});
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -168,14 +143,9 @@ Function::VariableBindings Function::ReferencedStorageTextureVariables() const {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::BindingDecoration* binding = nullptr;
|
if (auto binding_point = var->Declaration()->binding_point()) {
|
||||||
ast::GroupDecoration* group = nullptr;
|
ret.push_back({var, binding_point});
|
||||||
std::tie(binding, group) = GetBindingAndGroup(var);
|
|
||||||
if (binding == nullptr || group == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.push_back({var, BindingInfo{binding, group}});
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -191,14 +161,9 @@ Function::VariableBindings Function::ReferencedDepthTextureVariables() const {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::BindingDecoration* binding = nullptr;
|
if (auto binding_point = var->Declaration()->binding_point()) {
|
||||||
ast::GroupDecoration* group = nullptr;
|
ret.push_back({var, binding_point});
|
||||||
std::tie(binding, group) = GetBindingAndGroup(var);
|
|
||||||
if (binding == nullptr || group == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.push_back({var, BindingInfo{binding, group}});
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -239,14 +204,9 @@ Function::VariableBindings Function::ReferencedSamplerVariablesImpl(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::BindingDecoration* binding = nullptr;
|
if (auto binding_point = var->Declaration()->binding_point()) {
|
||||||
ast::GroupDecoration* group = nullptr;
|
ret.push_back({var, binding_point});
|
||||||
std::tie(binding, group) = GetBindingAndGroup(var);
|
|
||||||
if (binding == nullptr || group == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.push_back({var, BindingInfo{binding, group}});
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -270,14 +230,9 @@ Function::VariableBindings Function::ReferencedSampledTextureVariablesImpl(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::BindingDecoration* binding = nullptr;
|
if (auto binding_point = var->Declaration()->binding_point()) {
|
||||||
ast::GroupDecoration* group = nullptr;
|
ret.push_back({var, binding_point});
|
||||||
std::tie(binding, group) = GetBindingAndGroup(var);
|
|
||||||
if (binding == nullptr || group == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.push_back({var, BindingInfo{binding, group}});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue