Add support for C++ pointers to Carbon methods (#7881)

C++ pointers to Carbon methods are supported using the same mechanisms
as for Carbon functions: we export the method to C++ and then form a
pointer to the exported method. This change does not support invoking a
C++ method pointer from Carbon, which will be more complicated because
we need to model instance binding on the Carbon side.
This commit is contained in:
Geoff Romer
2026-10-02 16:41:55 +00:00
committed by GitHub
parent 632a81fcb6
commit 976692abf4
10 changed files with 1053 additions and 31 deletions
+12 -5
View File
@@ -1325,7 +1325,8 @@ static auto MapTagType(Context& context, const clang::TagType& type)
static auto MapFunctionPointerType(Context& context, SemIR::LocId /*loc_id*/,
clang::QualType type) -> TypeExpr {
CARBON_CHECK(type->isFunctionPointerType());
CARBON_CHECK(type->isFunctionPointerType() ||
type->isMemberFunctionPointerType());
auto clang_type_id = context.clang_function_pointer_types().Lookup(
type.getCanonicalType().getTypePtr());
@@ -1350,7 +1351,7 @@ static auto MapNonWrapperType(Context& context, SemIR::LocId loc_id,
return MapTagType(context, *tag_type);
}
if (type->isFunctionPointerType()) {
if (type->isFunctionPointerType() || type->isMemberFunctionPointerType()) {
return MapFunctionPointerType(context, loc_id, type);
}
@@ -2105,7 +2106,8 @@ static auto ImportFunctionDecl(Context& context, SemIR::LocId loc_id,
static auto ImportFunctionPointer(Context& context,
const clang::Type* pointer_type)
-> SemIR::InstId {
CARBON_CHECK(pointer_type->isFunctionPointerType());
CARBON_CHECK(pointer_type->isFunctionPointerType() ||
pointer_type->isMemberFunctionPointerType());
// Allocate an ID for the function pointer type and return it.
pointer_type = clang::QualType(pointer_type, /*Quals=*/0)
.getCanonicalType()
@@ -2130,6 +2132,10 @@ auto ImportFunctionPointerInvoke(
if (info.decl_id.has_value()) {
return info;
}
if (info.clang_type->isMemberFunctionPointerType()) {
context.TODO(loc_id,
"invoking a C++ member function pointer is unsupported");
}
Diagnostics::AnnotationScope annotate_diagnostics(
&context.emitter(), [&](auto& builder) {
CARBON_DIAGNOSTIC(InCppFunctionPointerThunk, Note,
@@ -2183,7 +2189,7 @@ static auto PushDecl(Context& context, SemIR::ClangDeclKey decl,
static auto PushType(Context& context, clang::QualType type,
ImportWorklist& worklist) -> void {
while (true) {
if (type->isFunctionPointerType()) {
if (type->isFunctionPointerType() || type->isMemberFunctionPointerType()) {
const clang::Type* type_ptr = type.getCanonicalType().getTypePtr();
if (!IsImported(context, type_ptr)) {
worklist.push_back({.key = type_ptr, .added_dependencies = false});
@@ -2418,7 +2424,8 @@ static auto ImportAfterDependencies(Context& context, SemIR::LocId loc_id,
return SemIR::ErrorInst::InstId;
}
case CARBON_KIND(const clang::Type* type): {
if (type->isFunctionPointerType()) {
if (type->isFunctionPointerType() ||
type->isMemberFunctionPointerType()) {
return ImportFunctionPointer(context, type);
}