validator: Validate attributes on non-entry point functions
Also validate that workgroup_size is only applied to compute stages,
and not duplicated.
Fixed: tint:703
Change-Id: I02f4ddea305cad25ee0a99e13dc9e7fd1d5dc3ea
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/51120
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Auto-Submit: James Price <jrprice@google.com>
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index d5166d9..145bdc0 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -823,6 +823,38 @@
return false;
}
+ auto stage_deco_count = 0;
+ auto workgroup_deco_count = 0;
+ for (auto* deco : func->decorations()) {
+ if (deco->Is<ast::StageDecoration>()) {
+ stage_deco_count++;
+ } else if (deco->Is<ast::WorkgroupDecoration>()) {
+ workgroup_deco_count++;
+ if (func->pipeline_stage() != ast::PipelineStage::kCompute) {
+ diagnostics_.add_error(
+ "the workgroup_size attribute is only valid for compute stages",
+ deco->source());
+ return false;
+ }
+ } else if (!deco->Is<ast::InternalDecoration>()) {
+ diagnostics_.add_error("decoration is not valid for functions",
+ deco->source());
+ return false;
+ }
+ }
+ if (stage_deco_count > 1) {
+ diagnostics_.add_error(
+ "v-0020", "only one stage decoration permitted per entry point",
+ func->source());
+ return false;
+ }
+ if (workgroup_deco_count > 1) {
+ diagnostics_.add_error(
+ "only one workgroup_size attribute permitted per entry point",
+ func->source());
+ return false;
+ }
+
for (auto* param : func->params()) {
if (!ValidateParameter(variable_to_info_.at(param))) {
return false;
@@ -867,23 +899,6 @@
bool Resolver::ValidateEntryPoint(const ast::Function* func,
const FunctionInfo* info) {
- auto stage_deco_count = 0;
- for (auto* deco : func->decorations()) {
- if (deco->Is<ast::StageDecoration>()) {
- stage_deco_count++;
- } else if (!deco->Is<ast::WorkgroupDecoration>()) {
- diagnostics_.add_error("decoration is not valid for functions",
- deco->source());
- return false;
- }
- }
- if (stage_deco_count > 1) {
- diagnostics_.add_error(
- "v-0020", "only one stage decoration permitted per entry point",
- func->source());
- return false;
- }
-
// Use a lambda to validate the entry point decorations for a type.
// Persistent state is used to track which builtins and locations have already
// been seen, in order to catch conflicts.