Skip to content

Commit ebb21d7

Browse files
hypzoecarver
authored andcommitted
[cxx-interop] Import const T& parameters as T.
This change allows Swift code to pass immutable values to const references in C++.
1 parent f93bc64 commit ebb21d7

15 files changed

+59
-29
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,15 +1967,17 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
19671967
cast<clang::TemplateTypeParmType>(paramTy->getPointeeType());
19681968
swiftParamTy =
19691969
findGenericTypeInGenericDecls(templateParamType, genericParams);
1970-
isInOut = true;
1970+
if (!paramTy->getPointeeType().isConstQualified())
1971+
isInOut = true;
19711972
} else if (auto *templateParamType =
19721973
dyn_cast<clang::TemplateTypeParmType>(paramTy)) {
19731974
swiftParamTy =
19741975
findGenericTypeInGenericDecls(templateParamType, genericParams);
19751976
} else {
19761977
if (auto refType = dyn_cast<clang::ReferenceType>(paramTy)) {
19771978
paramTy = refType->getPointeeType();
1978-
isInOut = true;
1979+
if (!paramTy.isConstQualified())
1980+
isInOut = true;
19791981
}
19801982
auto importedType = importType(paramTy, importKind, allowNSUIntegerAsInt,
19811983
Bridgeability::Full, OptionalityOfParam);

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,14 @@ static bool isClangTypeMoreIndirectThanSubstType(TypeConverter &TC,
13231323

13241324
return true;
13251325
}
1326+
1327+
// Pass C++ const reference types indirectly. Right now there's no way to
1328+
// express immutable borrowed params, so we have to have this hack.
1329+
// Eventually, we should just express these correctly: rdar://89647503
1330+
if (clangTy->isReferenceType() &&
1331+
clangTy->getPointeeType().isConstQualified())
1332+
return true;
1333+
13261334
return false;
13271335
}
13281336

test/Interop/Cxx/ergonomics/implicit-computed-properties-module-interface.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@
211211
// CHECK-NEXT: init()
212212
// CHECK-NEXT: init(value: Int32)
213213
// CHECK-NEXT: mutating func getXMutating() -> UnsafePointer<Int32>
214-
// CHECK-NEXT: mutating func setXMutating(_ v: inout Int32)
214+
// CHECK-NEXT: mutating func setXMutating(_ v: Int32)
215215
// CHECK-NEXT: var value: Int32
216216
// CHECK-NEXT: }
217217

test/Interop/Cxx/reference/Inputs/reference.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,7 @@ void setConstStaticIntRvalueRef(const int &&i) { staticInt = i; }
1616

1717
auto getFuncRef() -> int (&)() { return getStaticInt; }
1818
auto getFuncRvalueRef() -> int (&&)() { return getStaticInt; }
19+
20+
void takeConstRef(const int &value) {
21+
staticInt = value;
22+
}

test/Interop/Cxx/reference/Inputs/reference.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ auto getFuncRvalueRef() -> int (&&)();
2020
// crashing when we have an "_Atomic" type or a reference to one.
2121
void dontImportAtomicRef(_Atomic(int)&) { }
2222

23+
void takeConstRef(const int &);
24+
2325
#endif // TEST_INTEROP_CXX_REFERENCE_INPUTS_REFERENCE_H

