mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
Instead of calling `PerformCppOverloadResolution()` and use the complex return value to call `PerformCallToFunction()`, we call `PerformCallToCppFunction()` which will call both `PerformCppOverloadResolution()` and `PerformCallToFunction()`. Followup of #6112. Part of #5995.
60 lines
2.3 KiB
C++
60 lines
2.3 KiB
C++
// 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 {
|
|
|
|
// Returns whether the function is an imported C++ operator member function.
|
|
static auto IsCppOperatorMethod(Context& context, SemIR::FunctionId function_id)
|
|
-> bool {
|
|
SemIR::ClangDeclId clang_decl_id =
|
|
context.functions().Get(function_id).clang_decl_id;
|
|
return clang_decl_id.has_value() &&
|
|
IsCppOperatorMethodDecl(
|
|
context.clang_decls().Get(clang_decl_id).key.decl);
|
|
}
|
|
|
|
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;
|
|
} else if (IsCppOperatorMethod(context, fn.function_id)) {
|
|
// Adjust `self` and args for C++ overloaded operator methods.
|
|
fn.self_id = arg_ids.consume_front();
|
|
}
|
|
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
|