Skip to content

Commit c88a3d6

Browse files
authored
Merge pull request #41658 from zoecarver/import-ref-to-template-return-tyeps
[cxx-interop] Support references to template types.
2 parents e4c51ba + b839741 commit c88a3d6

File tree

4 files changed

+33
-0
lines changed

4 files changed

+33
-0
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1863,6 +1863,17 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
18631863
dyn_cast<clang::TemplateTypeParmType>(clangDecl->getReturnType())) {
18641864
importedType = {findGenericTypeInGenericDecls(templateType, genericParams),
18651865
false};
1866+
} else if ((isa<clang::PointerType>(clangDecl->getReturnType()) ||
1867+
isa<clang::ReferenceType>(clangDecl->getReturnType())) &&
1868+
isa<clang::TemplateTypeParmType>(clangDecl->getReturnType()->getPointeeType())) {
1869+
auto pointeeType = clangDecl->getReturnType()->getPointeeType();
1870+
auto templateParamType = cast<clang::TemplateTypeParmType>(pointeeType);
1871+
PointerTypeKind pointerKind = pointeeType.getQualifiers().hasConst()
1872+
? PTK_UnsafePointer
1873+
: PTK_UnsafeMutablePointer;
1874+
auto genericType =
1875+
findGenericTypeInGenericDecls(templateParamType, genericParams);
1876+
importedType = {genericType->wrapInPointer(pointerKind), false};
18661877
} else if (!(isa<clang::RecordType>(clangDecl->getReturnType()) ||
18671878
isa<clang::TemplateSpecializationType>(clangDecl->getReturnType())) ||
18681879
// TODO: we currently don't lazily load operator return types, but

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,10 @@ void dontImportAtomicRef(_Atomic(int)&) { }
2828

2929
void takeConstRef(const int &);
3030

31+
template<class T>
32+
T &refToTemplate(T &t) { return t; }
33+
34+
template<class T>
35+
const T &constRefToTemplate(const T &t) { return t; }
36+
3137
#endif // TEST_INTEROP_CXX_REFERENCE_INPUTS_REFERENCE_H

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// CHECK: func setConstStaticIntRvalueRef(_: Int32)
1313
// CHECK: func getFuncRef() -> @convention(c) () -> Int32
1414
// CHECK: func getFuncRvalueRef() -> @convention(c) () -> Int32
15+
// CHECK: func refToTemplate<T>(_ t: inout T) -> UnsafeMutablePointer<T>
16+
// CHECK: func constRefToTemplate<T>(_ t: T) -> UnsafePointer<T>
1517

1618
// CHECK-NOT: refToDependent
1719
// CHECK-NOT: dontImportAtomicRef

test/Interop/Cxx/reference/reference.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,18 @@ ReferenceTestSuite.test("pod-struct-const-lvalue-reference") {
8787
expectEqual(getStaticInt(), 78)
8888
}
8989

90+
ReferenceTestSuite.test("reference to template") {
91+
var val: CInt = 53
92+
let ref = refToTemplate(&val)
93+
expectEqual(53, ref.pointee)
94+
ref.pointee = 42
95+
expectEqual(42, val)
96+
}
97+
98+
ReferenceTestSuite.test("const reference to template") {
99+
var val: CInt = 53
100+
let ref = constRefToTemplate(val)
101+
expectEqual(53, ref.pointee)
102+
}
103+
90104
runAllTests()

0 commit comments

Comments
 (0)