Skip to content

Commit caf83c2

Browse files
committed
[cxx-interop] Import const-refs as value types when importing clang function types.
Otherwise, it will pass the value as a poitner.
1 parent d996b98 commit caf83c2

File tree

6 files changed

+57
-2
lines changed

6 files changed

+57
-2
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,13 @@ namespace {
671671
paramImportKind = ImportTypeKind::CompletionHandlerResultParameter;
672672
}
673673

674+
auto paramQualType = *param;
675+
if (paramQualType->isReferenceType() &&
676+
paramQualType->getPointeeType().isConstQualified())
677+
paramQualType = paramQualType->getPointeeType();
678+
674679
auto swiftParamTy = Impl.importTypeIgnoreIUO(
675-
*param, paramImportKind, AllowNSUIntegerAsInt, Bridging,
680+
paramQualType, paramImportKind, AllowNSUIntegerAsInt, Bridging,
676681
OTK_Optional);
677682
if (!swiftParamTy)
678683
return Type();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef TEST_INTEROP_CXX_CLOSURES_INPUTS_REFERENCE_H
2+
#define TEST_INTEROP_CXX_CLOSURES_INPUTS_REFERENCE_H
3+
4+
inline void invokeWith42ConstRef(void (^fn)(const int&)) {
5+
int i = 42;
6+
fn(i);
7+
}
8+
9+
inline void invokeWith42Ref(void (^fn)(int&)) {
10+
int i = 42;
11+
fn(i);
12+
}
13+
14+
#endif // TEST_INTEROP_CXX_CLOSURES_INPUTS_REFERENCE_H

test/Interop/Cxx/reference/Inputs/module.modulemap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,8 @@ module Reference {
22
header "reference.h"
33
requires cplusplus
44
}
5+
6+
module Closures {
7+
header "closures.h"
8+
requires cplusplus
9+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// RUN: %target-swift-ide-test -print-module -module-to-print=Closures -I %S/Inputs -source-filename=x -enable-cxx-interop | %FileCheck %s
2+
3+
// CHECK: func invokeWith42ConstRef(_ fn: ((Int32) -> Void)!)
4+
// CHECK: func invokeWith42Ref(_ fn: ((UnsafeMutablePointer<Int32>) -> Void)!)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-clangxx -c %S/Inputs/reference.cpp -I %S/Inputs -o %t/reference.o
3+
// RUN: %target-build-swift %s -I %S/Inputs -o %t/reference %t/reference.o -Xfrontend -enable-cxx-interop
4+
// RUN: %target-codesign %t/reference
5+
// RUN: %target-run %t/reference
6+
//
7+
// REQUIRES: executable_test
8+
// REQUIRES: objc_interop
9+
10+
import Closures
11+
import StdlibUnittest
12+
13+
var ClosuresTestSuite = TestSuite("Closures")
14+
15+
ClosuresTestSuite.test("const reference closure") {
16+
var x: CInt = 0
17+
invokeWith42ConstRef { x = $0 }
18+
expectEqual(42, x)
19+
}
20+
21+
ClosuresTestSuite.test("mutable reference closure") {
22+
var x: CInt = 0
23+
invokeWith42Ref { x = $0.pointee }
24+
expectEqual(42, x)
25+
}
26+
27+
runAllTests()

test/Interop/Cxx/reference/reference.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ ReferenceTestSuite.test("reference to template") {
9696
}
9797

9898
ReferenceTestSuite.test("const reference to template") {
99-
var val: CInt = 53
99+
let val: CInt = 53
100100
let ref = constRefToTemplate(val)
101101
expectEqual(53, ref.pointee)
102102
}

0 commit comments

Comments
 (0)