C++ interop: Add return reference types support (#6178)

This is a follow up of #6082, which added support for reference types,
but not for return types.

C++ Interop Demo:

```carbon
// main.carbon

library "Main";

import Core library "io";

import Cpp inline '''
struct C {
  auto Inc() -> void { ++x; }
  int x = 0;
};
auto GetC() -> C& {
  static C c;
  return c;
}
''';

fn Run() -> i32 {
  Core.Print(Cpp.GetC()->x);
  Cpp.GetC()->Inc();
  Core.Print(Cpp.GetC()->x);
  Cpp.GetC()->Inc();
  Core.Print(Cpp.GetC()->x);
  return 0;
}
```

```shell
$ bazel build toolchain:carbon && bazel-bin/toolchain/carbon compile main.carbon && bazel-bin/toolchain/carbon link main.o --output=demo && ./demo
0
1
2
```

**Without this change**:
```shell
main.carbon:19:14: error: semantics TODO: `Unsupported: return type: C &`
  Core.Print(Cpp.GetC()->x);
             ^~~~~~~~~~
```

Part of #6148.
This commit is contained in:
Boaz Brickner
2025-10-08 16:33:09 +00:00
committed by GitHub
parent ba8ed99eb0
commit bfc4d2b127
4 changed files with 268 additions and 111 deletions
+12 -6
View File
@@ -241,6 +241,14 @@ static auto GetNonnullType(clang::ASTContext& ast_context,
pointer_type, pointer_type);
}
// Given a type, returns the corresponding _Nonnull-qualified pointer type,
// ignoring references.
static auto GetNonNullablePointerType(clang::ASTContext& ast_context,
clang::QualType type) {
return GetNonnullType(ast_context,
ast_context.getPointerType(type.getNonReferenceType()));
}
// Given the type of a callee parameter, returns the type to use for the
// corresponding thunk parameter.
static auto GetThunkParameterType(clang::ASTContext& ast_context,
@@ -249,8 +257,7 @@ static auto GetThunkParameterType(clang::ASTContext& ast_context,
if (IsSimpleAbiType(ast_context, callee_type)) {
return callee_type;
}
return GetNonnullType(ast_context, ast_context.getPointerType(
callee_type.getNonReferenceType()));
return GetNonNullablePointerType(ast_context, callee_type);
}
// Creates the thunk parameter types given the callee function.
@@ -272,9 +279,8 @@ static auto BuildThunkParameterTypes(clang::ASTContext& ast_context,
}
if (!callee_info.has_simple_return_type) {
thunk_param_types.push_back(GetNonnullType(
ast_context,
ast_context.getPointerType(callee_info.effective_return_type)));
thunk_param_types.push_back(GetNonNullablePointerType(
ast_context, callee_info.effective_return_type));
}
CARBON_CHECK(thunk_param_types.size() == callee_info.num_thunk_params());
@@ -524,7 +530,7 @@ static auto BuildThunkBody(clang::Sema& sema,
auto* return_object_addr = BuildThunkParamRef(
sema, thunk_function_decl, callee_info.GetThunkReturnParamIndex());
auto return_type = callee_info.effective_return_type;
auto return_type = callee_info.effective_return_type.getNonReferenceType();
auto* return_type_info =
sema.Context.getTrivialTypeSourceInfo(return_type, clang_loc);
auto placement_new = sema.BuildCXXNew(