mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 13:11:04 +01:00
Initial support for C++ function pointers (#7788)
This change introduces a new inst kind `CppFunctionPointerType`, which represents an imported C++ function pointer that can be invoked from Carbon (support for forming such a pointer from a Carbon function is in a follow-up PR). This is implemented by treating the operation of invoking a function pointer in C++ as if it were a call to an `__invoke` method on the function pointer type, and extending the existing function-import logic to support importing this fictitious method. --------- Co-authored-by: Nicholas Bishop <nbishop@nbishop.net>
This commit is contained in:
co-authored by
Nicholas Bishop
parent
f65572a1e6
commit
12e1afeb15
@@ -197,14 +197,55 @@ CalleeFunctionInfo::CalleeFunctionInfo(Context& context,
|
||||
/*for_parameter=*/false);
|
||||
}
|
||||
|
||||
CalleeFunctionInfo::CalleeFunctionInfo(Context& context,
|
||||
const clang::Type* function_pointer_type)
|
||||
: self_param_kind(SelfParamKind::FunctionPointer),
|
||||
decl(nullptr),
|
||||
decl_name(&context.ast_context().Idents.get("__invoke")),
|
||||
clang_loc(),
|
||||
sem_ir_loc(SemIR::LocId::None),
|
||||
function_type(function_pointer_type->getPointeeType()
|
||||
->getAs<clang::FunctionProtoType>()),
|
||||
signature_id(SemIR::ClangDeclSignatureId::None),
|
||||
signature(nullptr),
|
||||
num_callee_params(function_type->getNumParams()),
|
||||
self_param_type(function_pointer_type, 0),
|
||||
effective_return_type(function_type->getReturnType()),
|
||||
has_simple_return_type(IsSimpleAbiType(context.ast_context(),
|
||||
effective_return_type,
|
||||
/*for_parameter=*/false)) {
|
||||
SemIR::ClangDeclSignature local_signature;
|
||||
local_signature.kind = SemIR::ClangDeclSignature::Normal;
|
||||
local_signature.num_params =
|
||||
static_cast<int32_t>(function_type->getNumParams());
|
||||
local_signature.self_passing_mode =
|
||||
SemIR::ClangDeclSignature::PassingMode::ByValue;
|
||||
local_signature.passing_modes.assign(
|
||||
local_signature.num_params,
|
||||
SemIR::ClangDeclSignature::PassingMode::ByValue);
|
||||
signature_id =
|
||||
context.clang_decl_signatures().Add(std::move(local_signature));
|
||||
signature = &context.clang_decl_signatures().Get(signature_id);
|
||||
}
|
||||
|
||||
auto CalleeFunctionInfo::GetCalleeParamIdentifier(int i) const
|
||||
-> clang::IdentifierInfo* {
|
||||
return decl->getParamDecl(i)->getIdentifier();
|
||||
switch (self_param_kind) {
|
||||
case SelfParamKind::FunctionPointer:
|
||||
return nullptr;
|
||||
default:
|
||||
return decl->getParamDecl(i)->getIdentifier();
|
||||
}
|
||||
}
|
||||
|
||||
auto CalleeFunctionInfo::GetCalleeParamLocation(int i) const
|
||||
-> clang::SourceLocation {
|
||||
return decl->getParamDecl(i)->getLocation();
|
||||
switch (self_param_kind) {
|
||||
case SelfParamKind::FunctionPointer:
|
||||
return {};
|
||||
default:
|
||||
return decl->getParamDecl(i)->getLocation();
|
||||
}
|
||||
}
|
||||
|
||||
auto IsCppThunkRequired(Context& context, const CalleeFunctionInfo& callee_info)
|
||||
@@ -514,7 +555,7 @@ static auto BuildThunkBody(CppContext& cpp_context, clang::Sema& sema,
|
||||
cast<clang::CXXMethodDecl>(callee_info.decl)
|
||||
->getFunctionObjectParameterReferenceType();
|
||||
auto* object_param_ref = BuildThunkParamRef(
|
||||
sema, thunk_function_decl, 0,
|
||||
sema, thunk_function_decl, /*thunk_index=*/0,
|
||||
callee_info.signature->self_passing_mode, object_param_type);
|
||||
constexpr bool IsArrow = false;
|
||||
auto object =
|
||||
@@ -533,6 +574,11 @@ static auto BuildThunkBody(CppContext& cpp_context, clang::Sema& sema,
|
||||
clang::OK_Ordinary);
|
||||
break;
|
||||
}
|
||||
case CalleeFunctionInfo::SelfParamKind::FunctionPointer:
|
||||
callee = BuildThunkParamRef(sema, thunk_function_decl, 0,
|
||||
callee_info.signature->self_passing_mode,
|
||||
callee_info.self_param_type);
|
||||
break;
|
||||
case CalleeFunctionInfo::SelfParamKind::None:
|
||||
if (isa<clang::CXXConstructorDecl>(callee_info.decl)) {
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user