Skip to content

Commit f02b298

Browse files
authored
Merge pull request #61828 from apple/egorzhdan/cxx-ir-virtual
[cxx-interop] Emit IR for virtual methods
2 parents 9a9cfab + 6ca60b0 commit f02b298

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

lib/IRGen/GenClangDecl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,17 @@ void IRGenModule::emitClangDecl(const clang::Decl *decl) {
201201
}
202202
}
203203

204+
// If something from a C++ class is used, emit all virtual methods of this
205+
// class because they might be emitted in the vtable even if not used
206+
// directly from Swift.
207+
if (auto *record = dyn_cast<clang::CXXRecordDecl>(next->getDeclContext())) {
208+
for (auto *method : record->methods()) {
209+
if (method->isVirtual()) {
210+
callback(method);
211+
}
212+
}
213+
}
214+
204215
if (auto var = dyn_cast<clang::VarDecl>(next))
205216
if (!var->isFileVarDecl())
206217
continue;

test/Interop/Cxx/class/inheritance/Inputs/module.modulemap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,8 @@ module SubTypes {
1313
module TypeAliases {
1414
header "type-aliases.h"
1515
}
16+
17+
module VirtualMethods {
18+
header "virtual-methods.h"
19+
requires cplusplus
20+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
extern "C" void puts(const char *);
2+
3+
inline void testFunctionCollected() {
4+
puts("test\n");
5+
}
6+
7+
struct Base {
8+
virtual void foo() = 0;
9+
};
10+
11+
template <class T>
12+
struct Derived : Base {
13+
inline void foo() override {
14+
testFunctionCollected();
15+
}
16+
17+
void callMe() {
18+
}
19+
};
20+
21+
using DerivedInt = Derived<int>;
22+
23+
template <class T>
24+
struct Unused : Base {
25+
inline void foo() override {
26+
}
27+
};
28+
29+
using UnusedInt = Unused<int>;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-swift-emit-ir -I %S/Inputs -enable-experimental-cxx-interop %s -validate-tbd-against-ir=none | %FileCheck %s
2+
3+
// FIXME: enable on Windows
4+
// XFAIL: OS=windows-msvc
5+
6+
import VirtualMethods
7+
8+
var x = DerivedInt()
9+
x.callMe()
10+
11+
// CHECK: define {{.*}}void @{{_ZN7DerivedIiE3fooEv|"\?foo@\?$Derived@H@@UEAAXXZ"}}
12+
// CHECK: call void @{{_Z21testFunctionCollectedv|"\?testFunctionCollected@@YAXXZ"}}
13+
14+
// CHECK: define {{.*}}void @{{_Z21testFunctionCollectedv|"\?testFunctionCollected@@YAXXZ"}}
15+
16+
// CHECK-NOT: _ZN6UnusedIiE3fooEv
17+
// CHECK-NOT: "\?foo@\?$Unused@H@@UEAAXXZ"

0 commit comments

Comments
 (0)