mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
Support C++ calling Carbon functions with ref parameters (#7107)
When creating the C++ thunk, make the parameters references if the corresponding callee parameters are `ref`s. When creating the Carbon thunk, tag the call arguments as `ref` if the corresponding callee parameters are `ref`s.
This commit is contained in:
@@ -168,6 +168,14 @@ auto ExportClassToCpp(Context& context, SemIR::LocId loc_id,
|
||||
|
||||
namespace {
|
||||
struct FunctionInfo {
|
||||
struct Param {
|
||||
// Type of the parameter's scrutinee.
|
||||
SemIR::TypeId type_id;
|
||||
|
||||
// Whether this is a `ref` param.
|
||||
bool is_ref;
|
||||
};
|
||||
|
||||
explicit FunctionInfo(Context& context, SemIR::FunctionId function_id,
|
||||
const SemIR::Function& function,
|
||||
clang::DeclContext* decl_context)
|
||||
@@ -188,15 +196,17 @@ struct FunctionInfo {
|
||||
self_type_id = scrutinee_type_id;
|
||||
}
|
||||
|
||||
// Get the function's explicit parameter types.
|
||||
// Get the function's explicit parameters.
|
||||
function_params =
|
||||
function_params.drop_front(function.call_param_ranges.implicit_size());
|
||||
function_params =
|
||||
function_params.drop_back(function.call_param_ranges.return_size());
|
||||
for (auto param_inst_id : function_params) {
|
||||
auto scrutinee_type_id = ExtractScrutineeType(
|
||||
context.sem_ir(), context.insts().Get(param_inst_id).type_id());
|
||||
param_type_ids.push_back(scrutinee_type_id);
|
||||
explicit_params.push_back(
|
||||
{.type_id = ExtractScrutineeType(
|
||||
context.sem_ir(), context.insts().Get(param_inst_id).type_id()),
|
||||
.is_ref =
|
||||
context.insts().Is<SemIR::RefParamPattern>(param_inst_id)});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,9 +230,9 @@ struct FunctionInfo {
|
||||
// `CXXRecordDecl`.
|
||||
clang::DeclContext* decl_context;
|
||||
|
||||
// Types of the function's explicit parameters (excludes implicit
|
||||
// parameters and return parameters).
|
||||
llvm::SmallVector<SemIR::TypeId> param_type_ids;
|
||||
// For each of the function's explicit parameters, the scrutinee type
|
||||
// and whether the parameter is a reference.
|
||||
llvm::SmallVector<Param> explicit_params;
|
||||
|
||||
// Type of the function's `self` parameter, or `None` if the function
|
||||
// is not a method.
|
||||
@@ -256,8 +266,8 @@ static auto BuildCppFunctionDeclForCarbonFn(Context& context,
|
||||
cpp_type = context.ast_context().getLValueReferenceType(cpp_type);
|
||||
cpp_param_types.push_back(cpp_type);
|
||||
}
|
||||
for (auto param_type_id : callee.param_type_ids) {
|
||||
auto cpp_type = MapToCppType(context, param_type_id);
|
||||
for (auto param : callee.explicit_params) {
|
||||
auto cpp_type = MapToCppType(context, param.type_id);
|
||||
if (cpp_type.isNull()) {
|
||||
context.TODO(loc_id, "failed to map Carbon type to C++");
|
||||
return nullptr;
|
||||
@@ -471,12 +481,15 @@ static auto BuildCppToCarbonThunk(Context& context, SemIR::LocId loc_id,
|
||||
auto& thunk_ident = context.ast_context().Idents.get(thunk_name);
|
||||
|
||||
llvm::SmallVector<clang::QualType> param_types;
|
||||
for (auto type_id : target.param_type_ids) {
|
||||
auto cpp_type = MapToCppType(context, type_id);
|
||||
for (auto param : target.explicit_params) {
|
||||
auto cpp_type = MapToCppType(context, param.type_id);
|
||||
if (cpp_type.isNull()) {
|
||||
context.TODO(loc_id, "failed to map C++ type to Carbon");
|
||||
return nullptr;
|
||||
}
|
||||
if (param.is_ref) {
|
||||
cpp_type = context.ast_context().getLValueReferenceType(cpp_type);
|
||||
}
|
||||
param_types.push_back(cpp_type);
|
||||
}
|
||||
|
||||
@@ -513,7 +526,10 @@ static auto BuildCarbonToCarbonThunk(Context& context, SemIR::LocId loc_id,
|
||||
// Get the thunk's parameters. These match the callee parameters, with
|
||||
// the addition of an output parameter for the callee's return value
|
||||
// (if it has one).
|
||||
llvm::SmallVector<SemIR::TypeId> thunk_param_type_ids(target.param_type_ids);
|
||||
llvm::SmallVector<SemIR::TypeId> thunk_param_type_ids;
|
||||
for (const auto& param : target.explicit_params) {
|
||||
thunk_param_type_ids.push_back(param.type_id);
|
||||
}
|
||||
auto callee_return_type_id =
|
||||
target.function.GetDeclaredReturnType(context.sem_ir());
|
||||
if (callee_return_type_id != SemIR::TypeId::None) {
|
||||
|
||||
Reference in New Issue
Block a user