test/Interop/Cxx/reference/reference-irgen.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ public func setCxxRef() {
3939
// CHECK: call void @{{_Z15setStaticIntRefRi|"\?setStaticIntRef@@YAXAEAH@Z"}}(i32* %{{.*}})
4040

4141
public func setCxxConstRef() {
42-
var val: CInt = 21
43-
setConstStaticIntRef(&val)
42+
let val: CInt = 21
43+
setConstStaticIntRef(val)
4444
}
4545

4646
// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main14setCxxConstRefyyF"()
@@ -55,8 +55,8 @@ public func setCxxRvalueRef() {
5555
// CHECK: call void @{{_Z21setStaticIntRvalueRefOi|"\?setStaticIntRvalueRef@@YAX\$\$QEAH@Z"}}(i32* %{{.*}})
5656

5757
public func setCxxConstRvalueRef() {
58-
var val: CInt = 21
59-
setConstStaticIntRvalueRef(&val)
58+
let val: CInt = 21
59+
setConstStaticIntRvalueRef(val)
6060
}
6161

6262
// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main20setCxxConstRvalueRefyyF"()

test/Interop/Cxx/reference/reference-module-interface.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
// CHECK: func setStaticInt(_: Int32)
99
// CHECK: func setStaticIntRef(_: inout Int32)
1010
// CHECK: func setStaticIntRvalueRef(_: inout Int32)
11-
// CHECK: func setConstStaticIntRef(_: inout Int32)
12-
// CHECK: func setConstStaticIntRvalueRef(_: inout Int32)
11+
// CHECK: func setConstStaticIntRef(_: Int32)
12+
// CHECK: func setConstStaticIntRvalueRef(_: Int32)
1313
// CHECK: func getFuncRef() -> @convention(c) () -> Int32
1414
// CHECK: func getFuncRvalueRef() -> @convention(c) () -> Int32
1515

test/Interop/Cxx/reference/reference-silgen.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ func setCxxRef() {
4444
// CHECK: apply [[REF]](%{{[0-9]+}}) : $@convention(c) (@inout Int32) -> ()
4545

4646
func setCxxConstRef() {
47-
var val: CInt = 21
48-
setConstStaticIntRef(&val)
47+
let val: CInt = 21
48+
setConstStaticIntRef(val)
4949
}
5050

5151
// CHECK: sil hidden @$s4main14setCxxConstRefyyF : $@convention(thin) () -> ()
52-
// CHECK: [[REF:%.*]] = function_ref @{{_Z20setConstStaticIntRefRKi|\?setConstStaticIntRef@@YAXAEBH@Z}} : $@convention(c) (@inout Int32) -> ()
53-
// CHECK: apply [[REF]](%{{[0-9]+}}) : $@convention(c) (@inout Int32) -> ()
52+
// CHECK: [[REF:%.*]] = function_ref @{{_Z20setConstStaticIntRefRKi|\?setConstStaticIntRef@@YAXAEBH@Z}} : $@convention(c) (@in Int32) -> ()
53+
// CHECK: apply [[REF]](%{{[0-9]+}}) : $@convention(c) (@in Int32) -> ()
5454

5555
func setCxxRvalueRef() {
5656
var val: CInt = 21
@@ -62,10 +62,10 @@ func setCxxRvalueRef() {
6262
// CHECK: apply [[REF]](%{{[0-9]+}}) : $@convention(c) (@inout Int32) -> ()
6363

6464
func setCxxConstRvalueRef() {
65-
var val: CInt = 21
66-
setConstStaticIntRvalueRef(&val)
65+
let val: CInt = 21
66+
setConstStaticIntRvalueRef(val)
6767
}
6868

6969
// CHECK: sil hidden @$s4main20setCxxConstRvalueRefyyF : $@convention(thin) () -> ()
70-
// CHECK: [[REF:%.*]] = function_ref @{{_Z26setConstStaticIntRvalueRefOKi|\?setConstStaticIntRvalueRef@@YAX\$\$QEBH@Z}} : $@convention(c) (@inout Int32) -> ()
71-
// CHECK: apply [[REF]](%{{[0-9]+}}) : $@convention(c) (@inout Int32) -> ()
70+
// CHECK: [[REF:%.*]] = function_ref @{{_Z26setConstStaticIntRvalueRefOKi|\?setConstStaticIntRvalueRef@@YAX\$\$QEBH@Z}} : $@convention(c) (@in Int32) -> ()
71+
// CHECK: apply [[REF]](%{{[0-9]+}}) : $@convention(c) (@in Int32) -> ()

test/Interop/Cxx/reference/reference.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ ReferenceTestSuite.test("pass-lvalue-reference") {
4646

4747
ReferenceTestSuite.test("pass-const-lvalue-reference") {
4848
expectNotEqual(22, getStaticInt())
49-
var val: CInt = 22
50-
setConstStaticIntRef(&val)
49+
let val: CInt = 22
50+
setConstStaticIntRef(val)
5151
expectEqual(22, getStaticInt())
5252
}
5353

@@ -60,8 +60,8 @@ ReferenceTestSuite.test("pass-rvalue-reference") {
6060

6161
ReferenceTestSuite.test("pass-const-rvalue-reference") {
6262
expectNotEqual(53, getStaticInt())
63-
var val: CInt = 53
64-
setConstStaticIntRvalueRef(&val)
63+
let val: CInt = 53
64+
setConstStaticIntRvalueRef(val)
6565
expectEqual(53, getStaticInt())
6666
}
6767

@@ -81,4 +81,10 @@ ReferenceTestSuite.test("func-rvalue-reference") {
8181
expectEqual(61, cxxF())
8282
}
8383

84+
ReferenceTestSuite.test("pod-struct-const-lvalue-reference") {
85+
expectNotEqual(getStaticInt(), 78)
86+
takeConstRef(78)
87+
expectEqual(getStaticInt(), 78)
88+
}
89+
8490
runAllTests()

test/Interop/Cxx/templates/Inputs/dependent-types.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ template<class T, class U>
5151
M<T> multipleDependentArgs(M<T> a, M<U> b) { return {a.value}; }
5252

5353
template<class T>
54-
M<T> refToDependent(const T &a) { return {a}; }
54+
M<T> refToDependent(T &a) { return {a}; }
55+
56+
template<class T>
57+
M<T> constRefToDependent(const T &a) { return {a}; }
5558

5659
// TODO: We can't import this template rdar://89028943
5760
template<class T>

0 commit comments

Comments
 (0)