[tint][ir] Remove Function::ReturnBuiltin, use core::BuiltinValue

Validation can catch the invalid builtin values, just like it catches everything else.

Change-Id: I10ac58eddbecf52680d997c75566ac6e1b47d42d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/165043
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/lang/core/ir/function.cc b/src/tint/lang/core/ir/function.cc
index 8c095e0..ebe4211 100644
--- a/src/tint/lang/core/ir/function.cc
+++ b/src/tint/lang/core/ir/function.cc
@@ -93,16 +93,4 @@
     return "<unknown>";
 }
 
-std::string_view ToString(enum Function::ReturnBuiltin value) {
-    switch (value) {
-        case Function::ReturnBuiltin::kFragDepth:
-            return "frag_depth";
-        case Function::ReturnBuiltin::kSampleMask:
-            return "sample_mask";
-        case Function::ReturnBuiltin::kPosition:
-            return "position";
-    }
-    return "<unknown>";
-}
-
 }  // namespace tint::core::ir
diff --git a/src/tint/lang/core/ir/function.h b/src/tint/lang/core/ir/function.h
index a03e510..5cf533f 100644
--- a/src/tint/lang/core/ir/function.h
+++ b/src/tint/lang/core/ir/function.h
@@ -62,16 +62,6 @@
         kVertex,
     };
 
-    /// Builtin attached to return types
-    enum class ReturnBuiltin {
-        /// Builtin Position attribute
-        kPosition,
-        /// Builtin FragDepth attribute
-        kFragDepth,
-        /// Builtin SampleMask
-        kSampleMask,
-    };
-
     /// Constructor
     Function();
 
@@ -114,12 +104,12 @@
 
     /// Sets the return attributes
     /// @param builtin the builtin to set
-    void SetReturnBuiltin(ReturnBuiltin builtin) {
+    void SetReturnBuiltin(BuiltinValue builtin) {
         TINT_ASSERT(!return_.builtin.has_value());
         return_.builtin = builtin;
     }
     /// @returns the return builtin attribute
-    std::optional<enum ReturnBuiltin> ReturnBuiltin() const { return return_.builtin; }
+    std::optional<BuiltinValue> ReturnBuiltin() const { return return_.builtin; }
 
     /// Clears the return builtin attribute.
     void ClearReturnBuiltin() { return_.builtin = {}; }
@@ -184,7 +174,7 @@
 
     struct {
         const core::type::Type* type = nullptr;
-        std::optional<enum ReturnBuiltin> builtin;
+        std::optional<BuiltinValue> builtin;
         std::optional<Location> location;
         bool invariant = false;
     } return_;
@@ -205,18 +195,6 @@
     return out << ToString(value);
 }
 
-/// @param value the enum value
-/// @returns the string for the given enum value
-std::string_view ToString(enum Function::ReturnBuiltin value);
-
-/// @param out the stream to write to
-/// @param value the Function::ReturnBuiltin
-/// @returns @p out so calls can be chained
-template <typename STREAM, typename = traits::EnableIfIsOStream<STREAM>>
-auto& operator<<(STREAM& out, enum Function::ReturnBuiltin value) {
-    return out << ToString(value);
-}
-
 }  // namespace tint::core::ir
 
 #endif  // SRC_TINT_LANG_CORE_IR_FUNCTION_H_
diff --git a/src/tint/lang/core/ir/function_test.cc b/src/tint/lang/core/ir/function_test.cc
index 57156cf..8873648 100644
--- a/src/tint/lang/core/ir/function_test.cc
+++ b/src/tint/lang/core/ir/function_test.cc
@@ -53,8 +53,8 @@
             Module mod;
             Builder b{mod};
             auto* f = b.Function("my_func", mod.Types().void_());
-            f->SetReturnBuiltin(Function::ReturnBuiltin::kFragDepth);
-            f->SetReturnBuiltin(Function::ReturnBuiltin::kPosition);
+            f->SetReturnBuiltin(BuiltinValue::kFragDepth);
+            f->SetReturnBuiltin(BuiltinValue::kPosition);
         },
         "");
 }
