Skip to content

Commit 02b5118

Browse files
committed
[cxx-interop] Correctly import static function templates.
Handle static members the same way we handle other member function templates. Also, set the "static"ness of the new (specialized) function decl.
1 parent f9e3f29 commit 02b5118

File tree

4 files changed

+46
-2
lines changed

4 files changed

+46
-2
lines changed

lib/Sema/CSApply.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ static ConcreteDeclRef generateDeclRefForSpecializedCXXFunctionTemplate(
121121
// In either case, we only want the result of that function type because that
122122
// is the function type with the generic params that need to be substituted:
123123
// (Generic) -> CType
124-
if (isa<ConstructorDecl>(oldDecl) || oldDecl->isInstanceMember())
124+
if (isa<ConstructorDecl>(oldDecl) || oldDecl->isInstanceMember() ||
125+
oldDecl->isStatic())
125126
newFnType = cast<FunctionType>(newFnType->getResult().getPointer());
126127
SmallVector<ParamDecl *, 4> newParams;
127128
unsigned i = 0;
@@ -162,6 +163,10 @@ static ConcreteDeclRef generateDeclRefForSpecializedCXXFunctionTemplate(
162163
/*Async=*/false, oldDecl->hasThrows(), newParamList,
163164
newFnType->getResult(), /*GenericParams=*/nullptr,
164165
oldDecl->getDeclContext(), specialized);
166+
if (oldDecl->isStatic()) {
167+
newFnDecl->setStatic();
168+
newFnDecl->setImportAsStaticMember();
169+
}
165170
newFnDecl->setSelfAccessKind(cast<FuncDecl>(oldDecl)->getSelfAccessKind());
166171
return ConcreteDeclRef(newFnDecl);
167172
}

test/Interop/Cxx/templates/Inputs/member-templates.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,10 @@ template <class T> struct TemplateClassWithMemberTemplates {
3333

3434
using IntWrapper = TemplateClassWithMemberTemplates<int>;
3535

36-
#endif // TEST_INTEROP_CXX_TEMPLATES_INPUTS_MEMBER_TEMPLATES_H
36+
struct HasStaticMemberTemplates {
37+
template <class T> static T add(T a, T b) { return a + b; }
38+
template <class T, class U> static T addTwoTemplates(T a, U b) { return a + b; }
39+
template <class T> static T removeReference(T &a) { return a; }
40+
};
41+
42+
#endif // TEST_INTEROP_CXX_TEMPLATES_INPUTS_MEMBER_TEMPLATES_H

test/Interop/Cxx/templates/member-templates-module-interface.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,10 @@
1919
// CHECK: }
2020

2121
// CHECK: typealias IntWrapper = __CxxTemplateInst32TemplateClassWithMemberTemplatesIiE
22+
23+
// CHECK: struct HasStaticMemberTemplates {
24+
// CHECK: init()
25+
// CHECK: static func add<T>(_ a: T, _ b: T) -> T
26+
// CHECK: static func addTwoTemplates<T, U>(_ a: T, _ b: U) -> T
27+
// CHECK: static func removeReference<T>(_ a: UnsafeMutablePointer<T>) -> T
28+
// CHECK: }

test/Interop/Cxx/templates/member-templates-silgen.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,29 @@ func testSetValue() {
4747
var w = IntWrapper(11)
4848
w.setValue(42)
4949
}
50+
51+
// CHECK-LABEL: sil hidden @$s4main17testStaticMembersyyF : $@convention(thin) () -> ()
52+
53+
// CHECK: [[ADD_FN:%.*]] = function_ref @_ZN24HasStaticMemberTemplates3addIlEET_S1_S1_ : $@convention(c) (Int, Int) -> Int
54+
// CHECK: apply [[ADD_FN]]({{.*}}) : $@convention(c) (Int, Int) -> Int
55+
56+
// CHECK: [[ADD_TWO_TEMPLATES_FN:%.*]] = function_ref @_ZN24HasStaticMemberTemplates15addTwoTemplatesIlcEET_S1_T0_ : $@convention(c) (Int, Int8) -> Int
57+
// CHECK: apply [[ADD_TWO_TEMPLATES_FN]]({{.*}}) : $@convention(c) (Int, Int8) -> Int
58+
59+
// CHECK: [[REMOVE_REFERENCE_FN:%.*]] = function_ref @_ZN24HasStaticMemberTemplates15removeReferenceIlEET_RS1_ : $@convention(c) (UnsafeMutablePointer<Int>) -> Int
60+
// CHECK: apply [[REMOVE_REFERENCE_FN]]({{.*}}) : $@convention(c) (UnsafeMutablePointer<Int>) -> Int
61+
62+
// CHECK-LABEL: end sil function '$s4main17testStaticMembersyyF'
63+
func testStaticMembers() {
64+
var x: Int = 0
65+
let y: CChar = 0
66+
HasStaticMemberTemplates.add(x, x)
67+
HasStaticMemberTemplates.addTwoTemplates(x, y)
68+
HasStaticMemberTemplates.removeReference(&x)
69+
}
70+
71+
// CHECK: sil hidden_external [clang HasStaticMemberTemplates._ZN24HasStaticMemberTemplates3addIlEET_S1_S1_] @_ZN24HasStaticMemberTemplates3addIlEET_S1_S1_ : $@convention(c) (Int, Int) -> Int
72+
73+
// CHECK: sil hidden_external [clang HasStaticMemberTemplates._ZN24HasStaticMemberTemplates15addTwoTemplatesIlcEET_S1_T0_] @_ZN24HasStaticMemberTemplates15addTwoTemplatesIlcEET_S1_T0_ : $@convention(c) (Int, Int8) -> Int
74+
75+
// CHECK: sil hidden_external [clang HasStaticMemberTemplates._ZN24HasStaticMemberTemplates15removeReferenceIlEET_RS1_] @_ZN24HasStaticMemberTemplates15removeReferenceIlEET_RS1_ : $@convention(c) (UnsafeMutablePointer<Int>) -> Int

0 commit comments

Comments
 (0)