xref: /llvm-project/clang/test/CodeGenCXX/modules-vtable.cppm (revision 6bb63002fca8a7cfa9ff8ffd86da4c2ca3d98a3b)
1// REQUIRES: !system-windows
2
3// RUN: rm -rf %t
4// RUN: split-file %s %t
5// RUN: cd %t
6//
7// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-module-interface \
8// RUN:     %t/Mod.cppm -o %t/Mod.pcm
9//
10// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/Mod.pcm \
11// RUN:     -emit-llvm -o - | FileCheck %t/Mod.cppm
12// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -fmodule-file=Mod=%t/Mod.pcm \
13// RUN:     %t/Use.cpp  -emit-llvm -o - | FileCheck %t/Use.cpp
14//
15// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-module-interface \
16// RUN:     %t/Mod.cppm -o %t/Mod.pcm -DKEY_FUNCTION_INLINE
17//
18// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/Mod.pcm \
19// RUN:     -emit-llvm -o - | FileCheck %t/Mod.cppm -check-prefix=CHECK-INLINE
20// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -fmodule-file=Mod=%t/Mod.pcm \
21// RUN:     %t/Use.cpp  -emit-llvm -o - | FileCheck %t/Use.cpp -check-prefix=CHECK-INLINE
22//
23// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -emit-module-interface \
24// RUN:     %t/M-A.cppm -o %t/M-A.pcm
25// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -fmodule-file=M:A=%t/M-A.pcm \
26// RUN:     %t/M-B.cppm  -emit-llvm -o - | FileCheck %t/M-B.cppm
27// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 \
28// RUN:     %t/M-A.pcm  -emit-llvm -o - | FileCheck %t/M-A.cppm
29
30//--- Mod.cppm
31export module Mod;
32
33export class Base {
34public:
35    virtual ~Base();
36};
37#ifdef KEY_FUNCTION_INLINE
38inline
39#endif
40Base::~Base() {}
41
42// CHECK: @_ZTVW3Mod4Base = unnamed_addr constant
43// CHECK: @_ZTIW3Mod4Base = constant
44// CHECK: @_ZTSW3Mod4Base = constant
45
46// With the new Itanium C++ ABI, the linkage of vtables in modules don't need to be linkonce ODR.
47// CHECK-INLINE: @_ZTVW3Mod4Base = {{.*}}unnamed_addr constant
48// CHECK-INLINE: @_ZTIW3Mod4Base = {{.*}}constant
49// CHECK-INLINE: @_ZTSW3Mod4Base = {{.*}}constant
50
51module :private;
52int private_use() {
53    Base base;
54    return 43;
55}
56
57//--- Use.cpp
58import Mod;
59int use() {
60    Base* base = new Base();
61    return 43;
62}
63
64// CHECK-NOT: @_ZTIW3Mod4Base
65// CHECK-NOT: @_ZTSW3Mod4Base
66// CHECK: @_ZTVW3Mod4Base = external
67
68// CHECK-INLINE-NOT: @_ZTIW3Mod4Base
69// CHECK-INLINE-NOT: @_ZTSW3Mod4Base
70// CHECK-INLINE: @_ZTVW3Mod4Base = external
71
72// Check the case that the declaration of the key function comes from another
73// module unit but the definition of the key function comes from the current
74// module unit.
75
76//--- M-A.cppm
77export module M:A;
78export class C {
79public:
80    virtual ~C();
81};
82
83int a_use() {
84    C c;
85    return 43;
86}
87
88// CHECK: @_ZTVW1M1C = unnamed_addr constant
89// CHECK: @_ZTIW1M1C = constant
90// CHECK: @_ZTSW1M1C = constant
91
92//--- M-B.cppm
93export module M:B;
94import :A;
95
96C::~C() {}
97
98int b_use() {
99    C c;
100    return 43;
101}
102
103// CHECK: @_ZTVW1M1C = external
104// CHECK-NOT: @_ZTIW1M1C
105// CHECK-NOT: @_ZTSW1M1C
106