Skip to content

[cxx-interop] Import const T& parameters as T. #41611

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lib/ClangImporter/ImportType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1967,15 +1967,17 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
cast<clang::TemplateTypeParmType>(paramTy->getPointeeType());
swiftParamTy =
findGenericTypeInGenericDecls(templateParamType, genericParams);
isInOut = true;
if (!paramTy->getPointeeType().isConstQualified())
isInOut = true;
} else if (auto *templateParamType =
dyn_cast<clang::TemplateTypeParmType>(paramTy)) {
swiftParamTy =
findGenericTypeInGenericDecls(templateParamType, genericParams);
} else {
if (auto refType = dyn_cast<clang::ReferenceType>(paramTy)) {
paramTy = refType->getPointeeType();
isInOut = true;
if (!paramTy.isConstQualified())
isInOut = true;
}
auto importedType = importType(paramTy, importKind, allowNSUIntegerAsInt,
Bridgeability::Full, OptionalityOfParam);
Expand Down
8 changes: 8 additions & 0 deletions lib/SIL/IR/SILFunctionType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,14 @@ static bool isClangTypeMoreIndirectThanSubstType(TypeConverter &TC,

return true;
}

// Pass C++ const reference types indirectly. Right now there's no way to
// express immutable borrowed params, so we have to have this hack.
// Eventually, we should just express these correctly: rdar://89647503
if (clangTy->isReferenceType() &&
clangTy->getPointeeType().isConstQualified())
return true;

return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@
// CHECK-NEXT: init()
// CHECK-NEXT: init(value: Int32)
// CHECK-NEXT: mutating func getXMutating() -> UnsafePointer<Int32>
// CHECK-NEXT: mutating func setXMutating(_ v: inout Int32)
// CHECK-NEXT: mutating func setXMutating(_ v: Int32)
// CHECK-NEXT: var value: Int32
// CHECK-NEXT: }

Expand Down
4 changes: 4 additions & 0 deletions test/Interop/Cxx/reference/Inputs/reference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ void setConstStaticIntRvalueRef(const int &&i) { staticInt = i; }

auto getFuncRef() -> int (&)() { return getStaticInt; }
auto getFuncRvalueRef() -> int (&&)() { return getStaticInt; }

void takeConstRef(const int &value) {
staticInt = value;
}
2 changes: 2 additions & 0 deletions test/Interop/Cxx/reference/Inputs/reference.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ auto getFuncRvalueRef() -> int (&&)();
// crashing when we have an "_Atomic" type or a reference to one.
void dontImportAtomicRef(_Atomic(int)&) { }

void takeConstRef(const int &);

#endif // TEST_INTEROP_CXX_REFERENCE_INPUTS_REFERENCE_H
8 changes: 4 additions & 4 deletions test/Interop/Cxx/reference/reference-irgen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ public func setCxxRef() {
// CHECK: call void @{{_Z15setStaticIntRefRi|"\?setStaticIntRef@@YAXAEAH@Z"}}(i32* %{{.*}})

public func setCxxConstRef() {
var val: CInt = 21
setConstStaticIntRef(&val)
let val: CInt = 21
setConstStaticIntRef(val)
}

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

public func setCxxConstRvalueRef() {
var val: CInt = 21
setConstStaticIntRvalueRef(&val)
let val: CInt = 21
setConstStaticIntRvalueRef(val)
}

// CHECK: define {{(protected |dllexport )?}}swiftcc void @"$s4main20setCxxConstRvalueRefyyF"()
Expand Down
4 changes: 2 additions & 2 deletions test/Interop/Cxx/reference/reference-module-interface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
// CHECK: func setStaticInt(_: Int32)
// CHECK: func setStaticIntRef(_: inout Int32)
// CHECK: func setStaticIntRvalueRef(_: inout Int32)
// CHECK: func setConstStaticIntRef(_: inout Int32)
// CHECK: func setConstStaticIntRvalueRef(_: inout Int32)
// CHECK: func setConstStaticIntRef(_: Int32)
// CHECK: func setConstStaticIntRvalueRef(_: Int32)
// CHECK: func getFuncRef() -> @convention(c) () -> Int32
// CHECK: func getFuncRvalueRef() -> @convention(c) () -> Int32

Expand Down
16 changes: 8 additions & 8 deletions test/Interop/Cxx/reference/reference-silgen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ func setCxxRef() {
// CHECK: apply [[REF]](%{{[0-9]+}}) : $@convention(c) (@inout Int32) -> ()

func setCxxConstRef() {
var val: CInt = 21
setConstStaticIntRef(&val)
let val: CInt = 21
setConstStaticIntRef(val)
}

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

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

func setCxxConstRvalueRef() {
var val: CInt = 21
setConstStaticIntRvalueRef(&val)
let val: CInt = 21
setConstStaticIntRvalueRef(val)
}

// CHECK: sil hidden @$s4main20setCxxConstRvalueRefyyF : $@convention(thin) () -> ()
// CHECK: [[REF:%.*]] = function_ref @{{_Z26setConstStaticIntRvalueRefOKi|\?setConstStaticIntRvalueRef@@YAX\$\$QEBH@Z}} : $@convention(c) (@inout Int32) -> ()
// CHECK: apply [[REF]](%{{[0-9]+}}) : $@convention(c) (@inout Int32) -> ()
// CHECK: [[REF:%.*]] = function_ref @{{_Z26setConstStaticIntRvalueRefOKi|\?setConstStaticIntRvalueRef@@YAX\$\$QEBH@Z}} : $@convention(c) (@in Int32) -> ()
// CHECK: apply [[REF]](%{{[0-9]+}}) : $@convention(c) (@in Int32) -> ()
14 changes: 10 additions & 4 deletions test/Interop/Cxx/reference/reference.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ ReferenceTestSuite.test("pass-lvalue-reference") {

ReferenceTestSuite.test("pass-const-lvalue-reference") {
expectNotEqual(22, getStaticInt())
var val: CInt = 22
setConstStaticIntRef(&val)
let val: CInt = 22
setConstStaticIntRef(val)
expectEqual(22, getStaticInt())
}

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

ReferenceTestSuite.test("pass-const-rvalue-reference") {
expectNotEqual(53, getStaticInt())
var val: CInt = 53
setConstStaticIntRvalueRef(&val)
let val: CInt = 53
setConstStaticIntRvalueRef(val)
expectEqual(53, getStaticInt())
}

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

ReferenceTestSuite.test("pod-struct-const-lvalue-reference") {
expectNotEqual(getStaticInt(), 78)
takeConstRef(78)
expectEqual(getStaticInt(), 78)
}

runAllTests()
5 changes: 4 additions & 1 deletion test/Interop/Cxx/templates/Inputs/dependent-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ template<class T, class U>
M<T> multipleDependentArgs(M<T> a, M<U> b) { return {a.value}; }

template<class T>
M<T> refToDependent(const T &a) { return {a}; }
M<T> refToDependent(T &a) { return {a}; }

template<class T>
M<T> constRefToDependent(const T &a) { return {a}; }

// TODO: We can't import this template rdar://89028943
template<class T>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
// CHECK: func multipleDependentArgs<T, U>(_ a: Any, _ b: Any, T: T.Type, U: U.Type) -> Any
// CHECK: func refToDependent<T>(_ a: inout T) -> Any
// CHECK: func dependentRef<T>(_ a: inout Any, T: T.Type) -> Any
// CHECK: func dependentRefAndRefInferred<T>(_ a: inout Any, _ b: inout T) -> Any
// CHECK: func dependentRefAndRefInferred<T>(_ a: Any, _ b: inout T) -> Any
5 changes: 5 additions & 0 deletions test/Interop/Cxx/templates/dependent-types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ DependentTypesTestSuite.test("Takes inout argument and returns dependent type.")
expectEqual(m.getValue(), 42)
}

DependentTypesTestSuite.test("Takes const ref and returns dependent type.") {
let m = constRefToDependent(42) as! M<Int>
expectEqual(m.getValue(), 42)
}


// We still have some problems calling methods on Windows: SR-13129 and rdar://88391102
#if !os(Windows)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// CHECK: }

// CHECK: func lvalueReference<T>(_ ref: inout T)
// CHECK: func constLvalueReference<T>(_: inout T)
// CHECK: func constLvalueReference<T>(_: T)
// CHECK: func forwardingReference<T>(_: inout T)
// CHECK: func PointerTemplateParameter<T>(_: UnsafeMutablePointer<T>)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// CHECK: mutating func passThroughConst<T>(_ val: T) -> T
// CHECK: func passThroughOnConst<T>(_ val: T) -> T
// CHECK: func passThroughConstOnConst<T>(_ val: T) -> T
// CHECK: mutating func doNothingConstRef<T>(_ val: inout T)
// CHECK: mutating func doNothingConstRef<T>(_ val: T)
// CHECK: mutating func make42Ref<T>(_ val: inout T)
// CHECK: }

Expand Down
8 changes: 4 additions & 4 deletions test/Interop/Cxx/templates/member-templates-silgen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import MemberTemplates
// CHECK: [[ADD_ALL:%.*]] = function_ref @_ZN18HasMemberTemplates6addAllIiiEEiiT_T0_ : $@convention(cxx_method) (Int32, Int32, Int32, @inout HasMemberTemplates) -> Int32
// CHECK: apply [[ADD_ALL]]({{.*}}) : $@convention(cxx_method) (Int32, Int32, Int32, @inout HasMemberTemplates) -> Int32

// CHECK: [[DO_NOTHING:%.*]] = function_ref @_ZN18HasMemberTemplates17doNothingConstRefIiEEvRKT_ : $@convention(cxx_method) (@inout Int32, @inout HasMemberTemplates) -> ()
// CHECK: apply [[DO_NOTHING]]({{.*}}) : $@convention(cxx_method) (@inout Int32, @inout HasMemberTemplates) -> ()
// CHECK: [[DO_NOTHING:%.*]] = function_ref @_ZN18HasMemberTemplates17doNothingConstRefIiEEvRKT_ : $@convention(cxx_method) (@in Int32, @inout HasMemberTemplates) -> ()
// CHECK: apply [[DO_NOTHING]]({{.*}}) : $@convention(cxx_method) (@in Int32, @inout HasMemberTemplates) -> ()

// CHECK-LABEL: end sil function '$s4main9basicTestyyF'
func basicTest() {
Expand All @@ -26,7 +26,7 @@ func basicTest() {
obj.addSameTypeParams(i, i)
obj.addMixedTypeParams(i, i)
obj.addAll(i, i, i)
obj.doNothingConstRef(&i)
obj.doNothingConstRef(i)
}

// CHECK-LABEL: sil [clang HasMemberTemplates.addSameTypeParams] @_ZN18HasMemberTemplates17addSameTypeParamsIiEET_S1_S1_ : $@convention(cxx_method) (Int32, Int32, @inout HasMemberTemplates) -> Int32
Expand All @@ -35,7 +35,7 @@ func basicTest() {

// CHECK-LABEL: sil [clang HasMemberTemplates.addAll] @_ZN18HasMemberTemplates6addAllIiiEEiiT_T0_ : $@convention(cxx_method) (Int32, Int32, Int32, @inout HasMemberTemplates) -> Int32

// CHECK-LABEL: sil [clang HasMemberTemplates.doNothingConstRef] @_ZN18HasMemberTemplates17doNothingConstRefIiEEvRKT_ : $@convention(cxx_method) (@inout Int32, @inout HasMemberTemplates) -> ()
// CHECK-LABEL: sil [clang HasMemberTemplates.doNothingConstRef] @_ZN18HasMemberTemplates17doNothingConstRefIiEEvRKT_ : $@convention(cxx_method) (@in Int32, @inout HasMemberTemplates) -> ()

// CHECK-LABEL: sil hidden @$s4main12testSetValueyyF : $@convention(thin) () -> ()

Expand Down