[ir] Simplify attribute handling in ShaderIO

Now that the attribute structures are all unified, we can directly
copy them between structure members, variables, and parameters.

Bug: 340196362
Change-Id: I7efe67fc642d2100d74cdfb25a8f906ccc23fad3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/196841
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/core/ir/transform/shader_io.cc b/src/tint/lang/core/ir/transform/shader_io.cc
index 86f7a74..4fd3502 100644
--- a/src/tint/lang/core/ir/transform/shader_io.cc
+++ b/src/tint/lang/core/ir/transform/shader_io.cc
@@ -172,19 +172,11 @@
                 }
             } else {
                 // Pull out the IO attributes and remove them from the parameter.
-                core::IOAttributes attributes;
-                if (auto loc = param->Location()) {
-                    attributes.location = loc->value;
-                    if (loc->interpolation && ep->Stage() == Function::PipelineStage::kFragment) {
-                        attributes.interpolation = *loc->interpolation;
-                    }
-                    param->ClearLocation();
-                } else if (auto builtin = param->Builtin()) {
-                    attributes.builtin = *builtin;
-                    param->ClearBuiltin();
+                auto attributes = param->Attributes();
+                if (attributes.interpolation && ep->Stage() != Function::PipelineStage::kFragment) {
+                    attributes.interpolation = {};
                 }
-                attributes.invariant = param->Invariant();
-                param->SetInvariant(false);
+                param->SetAttributes({});
 
                 auto name = ir.NameOf(param);
                 backend->AddInput(name, param->Type(), std::move(attributes));
@@ -209,19 +201,11 @@
             }
         } else {
             // Pull out the IO attributes and remove them from the original function.
-            core::IOAttributes attributes;
-            if (auto loc = ep->ReturnLocation()) {
-                attributes.location = loc->value;
-                if (loc->interpolation && ep->Stage() == Function::PipelineStage::kVertex) {
-                    attributes.interpolation = *loc->interpolation;
-                }
-                ep->ClearReturnLocation();
-            } else if (auto builtin = ep->ReturnBuiltin()) {
-                attributes.builtin = *builtin;
-                ep->ClearReturnBuiltin();
+            auto attributes = ep->ReturnAttributes();
+            if (attributes.interpolation && ep->Stage() != Function::PipelineStage::kVertex) {
+                attributes.interpolation = {};
             }
-            attributes.invariant = ep->ReturnInvariant();
-            ep->SetReturnInvariant(false);
+            ep->SetReturnAttributes({});
 
             backend->AddOutput(ir.symbols.New(), ep->ReturnType(), std::move(attributes));
         }
diff --git a/src/tint/lang/spirv/reader/lower/shader_io.cc b/src/tint/lang/spirv/reader/lower/shader_io.cc
index 7179d8b..db19178 100644
--- a/src/tint/lang/spirv/reader/lower/shader_io.cc
+++ b/src/tint/lang/spirv/reader/lower/shader_io.cc
@@ -193,13 +193,7 @@
             }
 
             // Copy the variable attributes to the struct member.
-            const auto& original_attributes = var->Attributes();
-            core::IOAttributes var_attributes;
-            var_attributes.invariant = original_attributes.invariant;
-            var_attributes.builtin = original_attributes.builtin;
-            var_attributes.location = original_attributes.location;
-            var_attributes.interpolation = original_attributes.interpolation;
-
+            auto var_attributes = var->Attributes();
             auto var_type = var->Result(0)->Type()->UnwrapPtr();
             if (auto* str = var_type->As<core::type::Struct>()) {
                 // Add an output for each member of the struct.
@@ -240,16 +234,7 @@
 
         if (output_descriptors.Length() == 1) {
             // Copy the output attributes to the function return.
-            const auto& attributes = output_descriptors[0].attributes;
-            wrapper->SetReturnInvariant(attributes.invariant);
-            if (attributes.builtin) {
-                wrapper->SetReturnBuiltin(attributes.builtin.value());
-            } else if (attributes.location) {
-                core::ir::Location loc;
-                loc.value = attributes.location.value();
-                loc.interpolation = attributes.interpolation;
-                wrapper->SetReturnLocation(std::move(loc));
-            }
+            wrapper->SetReturnAttributes(output_descriptors[0].attributes);
 
             // Return the output from the wrapper function.
             wrapper->SetReturnType(output_descriptors[0].type);
@@ -397,15 +382,7 @@
             }
         } else {
             // Set attributes directly on the function parameter.
-            param->SetInvariant(attributes.invariant);
-            if (attributes.builtin) {
-                param->SetBuiltin(attributes.builtin.value());
-            } else if (attributes.location) {
-                core::ir::Location loc;
-                loc.value = attributes.location.value();
-                loc.interpolation = attributes.interpolation;
-                param->SetLocation(std::move(loc));
-            }
+            param->SetAttributes(attributes);
         }
     }
 };
diff --git a/src/tint/lang/spirv/writer/raise/shader_io.cc b/src/tint/lang/spirv/writer/raise/shader_io.cc
index c418877..359e7fe 100644
--- a/src/tint/lang/spirv/writer/raise/shader_io.cc
+++ b/src/tint/lang/spirv/writer/raise/shader_io.cc
@@ -126,14 +126,7 @@
             // Create an IO variable and add it to the root block.
             auto* ptr = ty.ptr(addrspace, store_type, access);
             auto* var = b.Var(name.str(), ptr);
-            var->SetAttributes(core::IOAttributes{
-                io.attributes.location,
-                io.attributes.blend_src,
-                io.attributes.color,
-                io.attributes.builtin,
-                io.attributes.interpolation,
-                io.attributes.invariant,
-            });
+            var->SetAttributes(io.attributes);
             ir.root_block->Append(var);
             vars.Push(var);
         }