// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "toolchain/check/cpp/call.h"

#include "toolchain/base/kind_switch.h"
#include "toolchain/check/call.h"
#include "toolchain/check/cpp/operators.h"
#include "toolchain/check/cpp/overload_resolution.h"
#include "toolchain/sem_ir/function.h"
#include "toolchain/sem_ir/ids.h"
#include "toolchain/sem_ir/typed_insts.h"

namespace Carbon::Check {

auto PerformCallToCppFunction(Context& context, SemIR::LocId loc_id,
                              SemIR::CppOverloadSetId overload_set_id,
                              SemIR::InstId self_id,
                              llvm::ArrayRef<SemIR::InstId> arg_ids)
    -> SemIR::InstId {
  SemIR::InstId callee_id = PerformCppOverloadResolution(
      context, loc_id, overload_set_id, self_id, arg_ids);
  SemIR::Callee callee = GetCallee(context.sem_ir(), callee_id);
  CARBON_KIND_SWITCH(callee) {
    case CARBON_KIND(SemIR::CalleeError _): {
      return SemIR::ErrorInst::InstId;
    }
    case CARBON_KIND(SemIR::CalleeFunction fn): {
      CARBON_CHECK(!fn.self_id.has_value());
      if (self_id.has_value()) {
        // Preserve the `self` argument from the original callee.
        fn.self_id = self_id;
      }
      return PerformCallToFunction(context, loc_id, callee_id, fn, arg_ids);
    }
    case CARBON_KIND(SemIR::CalleeCppOverloadSet _): {
      CARBON_FATAL("overloads can't be recursive");
    }
    case CARBON_KIND(SemIR::CalleeNonFunction _): {
      CARBON_FATAL("overloads should produce functions");
    }
  }
}

}  // namespace Carbon::Check
