[ir] Use IOAttributes for Function return

Leave the individual getters and setters for now to avoid extra churn.

Bug: 340196362
Change-Id: I2d51b698c19f8f38f3493b3986728fd6399afd4c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/196840
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/core/ir/function.cc b/src/tint/lang/core/ir/function.cc
index 2cce808..4795ddf 100644
--- a/src/tint/lang/core/ir/function.cc
+++ b/src/tint/lang/core/ir/function.cc
@@ -54,9 +54,7 @@
         ctx.ir.allocators.values.Create<Function>(return_.type, pipeline_stage_, workgroup_size_);
     new_func->block_ = ctx.ir.blocks.Create<ir::Block>();
     new_func->SetParams(ctx.Clone<1>(params_.Slice()));
-    new_func->return_.builtin = return_.builtin;
-    new_func->return_.location = return_.location;
-    new_func->return_.invariant = return_.invariant;
+    new_func->return_.attributes = return_.attributes;
 
     ctx.Replace(this, new_func);
     block_->CloneInto(ctx, new_func->block_);
diff --git a/src/tint/lang/core/ir/function.h b/src/tint/lang/core/ir/function.h
index 7b2976d..0341780 100644
--- a/src/tint/lang/core/ir/function.h
+++ b/src/tint/lang/core/ir/function.h
@@ -32,6 +32,7 @@
 #include <optional>
 #include <utility>
 
+#include "src/tint/lang/core/io_attributes.h"
 #include "src/tint/lang/core/ir/function_param.h"
 #include "src/tint/lang/core/ir/location.h"
 #include "src/tint/lang/core/ir/value.h"
@@ -106,41 +107,62 @@
     /// @returns the return type for the function
     const core::type::Type* ReturnType() const { return return_.type; }
 
+    /// Sets the return IO attributes.
+    /// @param attrs the attributes
+    void SetReturnAttributes(const IOAttributes& attrs) { return_.attributes = attrs; }
+    /// @returns the return IO attributes
+    const IOAttributes& ReturnAttributes() const { return return_.attributes; }
+
     /// Sets the return attributes
     /// @param builtin the builtin to set
     void SetReturnBuiltin(BuiltinValue builtin) {
-        TINT_ASSERT(!return_.builtin.has_value());
-        return_.builtin = builtin;
+        TINT_ASSERT(!return_.attributes.builtin.has_value());
+        return_.attributes.builtin = builtin;
     }
     /// @returns the return builtin attribute
-    std::optional<BuiltinValue> ReturnBuiltin() const { return return_.builtin; }
+    std::optional<BuiltinValue> ReturnBuiltin() const { return return_.attributes.builtin; }
 
     /// Clears the return builtin attribute.
-    void ClearReturnBuiltin() { return_.builtin = {}; }
+    void ClearReturnBuiltin() { return_.attributes.builtin = {}; }
 
     /// Sets the return location
     /// @param location the location to set
-    void SetReturnLocation(Location location) { return_.location = std::move(location); }
+    void SetReturnLocation(Location location) {
+        // TODO(340196362): Remove this overload.
+        return_.attributes.location = location.value;
+        return_.attributes.interpolation = location.interpolation;
+    }
 
     /// Sets the return location
     /// @param loc the location to set
     /// @param interp the interpolation
     void SetReturnLocation(uint32_t loc, std::optional<core::Interpolation> interp) {
-        return_.location = {loc, interp};
+        return_.attributes.location = loc;
+        return_.attributes.interpolation = interp;
     }
 
     /// @returns the return location
-    std::optional<Location> ReturnLocation() const { return return_.location; }
+    std::optional<Location> ReturnLocation() const {
+        // TODO(340196362): Remove this overload.
+        if (return_.attributes.location.has_value()) {
+            return ir::Location{return_.attributes.location.value(),
+                                return_.attributes.interpolation};
+        }
+        return {};
+    }
 
     /// Clears the return location attribute.
-    void ClearReturnLocation() { return_.location = {}; }
+    void ClearReturnLocation() {
+        return_.attributes.location = {};
+        return_.attributes.interpolation = {};
+    }
 
     /// Sets the return as invariant
     /// @param val the invariant value to set
-    void SetReturnInvariant(bool val) { return_.invariant = val; }
+    void SetReturnInvariant(bool val) { return_.attributes.invariant = val; }
 
     /// @returns the return invariant value
-    bool ReturnInvariant() const { return return_.invariant; }
+    bool ReturnInvariant() const { return return_.attributes.invariant; }
 
     /// Sets the function parameters
     /// @param params the function parameters
@@ -182,9 +204,7 @@
 
     struct {
         const core::type::Type* type = nullptr;
-        std::optional<BuiltinValue> builtin;
-        std::optional<Location> location;
-        bool invariant = false;
+        IOAttributes attributes = {};
     } return_;
 
     Vector<FunctionParam*, 1> params_;