Skip to content

Commit f79b73a

Browse files
authored
Merge pull request #79288 from swiftlang/gaborh/import-static-factory-as-initializer
[cxx-interop] Support importing static factories as initializers
2 parents 974767e + 2f46d55 commit f79b73a

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3946,6 +3946,11 @@ namespace {
39463946
// FIXME: Poor location info.
39473947
auto nameLoc = Impl.importSourceLoc(decl->getLocation());
39483948

3949+
if (auto method = dyn_cast<clang::CXXMethodDecl>(decl);
3950+
method && method->isStatic() && name.getBaseName().isConstructor()) {
3951+
return importGlobalAsInitializer(
3952+
decl, name, dc, importedName.getInitKind(), correctSwiftName);
3953+
}
39493954
AbstractFunctionDecl *result = nullptr;
39503955
if (auto *ctordecl = dyn_cast<clang::CXXConstructorDecl>(decl)) {
39513956
// Don't import copy constructor or move constructor -- these will be
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#pragma once
2+
3+
struct __attribute__((swift_attr("import_reference")))
4+
__attribute__((swift_attr("retain:retain")))
5+
__attribute__((swift_attr("release:release"))) ImportWithCtor {
6+
int value = 0;
7+
int param1 = 0;
8+
int param2 = 0;
9+
10+
__attribute__((swift_name("init()")))
11+
__attribute__((swift_attr("returns_retained")))
12+
static ImportWithCtor * _Nonnull create() {
13+
return new ImportWithCtor{1};
14+
}
15+
16+
__attribute__((swift_name("init(_:)")))
17+
__attribute__((swift_attr("returns_retained")))
18+
static ImportWithCtor * _Nonnull create(int x) {
19+
return new ImportWithCtor{1, x};
20+
}
21+
22+
__attribute__((swift_name("init(_:_:)")))
23+
__attribute__((swift_attr("returns_retained")))
24+
static ImportWithCtor * _Nonnull create(int x, int y) {
25+
return new ImportWithCtor{1, x, y};
26+
}
27+
28+
__attribute__((swift_name("init(_:_:_:)")))
29+
__attribute__((swift_attr("returns_unretained")))
30+
static ImportWithCtor * _Nonnull create(int x, int y, int z) {
31+
return new ImportWithCtor{0, x, y};
32+
}
33+
};
34+
35+
inline void retain(ImportWithCtor * _Nonnull x) {
36+
x->value++;
37+
}
38+
39+
inline void release(ImportWithCtor * _Nonnull x) {
40+
if (!--x->value)
41+
delete x;
42+
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
module Constructor {
2+
header "constructor.h"
3+
requires cplusplus
4+
}
5+
16
module POD {
27
header "pod.h"
38
requires cplusplus
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-run-simple-swift(-I %S/Inputs -Xfrontend -enable-experimental-cxx-interop -Xfrontend -disable-availability-checking)
2+
// REQUIRES: executable_test
3+
4+
import Constructor
5+
import StdlibUnittest
6+
7+
var ForeignRefCtorSuite = TestSuite("ForeignRef Ctor")
8+
9+
ForeignRefCtorSuite.test("ImportStaticFactoryAsInitializer") {
10+
let x = ImportWithCtor()
11+
expectEqual(x.param1, 0)
12+
expectEqual(x.param2, 0)
13+
let y = x
14+
let z = ImportWithCtor(1)
15+
expectEqual(z.param1, 1)
16+
expectEqual(z.param2, 0)
17+
let z2 = ImportWithCtor(2, 3)
18+
expectEqual(z2.param1, 2)
19+
expectEqual(z2.param2, 3)
20+
let z3 = ImportWithCtor(2, 3, 4)
21+
expectEqual(z3.param1, 2)
22+
expectEqual(z3.param2, 3)
23+
}
24+
25+
runAllTests()

0 commit comments

Comments
 (0)