mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 14:31:04 +01:00
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:
@@ -1446,16 +1446,26 @@ static auto MakeParamPatternsBlockId(Context& context, SemIR::LocId loc_id,
|
||||
// TODO: Support more return types.
|
||||
static auto GetReturnTypeExpr(Context& context, SemIR::LocId loc_id,
|
||||
clang::FunctionDecl* clang_decl) -> TypeExpr {
|
||||
clang::QualType ret_type = clang_decl->getReturnType();
|
||||
if (!ret_type->isVoidType()) {
|
||||
TypeExpr mapped_type = MapType(context, loc_id, ret_type);
|
||||
if (!mapped_type.inst_id.has_value()) {
|
||||
clang::QualType orig_ret_type = clang_decl->getReturnType();
|
||||
if (!orig_ret_type->isVoidType()) {
|
||||
// We map `T&` return type to `addr param: T*`, and `T&&` parameters to
|
||||
// `param: T`.
|
||||
// TODO: Revisit this and decide what we really want to do here.
|
||||
clang::QualType ret_type = orig_ret_type.getNonReferenceType();
|
||||
|
||||
auto [orig_type_inst_id, type_id] = MapType(context, loc_id, ret_type);
|
||||
if (!orig_type_inst_id.has_value()) {
|
||||
context.TODO(loc_id, llvm::formatv("Unsupported: return type: {0}",
|
||||
ret_type.getAsString()));
|
||||
orig_ret_type.getAsString()));
|
||||
return {.inst_id = SemIR::ErrorInst::TypeInstId,
|
||||
.type_id = SemIR::ErrorInst::TypeId};
|
||||
}
|
||||
return mapped_type;
|
||||
|
||||
if (orig_ret_type->isLValueReferenceType()) {
|
||||
type_id = GetPointerType(context, orig_type_inst_id);
|
||||
}
|
||||
|
||||
return {orig_type_inst_id, type_id};
|
||||
}
|
||||
|
||||
auto* ctor = dyn_cast<clang::CXXConstructorDecl>(clang_decl);
|
||||
|
||||
Reference in New Issue
Block a user