Store location value into `sem::Function`.
This CL adds an optional location value to the `sem::Function` which will store the resolved `@location` value. Bug: tint:1633 Change-Id: I95130858d8a1cecae1389be74120da29fec2b448 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/101063 Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Dan Sinclair <dsinclair@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
c8278e5cbd
commit
766a458f53
|
@ -906,6 +906,19 @@ sem::Function* Resolver::Function(const ast::Function* decl) {
|
||||||
return_type = builder_->create<sem::Void>();
|
return_type = builder_->create<sem::Void>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine if the return type has a location
|
||||||
|
std::optional<uint32_t> return_location;
|
||||||
|
for (auto* attr : decl->return_type_attributes) {
|
||||||
|
Mark(attr);
|
||||||
|
|
||||||
|
if (auto* a = attr->As<ast::LocationAttribute>()) {
|
||||||
|
return_location = a->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!validator_.NoDuplicateAttributes(decl->attributes)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (auto* str = return_type->As<sem::Struct>()) {
|
if (auto* str = return_type->As<sem::Struct>()) {
|
||||||
if (!ApplyStorageClassUsageToType(ast::StorageClass::kNone, str, decl->source)) {
|
if (!ApplyStorageClassUsageToType(ast::StorageClass::kNone, str, decl->source)) {
|
||||||
AddNote(
|
AddNote(
|
||||||
|
@ -929,7 +942,8 @@ sem::Function* Resolver::Function(const ast::Function* decl) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* func = builder_->create<sem::Function>(decl, return_type, std::move(parameters));
|
auto* func =
|
||||||
|
builder_->create<sem::Function>(decl, return_type, return_location, std::move(parameters));
|
||||||
builder_->Sem().Add(decl, func);
|
builder_->Sem().Add(decl, func);
|
||||||
|
|
||||||
TINT_SCOPED_ASSIGNMENT(current_function_, func);
|
TINT_SCOPED_ASSIGNMENT(current_function_, func);
|
||||||
|
@ -968,13 +982,7 @@ sem::Function* Resolver::Function(const ast::Function* decl) {
|
||||||
for (auto* attr : decl->attributes) {
|
for (auto* attr : decl->attributes) {
|
||||||
Mark(attr);
|
Mark(attr);
|
||||||
}
|
}
|
||||||
if (!validator_.NoDuplicateAttributes(decl->attributes)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto* attr : decl->return_type_attributes) {
|
|
||||||
Mark(attr);
|
|
||||||
}
|
|
||||||
if (!validator_.NoDuplicateAttributes(decl->return_type_attributes)) {
|
if (!validator_.NoDuplicateAttributes(decl->return_type_attributes)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -802,6 +802,45 @@ TEST_F(ResolverTest, Function_RegisterInputOutputVariables) {
|
||||||
EXPECT_EQ(vars[2]->Declaration(), priv_var);
|
EXPECT_EQ(vars[2]->Declaration(), priv_var);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverTest, Function_ReturnType_Location) {
|
||||||
|
auto* func = Func("my_func", utils::Empty, ty.f32(),
|
||||||
|
utils::Vector{
|
||||||
|
Return(1_f),
|
||||||
|
},
|
||||||
|
utils::Vector{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
utils::Vector{
|
||||||
|
Location(2),
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
auto* sem = Sem().Get(func);
|
||||||
|
ASSERT_NE(nullptr, sem);
|
||||||
|
EXPECT_EQ(2u, sem->ReturnLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverTest, Function_ReturnType_NoLocation) {
|
||||||
|
GlobalVar("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
|
||||||
|
auto* func = Func("my_func", utils::Empty, ty.vec4<f32>(),
|
||||||
|
utils::Vector{
|
||||||
|
Return("my_vec"),
|
||||||
|
},
|
||||||
|
utils::Vector{
|
||||||
|
Stage(ast::PipelineStage::kVertex),
|
||||||
|
},
|
||||||
|
utils::Vector{
|
||||||
|
Builtin(ast::BuiltinValue::kPosition),
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
auto* sem = Sem().Get(func);
|
||||||
|
ASSERT_NE(nullptr, sem);
|
||||||
|
EXPECT_FALSE(sem->ReturnLocation());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) {
|
TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) {
|
||||||
auto* s = Structure("S", utils::Vector{Member("m", ty.u32())});
|
auto* s = Structure("S", utils::Vector{Member("m", ty.u32())});
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,12 @@ utils::VectorRef<const Parameter*> SetOwner(utils::VectorRef<Parameter*> paramet
|
||||||
|
|
||||||
Function::Function(const ast::Function* declaration,
|
Function::Function(const ast::Function* declaration,
|
||||||
Type* return_type,
|
Type* return_type,
|
||||||
|
std::optional<uint32_t> return_location,
|
||||||
utils::VectorRef<Parameter*> parameters)
|
utils::VectorRef<Parameter*> parameters)
|
||||||
: Base(return_type, SetOwner(std::move(parameters), this), EvaluationStage::kRuntime),
|
: Base(return_type, SetOwner(std::move(parameters), this), EvaluationStage::kRuntime),
|
||||||
declaration_(declaration),
|
declaration_(declaration),
|
||||||
workgroup_size_{WorkgroupDimension{1}, WorkgroupDimension{1}, WorkgroupDimension{1}} {}
|
workgroup_size_{WorkgroupDimension{1}, WorkgroupDimension{1}, WorkgroupDimension{1}},
|
||||||
|
return_location_(return_location) {}
|
||||||
|
|
||||||
Function::~Function() = default;
|
Function::~Function() = default;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#define SRC_TINT_SEM_FUNCTION_H_
|
#define SRC_TINT_SEM_FUNCTION_H_
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <optional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -60,9 +61,11 @@ class Function final : public Castable<Function, CallTarget> {
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param declaration the ast::Function
|
/// @param declaration the ast::Function
|
||||||
/// @param return_type the return type of the function
|
/// @param return_type the return type of the function
|
||||||
|
/// @param return_location the location value for the return, if provided
|
||||||
/// @param parameters the parameters to the function
|
/// @param parameters the parameters to the function
|
||||||
Function(const ast::Function* declaration,
|
Function(const ast::Function* declaration,
|
||||||
Type* return_type,
|
Type* return_type,
|
||||||
|
std::optional<uint32_t> return_location,
|
||||||
utils::VectorRef<Parameter*> parameters);
|
utils::VectorRef<Parameter*> parameters);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
|
@ -254,6 +257,9 @@ class Function final : public Castable<Function, CallTarget> {
|
||||||
/// @return the behaviors of this function
|
/// @return the behaviors of this function
|
||||||
sem::Behaviors& Behaviors() { return behaviors_; }
|
sem::Behaviors& Behaviors() { return behaviors_; }
|
||||||
|
|
||||||
|
/// @return the location for the return, if provided
|
||||||
|
std::optional<uint32_t> ReturnLocation() const { return return_location_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Function(const Function&) = delete;
|
Function(const Function&) = delete;
|
||||||
Function(Function&&) = delete;
|
Function(Function&&) = delete;
|
||||||
|
@ -274,6 +280,8 @@ class Function final : public Castable<Function, CallTarget> {
|
||||||
std::vector<const Function*> ancestor_entry_points_;
|
std::vector<const Function*> ancestor_entry_points_;
|
||||||
bool has_discard_ = false;
|
bool has_discard_ = false;
|
||||||
sem::Behaviors behaviors_{sem::Behavior::kNext};
|
sem::Behaviors behaviors_{sem::Behavior::kNext};
|
||||||
|
|
||||||
|
std::optional<uint32_t> return_location_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
|
Loading…
Reference in New Issue