[msl] Add MSL subclass of MemberBuiltinCall

Test will be added when there is a member function intrinsic.

Bug: 42251016
Change-Id: I2dc1fce11a4af84e40bbdf205f4ee1359f2e0b07
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/192304
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/core/ir/builder.h b/src/tint/lang/core/ir/builder.h
index faae146..f85ec01 100644
--- a/src/tint/lang/core/ir/builder.h
+++ b/src/tint/lang/core/ir/builder.h
@@ -55,6 +55,7 @@
 #include "src/tint/lang/core/ir/load.h"
 #include "src/tint/lang/core/ir/load_vector_element.h"
 #include "src/tint/lang/core/ir/loop.h"
+#include "src/tint/lang/core/ir/member_builtin_call.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/multi_in_block.h"
 #include "src/tint/lang/core/ir/next_iteration.h"
@@ -1063,6 +1064,33 @@
                                      Values(std::forward<ARGS>(args)...));
     }
 
+    /// Creates a member builtin call instruction with an existing instruction result.
+    /// @param result the instruction result to use
+    /// @param func the builtin function to call
+    /// @param obj the object
+    /// @param args the call arguments
+    /// @returns the instruction
+    template <typename KLASS, typename FUNC, typename OBJ, typename... ARGS>
+    tint::traits::EnableIf<tint::traits::IsTypeOrDerived<KLASS, ir::MemberBuiltinCall>, KLASS*>
+    MemberCallWithResult(ir::InstructionResult* result, FUNC func, OBJ&& obj, ARGS&&... args) {
+        return Append(ir.allocators.instructions.Create<KLASS>(
+            result, func, Value(std::forward<OBJ>(obj)), Values(std::forward<ARGS>(args)...)));
+    }
+
+    /// Creates a member builtin call instruction.
+    /// @param type the return type of the call
+    /// @param func the builtin function to call
+    /// @param obj the object
+    /// @param args the call arguments
+    /// @returns the instruction
+    template <typename KLASS, typename FUNC, typename OBJ, typename... ARGS>
+    tint::traits::EnableIf<tint::traits::IsTypeOrDerived<KLASS, ir::MemberBuiltinCall>, KLASS*>
+    MemberCall(const core::type::Type* type, FUNC func, OBJ&& obj, ARGS&&... args) {
+        return MemberCallWithResult<KLASS>(InstructionResult(type), func,
+                                           Value(std::forward<OBJ>(obj)),
+                                           Values(std::forward<ARGS>(args)...));
+    }
+
     /// Creates a value conversion instruction to the template type T
     /// @param val the value to be converted
     /// @returns the instruction
