tint/resolver: Resolve dependencies of parameter attributes

Fixed: chromium:1381883
Change-Id: If93840977407e349ab8d3ea5a2f51b9e03c7d0e5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/108920
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Auto-Submit: Ben Clayton <bclayton@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/resolver/dependency_graph.cc b/src/tint/resolver/dependency_graph.cc
index 5a21c55..3238c8b 100644
--- a/src/tint/resolver/dependency_graph.cc
+++ b/src/tint/resolver/dependency_graph.cc
@@ -193,8 +193,6 @@
             },
             [&](const ast::Function* func) {
                 Declare(func->symbol, func);
-                TraverseAttributes(func->attributes);
-                TraverseAttributes(func->return_type_attributes);
                 TraverseFunction(func);
             },
             [&](const ast::Variable* var) {
@@ -216,10 +214,13 @@
     /// Traverses the function, performing symbol resolution and determining
     /// global dependencies.
     void TraverseFunction(const ast::Function* func) {
+        TraverseAttributes(func->attributes);
+        TraverseAttributes(func->return_type_attributes);
         // Perform symbol resolution on all the parameter types before registering
         // the parameters themselves. This allows the case of declaring a parameter
         // with the same identifier as its type.
         for (auto* param : func->params) {
+            TraverseAttributes(param->attributes);
             TraverseType(param->type);
         }
         // Resolve the return type
diff --git a/src/tint/resolver/dependency_graph_test.cc b/src/tint/resolver/dependency_graph_test.cc
index 311c9cc..272357b 100644
--- a/src/tint/resolver/dependency_graph_test.cc
+++ b/src/tint/resolver/dependency_graph_test.cc
@@ -1237,9 +1237,14 @@
                                    })});
     GlobalVar(Sym(), T, V);
     GlobalConst(Sym(), T, V);
-    Func(Sym(),                           //
-         utils::Vector{Param(Sym(), T)},  //
-         T,                               // Return type
+    Func(Sym(),
+         utils::Vector{
+             Param(Sym(), T,
+                   utils::Vector{
+                       Location(V),  // Parameter attributes
+                   }),
+         },
+         T,  // Return type
          utils::Vector{
              Decl(Var(Sym(), T, V)),                    //
              Decl(Let(Sym(), T, V)),                    //
diff --git a/test/tint/bug/chromium/1381883.wgsl b/test/tint/bug/chromium/1381883.wgsl
new file mode 100644
index 0000000..8caec68
--- /dev/null
+++ b/test/tint/bug/chromium/1381883.wgsl
@@ -0,0 +1,5 @@
+const C = 2;
+
+@fragment
+fn main(@location(C) none : f32) {
+}
diff --git a/test/tint/bug/chromium/1381883.wgsl.expected.dxc.hlsl b/test/tint/bug/chromium/1381883.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..6971386
--- /dev/null
+++ b/test/tint/bug/chromium/1381883.wgsl.expected.dxc.hlsl
@@ -0,0 +1,11 @@
+struct tint_symbol_1 {
+  float none : TEXCOORD2;
+};
+
+void main_inner(float none) {
+}
+
+void main(tint_symbol_1 tint_symbol) {
+  main_inner(tint_symbol.none);
+  return;
+}
diff --git a/test/tint/bug/chromium/1381883.wgsl.expected.fxc.hlsl b/test/tint/bug/chromium/1381883.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..6971386
--- /dev/null
+++ b/test/tint/bug/chromium/1381883.wgsl.expected.fxc.hlsl
@@ -0,0 +1,11 @@
+struct tint_symbol_1 {
+  float none : TEXCOORD2;
+};
+
+void main_inner(float none) {
+}
+
+void main(tint_symbol_1 tint_symbol) {
+  main_inner(tint_symbol.none);
+  return;
+}
diff --git a/test/tint/bug/chromium/1381883.wgsl.expected.glsl b/test/tint/bug/chromium/1381883.wgsl.expected.glsl
new file mode 100644
index 0000000..b591351
--- /dev/null
+++ b/test/tint/bug/chromium/1381883.wgsl.expected.glsl
@@ -0,0 +1,11 @@
+#version 310 es
+precision mediump float;
+
+layout(location = 2) in float none_1;
+void tint_symbol(float none) {
+}
+
+void main() {
+  tint_symbol(none_1);
+  return;
+}
diff --git a/test/tint/bug/chromium/1381883.wgsl.expected.msl b/test/tint/bug/chromium/1381883.wgsl.expected.msl
new file mode 100644
index 0000000..a5bb014
--- /dev/null
+++ b/test/tint/bug/chromium/1381883.wgsl.expected.msl
@@ -0,0 +1,15 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct tint_symbol_2 {
+  float none [[user(locn2)]];
+};
+
+void tint_symbol_inner(float none) {
+}
+
+fragment void tint_symbol(tint_symbol_2 tint_symbol_1 [[stage_in]]) {
+  tint_symbol_inner(tint_symbol_1.none);
+  return;
+}
+
diff --git a/test/tint/bug/chromium/1381883.wgsl.expected.spvasm b/test/tint/bug/chromium/1381883.wgsl.expected.spvasm
new file mode 100644
index 0000000..3803de3
--- /dev/null
+++ b/test/tint/bug/chromium/1381883.wgsl.expected.spvasm
@@ -0,0 +1,31 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 14
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %none_1
+               OpExecutionMode %main OriginUpperLeft
+               OpName %none_1 "none_1"
+               OpName %main_inner "main_inner"
+               OpName %none "none"
+               OpName %main "main"
+               OpDecorate %none_1 Location 2
+      %float = OpTypeFloat 32
+%_ptr_Input_float = OpTypePointer Input %float
+     %none_1 = OpVariable %_ptr_Input_float Input
+       %void = OpTypeVoid
+          %4 = OpTypeFunction %void %float
+          %9 = OpTypeFunction %void
+ %main_inner = OpFunction %void None %4
+       %none = OpFunctionParameter %float
+          %8 = OpLabel
+               OpReturn
+               OpFunctionEnd
+       %main = OpFunction %void None %9
+         %11 = OpLabel
+         %13 = OpLoad %float %none_1
+         %12 = OpFunctionCall %void %main_inner %13
+               OpReturn
+               OpFunctionEnd
diff --git a/test/tint/bug/chromium/1381883.wgsl.expected.wgsl b/test/tint/bug/chromium/1381883.wgsl.expected.wgsl
new file mode 100644
index 0000000..8caec68
--- /dev/null
+++ b/test/tint/bug/chromium/1381883.wgsl.expected.wgsl
@@ -0,0 +1,5 @@
+const C = 2;
+
+@fragment
+fn main(@location(C) none : f32) {
+}