@@ -84,7 +84,7 @@
 TEST_F(IR_FunctionTest, Clone) {
     auto* f =
         b.Function("my_func", mod.Types().i32(), Function::PipelineStage::kCompute, {{2, 3, 4}});
-    f->SetReturnBuiltin(Function::ReturnBuiltin::kFragDepth);
+    f->SetReturnBuiltin(BuiltinValue::kFragDepth);
     f->SetReturnLocation(
         1, Interpolation{core::InterpolationType::kFlat, core::InterpolationSampling::kCentroid});
     f->SetReturnInvariant(true);
@@ -110,7 +110,7 @@
     EXPECT_EQ(mod.Types().i32(), new_f->ReturnType());
 
     EXPECT_TRUE(new_f->ReturnBuiltin().has_value());
-    EXPECT_EQ(Function::ReturnBuiltin::kFragDepth, new_f->ReturnBuiltin().value());
+    EXPECT_EQ(BuiltinValue::kFragDepth, new_f->ReturnBuiltin().value());
 
     EXPECT_TRUE(new_f->ReturnLocation().has_value());
     auto loc = new_f->ReturnLocation().value();
diff --git a/src/tint/lang/core/ir/transform/shader_io.cc b/src/tint/lang/core/ir/transform/shader_io.cc
index d509671..a0c6d78 100644
--- a/src/tint/lang/core/ir/transform/shader_io.cc
+++ b/src/tint/lang/core/ir/transform/shader_io.cc
@@ -41,18 +41,6 @@
 
 namespace {
 
-core::BuiltinValue ReturnBuiltin(enum Function::ReturnBuiltin builtin) {
-    switch (builtin) {
-        case Function::ReturnBuiltin::kPosition:
-            return core::BuiltinValue::kPosition;
-        case Function::ReturnBuiltin::kFragDepth:
-            return core::BuiltinValue::kFragDepth;
-        case Function::ReturnBuiltin::kSampleMask:
-            return core::BuiltinValue::kSampleMask;
-    }
-    return core::BuiltinValue::kUndefined;
-}
-
 /// PIMPL state for the transform.
 struct State {
     /// The IR module.
@@ -191,7 +179,7 @@
                 }
                 func->ClearReturnLocation();
             } else if (auto builtin = func->ReturnBuiltin()) {
-                attributes.builtin = ReturnBuiltin(*builtin);
+                attributes.builtin = *builtin;
                 func->ClearReturnBuiltin();
             }
             attributes.invariant = func->ReturnInvariant();
diff --git a/src/tint/lang/spirv/writer/function_test.cc b/src/tint/lang/spirv/writer/function_test.cc
index 85904d4..2658f3f 100644
--- a/src/tint/lang/spirv/writer/function_test.cc
+++ b/src/tint/lang/spirv/writer/function_test.cc
@@ -315,7 +315,7 @@
 
 TEST_F(SpirvWriterTest, Function_ShaderIO_VertexPointSize) {
     auto* func = b.Function("main", ty.vec4<f32>(), core::ir::Function::PipelineStage::kVertex);
-    func->SetReturnBuiltin(core::ir::Function::ReturnBuiltin::kPosition);
+    func->SetReturnBuiltin(core::BuiltinValue::kPosition);
     b.Append(func->Block(), [&] {  //
         b.Return(func, b.Construct(ty.vec4<f32>(), 0.5_f));
     });
diff --git a/src/tint/lang/spirv/writer/raise/shader_io_test.cc b/src/tint/lang/spirv/writer/raise/shader_io_test.cc
index 5899c91..0b5a962 100644
--- a/src/tint/lang/spirv/writer/raise/shader_io_test.cc
+++ b/src/tint/lang/spirv/writer/raise/shader_io_test.cc
@@ -420,7 +420,7 @@
 
 TEST_F(SpirvWriter_ShaderIOTest, ReturnValue_NonStructBuiltin) {
     auto* ep = b.Function("foo", ty.vec4<f32>());
-    ep->SetReturnBuiltin(core::ir::Function::ReturnBuiltin::kPosition);
+    ep->SetReturnBuiltin(core::BuiltinValue::kPosition);
     ep->SetReturnInvariant(true);
     ep->SetStage(core::ir::Function::PipelineStage::kVertex);
 
@@ -1065,7 +1065,7 @@
     // Vertex shader.
     {
         auto* ep = b.Function("vert", ty.vec4<f32>());
-        ep->SetReturnBuiltin(core::ir::Function::ReturnBuiltin::kPosition);
+        ep->SetReturnBuiltin(core::BuiltinValue::kPosition);
         ep->SetReturnInvariant(true);
         ep->SetStage(core::ir::Function::PipelineStage::kVertex);
 
@@ -1446,7 +1446,7 @@
 TEST_F(SpirvWriter_ShaderIOTest, EmitVertexPointSize) {
     auto* ep = b.Function("foo", ty.vec4<f32>());
     ep->SetStage(core::ir::Function::PipelineStage::kVertex);
-    ep->SetReturnBuiltin(core::ir::Function::ReturnBuiltin::kPosition);
+    ep->SetReturnBuiltin(core::BuiltinValue::kPosition);
 
     b.Append(ep->Block(), [&] {  //
         b.Return(ep, b.Construct(ty.vec4<f32>(), 0.5_f));
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
index f227efb..0ae2eea 100644
--- a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
+++ b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
@@ -340,24 +340,7 @@
                                 program_.Sem()
                                     .Get(b)
                                     ->As<sem::BuiltinEnumExpression<core::BuiltinValue>>()) {
-                            switch (ident_sem->Value()) {
-                                case core::BuiltinValue::kPosition:
-                                    ir_func->SetReturnBuiltin(
-                                        core::ir::Function::ReturnBuiltin::kPosition);
-                                    break;
-                                case core::BuiltinValue::kFragDepth:
-                                    ir_func->SetReturnBuiltin(
-                                        core::ir::Function::ReturnBuiltin::kFragDepth);
-                                    break;
-                                case core::BuiltinValue::kSampleMask:
-                                    ir_func->SetReturnBuiltin(
-                                        core::ir::Function::ReturnBuiltin::kSampleMask);
-                                    break;
-                                default:
-                                    TINT_ICE() << "Unknown builtin value in return attributes "
-                                               << ident_sem->Value();
-                                    return;
-                            }
+                            ir_func->SetReturnBuiltin(ident_sem->Value());
                         } else {
                             TINT_ICE() << "Builtin attribute sem invalid";
                             return;
diff --git a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
index 09483c9..f7b6321 100644
--- a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
+++ b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
@@ -300,15 +300,18 @@
         // Emit return type attributes.
         if (auto builtin = fn->ReturnBuiltin()) {
             switch (builtin.value()) {
-                case core::ir::Function::ReturnBuiltin::kPosition:
+                case core::BuiltinValue::kPosition:
                     ret_attrs.Push(b.Builtin(core::BuiltinValue::kPosition));
                     break;
-                case core::ir::Function::ReturnBuiltin::kFragDepth:
+                case core::BuiltinValue::kFragDepth:
                     ret_attrs.Push(b.Builtin(core::BuiltinValue::kFragDepth));
                     break;
-                case core::ir::Function::ReturnBuiltin::kSampleMask:
+                case core::BuiltinValue::kSampleMask:
                     ret_attrs.Push(b.Builtin(core::BuiltinValue::kSampleMask));
                     break;
+                default:
+                    TINT_UNIMPLEMENTED() << builtin.value();
+                    break;
             }
         }
         if (auto loc = fn->ReturnLocation()) {
diff --git a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc
index a470fe3..f379020 100644
--- a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc
+++ b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc
@@ -144,7 +144,7 @@
 
 TEST_F(IRToProgramTest, EntryPoint_Vertex) {
     auto* fn = b.Function("f", ty.vec4<f32>(), core::ir::Function::PipelineStage::kVertex);
-    fn->SetReturnBuiltin(core::ir::Function::ReturnBuiltin::kPosition);
+    fn->SetReturnBuiltin(core::BuiltinValue::kPosition);
 
     fn->Block()->Append(b.Return(fn, b.Splat(ty.vec4<f32>(), 0_f, 4)));
 
@@ -158,7 +158,7 @@
 
 TEST_F(IRToProgramTest, EntryPoint_ReturnAttribute_FragDepth) {
     auto* fn = b.Function("f", ty.f32(), core::ir::Function::PipelineStage::kFragment);
-    fn->SetReturnBuiltin(core::ir::Function::ReturnBuiltin::kFragDepth);
+    fn->SetReturnBuiltin(core::BuiltinValue::kFragDepth);
 
     fn->Block()->Append(b.Return(fn, b.Constant(0.5_f)));
 
@@ -172,7 +172,7 @@
 
 TEST_F(IRToProgramTest, EntryPoint_ReturnAttribute_SampleMask) {
     auto* fn = b.Function("f", ty.u32(), core::ir::Function::PipelineStage::kFragment);
-    fn->SetReturnBuiltin(core::ir::Function::ReturnBuiltin::kSampleMask);
+    fn->SetReturnBuiltin(core::BuiltinValue::kSampleMask);
 
     fn->Block()->Append(b.Return(fn, b.Constant(3_u)));
 
@@ -186,7 +186,7 @@
 
 TEST_F(IRToProgramTest, EntryPoint_ReturnAttribute_Invariant) {
     auto* fn = b.Function("f", ty.vec4<f32>(), core::ir::Function::PipelineStage::kVertex);
-    fn->SetReturnBuiltin(core::ir::Function::ReturnBuiltin::kPosition);
+    fn->SetReturnBuiltin(core::BuiltinValue::kPosition);
     fn->SetReturnInvariant(true);
 
     fn->Block()->Append(b.Return(fn, b.Splat(ty.vec4<f32>(), 0_f, 4)));