diff --git a/src/tint/lang/msl/ir/BUILD.bazel b/src/tint/lang/msl/ir/BUILD.bazel
index d7f52b8..a4afc1f 100644
--- a/src/tint/lang/msl/ir/BUILD.bazel
+++ b/src/tint/lang/msl/ir/BUILD.bazel
@@ -40,10 +40,12 @@
   name = "ir",
   srcs = [
     "builtin_call.cc",
+    "member_builtin_call.cc",
     "memory_order.cc",
   ],
   hdrs = [
     "builtin_call.h",
+    "member_builtin_call.h",
     "memory_order.h",
   ],
   deps = [
diff --git a/src/tint/lang/msl/ir/BUILD.cmake b/src/tint/lang/msl/ir/BUILD.cmake
index 1ff9a0c..872daf1 100644
--- a/src/tint/lang/msl/ir/BUILD.cmake
+++ b/src/tint/lang/msl/ir/BUILD.cmake
@@ -41,6 +41,8 @@
 tint_add_target(tint_lang_msl_ir lib
   lang/msl/ir/builtin_call.cc
   lang/msl/ir/builtin_call.h
+  lang/msl/ir/member_builtin_call.cc
+  lang/msl/ir/member_builtin_call.h
   lang/msl/ir/memory_order.cc
   lang/msl/ir/memory_order.h
 )
diff --git a/src/tint/lang/msl/ir/BUILD.gn b/src/tint/lang/msl/ir/BUILD.gn
index 21fb844..53b4f67 100644
--- a/src/tint/lang/msl/ir/BUILD.gn
+++ b/src/tint/lang/msl/ir/BUILD.gn
@@ -46,6 +46,8 @@
   sources = [
     "builtin_call.cc",
     "builtin_call.h",
+    "member_builtin_call.cc",
+    "member_builtin_call.h",
     "memory_order.cc",
     "memory_order.h",
   ]
diff --git a/src/tint/lang/msl/ir/member_builtin_call.cc b/src/tint/lang/msl/ir/member_builtin_call.cc
new file mode 100644
index 0000000..0f2ca6d
--- /dev/null
+++ b/src/tint/lang/msl/ir/member_builtin_call.cc
@@ -0,0 +1,63 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+//    contributors may be used to endorse or promote products derived from
+//    this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/msl/ir/member_builtin_call.h"
+
+#include <utility>
+
+#include "src/tint/lang/core/ir/clone_context.h"
+#include "src/tint/lang/core/ir/instruction_result.h"
+#include "src/tint/lang/core/ir/module.h"
+#include "src/tint/lang/core/ir/value.h"
+#include "src/tint/lang/msl/builtin_fn.h"
+#include "src/tint/utils/containers/vector.h"
+#include "src/tint/utils/ice/ice.h"
+#include "src/tint/utils/rtti/castable.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::msl::ir::MemberBuiltinCall);
+
+namespace tint::msl::ir {
+
+MemberBuiltinCall::MemberBuiltinCall(core::ir::InstructionResult* result,
+                                     BuiltinFn func,
+                                     core::ir::Value* object,
+                                     VectorRef<core::ir::Value*> arguments)
+    : Base(result, object, arguments), func_(func) {
+    TINT_ASSERT(func != BuiltinFn::kNone);
+}
+
+MemberBuiltinCall::~MemberBuiltinCall() = default;
+
+MemberBuiltinCall* MemberBuiltinCall::Clone(core::ir::CloneContext& ctx) {
+    auto* new_result = ctx.Clone(Result(0));
+    auto* new_object = ctx.Clone(Object());
+    auto new_args = ctx.Clone<MemberBuiltinCall::kDefaultNumOperands>(Args());
+    return ctx.ir.allocators.instructions.Create<MemberBuiltinCall>(new_result, func_, new_object,
+                                                                    std::move(new_args));
+}
+
+}  // namespace tint::msl::ir
diff --git a/src/tint/lang/msl/ir/member_builtin_call.h b/src/tint/lang/msl/ir/member_builtin_call.h
new file mode 100644
index 0000000..6caa835
--- /dev/null
+++ b/src/tint/lang/msl/ir/member_builtin_call.h
@@ -0,0 +1,78 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+//    this list of conditions and the following disclaimer in the documentation
+//    and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+//    contributors may be used to endorse or promote products derived from
+//    this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_LANG_MSL_IR_MEMBER_BUILTIN_CALL_H_
+#define SRC_TINT_LANG_MSL_IR_MEMBER_BUILTIN_CALL_H_
+
+#include <string>
+
+#include "src/tint/lang/core/intrinsic/table_data.h"
+#include "src/tint/lang/core/ir/member_builtin_call.h"
+#include "src/tint/lang/msl/builtin_fn.h"
+#include "src/tint/lang/msl/intrinsic/dialect.h"
+#include "src/tint/utils/rtti/castable.h"
+
+namespace tint::msl::ir {
+
+/// An MSL member builtin call instruction in the IR.
+class MemberBuiltinCall final : public Castable<MemberBuiltinCall, core::ir::MemberBuiltinCall> {
+  public:
+    /// Constructor
+    /// @param result the result value
+    /// @param func the builtin function
+    /// @param object the object
+    /// @param args the call arguments
+    MemberBuiltinCall(core::ir::InstructionResult* result,
+                      BuiltinFn func,
+                      core::ir::Value* object,
+                      VectorRef<core::ir::Value*> args = tint::Empty);
+    ~MemberBuiltinCall() override;
+
+    /// @copydoc core::ir::Instruction::Clone()
+    MemberBuiltinCall* Clone(core::ir::CloneContext& ctx) override;
+
+    /// @returns the builtin function
+    BuiltinFn Func() const { return func_; }
+
+    /// @returns the identifier for the function
+    size_t FuncId() const override { return static_cast<size_t>(func_); }
+
+    /// @returns the friendly name for the instruction
+    std::string FriendlyName() const override { return str(func_); }
+
+    /// @returns the table data to validate this builtin
+    const core::intrinsic::TableData& TableData() const override {
+        return msl::intrinsic::Dialect::kData;
+    }
+
+  private:
+    BuiltinFn func_;
+};
+
+}  // namespace tint::msl::ir
+
+#endif  // SRC_TINT_LANG_MSL_IR_MEMBER_BUILTIN_CALL_H_