xref: /llvm-project/clang/test/CXX/module/basic/basic.def.odr/p4.cppm (revision fb2c9d940ad87e6ae09e06c6915e0c925a4f87ec)
1// RUN: rm -rf %t
2// RUN: mkdir %t
3// RUN: split-file %s %t
4//
5// RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %t/Module.cppm --implicit-check-not unused
6//
7// RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple -emit-module-interface -o %t/Module.pcm
8// RUN: %clang_cc1 -std=c++20 %t/module.cpp -triple %itanium_abi_triple -fmodule-file=Module=%t/Module.pcm -emit-llvm -o - | FileCheck %t/module.cpp --implicit-check-not=unused --implicit-check-not=global_module
9//
10// RUN: %clang_cc1 -std=c++20 %t/user.cpp -triple %itanium_abi_triple -fmodule-file=Module=%t/Module.pcm -emit-llvm -o - | FileCheck %t/user.cpp --implicit-check-not=unused --implicit-check-not=global_module
11
12//--- Module.cppm
13// CHECK-DAG: @extern_var_global_module = external {{(dso_local )?}}global
14// CHECK-DAG: @inline_var_global_module = linkonce_odr {{(dso_local )?}}global
15// CHECK-DAG: @_ZL24static_var_global_module = internal global
16// CHECK-DAG: @_ZL23const_var_global_module = internal constant
17//
18// With strong-ownership, the module is mangled into exported symbols
19// that are attached to a named module.
20// CHECK-DAG: @_ZW6Module19extern_var_exported = external {{(dso_local )?}}global
21// FIXME: Should this be 'weak_odr global'? Presumably it must be, since we
22// can discard this global and its initializer (if any), and other TUs are not
23// permitted to run the initializer for this variable.
24// CHECK-DAG: @_ZW6Module19inline_var_exported = linkonce_odr {{(dso_local )?}}global
25// CHECK-DAG: @_ZW6Module18const_var_exported = {{(dso_local )?}}constant
26//
27// CHECK-DAG: @_ZW6Module25extern_var_module_linkage = external {{(dso_local )?}}global
28// FIXME: Should this be 'weak_odr global'? Presumably it must be, since we
29// can discard this global and its initializer (if any), and other TUs are not
30// permitted to run the initializer for this variable.
31// CHECK-DAG: @_ZW6Module25inline_var_module_linkage = linkonce_odr {{(dso_local )?}}global
32// CHECK-DAG: @_ZL25static_var_module_linkage = internal
33// CHECK-DAG: @_ZW6Module24const_var_module_linkage = {{(dso_local )?}}constant
34//
35// CHECK-DAG: @_ZW6Module25unused_var_module_linkage = {{(dso_local )?}}global i32 4
36
37module;
38
39static void unused_static_global_module() {}
40static void used_static_global_module() {}
41
42inline void unused_inline_global_module() {}
43inline void used_inline_global_module() {}
44
45extern int extern_var_global_module;
46inline int inline_var_global_module;
47static int static_var_global_module;
48const int const_var_global_module = 3;
49
50// CHECK: define {{(dso_local )?}}void {{.*}}@_Z23noninline_global_modulev
51void noninline_global_module() {
52  // FIXME: This should be promoted to module linkage and given a
53  // module-mangled name, if it's called from an inline function within
54  // the module interface.
55  // (We should try to avoid this when it's not reachable from outside
56  // the module interface unit.)
57  // CHECK: define internal {{.*}}@_ZL25used_static_global_modulev
58  used_static_global_module();
59  // CHECK: define linkonce_odr {{.*}}@_Z25used_inline_global_modulev
60  used_inline_global_module();
61
62  (void)&extern_var_global_module;
63  (void)&inline_var_global_module;
64  (void)&static_var_global_module;
65  (void)&const_var_global_module;
66}
67
68export module Module;
69
70export {
71  inline void unused_inline_exported() {}
72  inline void used_inline_exported() {}
73
74  extern int extern_var_exported;
75  inline int inline_var_exported;
76  const int const_var_exported = 3;
77
78  // CHECK: define {{(dso_local )?}}void {{.*}}@_ZW6Module18noninline_exportedv
79  void noninline_exported() {
80    (void)&extern_var_exported;
81    (void)&inline_var_exported;
82    (void)&const_var_exported;
83  }
84}
85
86static void unused_static_module_linkage() {}
87
88static void used_static_module_linkage() {}
89
90inline void unused_inline_module_linkage() {}
91inline void used_inline_module_linkage() {}
92
93extern int extern_var_module_linkage;
94inline int inline_var_module_linkage;
95static int static_var_module_linkage;
96const int const_var_module_linkage = 3;
97
98// CHECK: define {{(dso_local )?}}void {{.*}}@_ZW6Module24noninline_module_linkagev
99// CHECK: define {{.*}}void {{.*}}@_ZL26used_static_module_linkagev
100void noninline_module_linkage() {
101  used_static_module_linkage();
102  // CHECK: define linkonce_odr {{.*}}@_ZW6Module26used_inline_module_linkagev
103  used_inline_module_linkage();
104
105  (void)&extern_var_module_linkage;
106  (void)&inline_var_module_linkage;
107  (void)&static_var_module_linkage;
108  (void)&const_var_module_linkage;
109}
110
111int unused_var_module_linkage = 4;
112static int unused_static_var_module_linkage = 5;
113inline int unused_inline_var_module_linkage = 6;
114const int unused_const_var_module_linkage = 7;
115
116struct a {
117  struct b {};
118  struct c {};
119};
120// CHECK: define {{(dso_local )?}}void @_ZW6Module1fNS_1a1bENS0_1cE(
121void f(a::b, a::c) {}
122
123//--- module.cpp
124
125// CHECK-DAG: @_ZW6Module19extern_var_exported = external {{(dso_local )?}}global
126// CHECK-DAG: @_ZW6Module19inline_var_exported = linkonce_odr {{(dso_local )?}}global
127// CHECK-DAG: @_ZW6Module18const_var_exported = available_externally {{(dso_local )?}}constant i32 3,
128//
129// CHECK-DAG: @_ZW6Module25extern_var_module_linkage = external {{(dso_local )?}}global
130// CHECK-DAG: @_ZW6Module25inline_var_module_linkage = linkonce_odr {{(dso_local )?}}global
131// CHECK-DAG: @_ZW6Module24const_var_module_linkage = available_externally {{(dso_local )?}}constant i32 3,
132
133module Module;
134
135void use() {
136  // CHECK: define linkonce_odr {{.*}}@_ZW6Module20used_inline_exportedv
137  used_inline_exported();
138  // CHECK: declare {{.*}}@_ZW6Module18noninline_exportedv
139  noninline_exported();
140
141  (void)&extern_var_exported;
142  (void)&inline_var_exported;
143  (void)&const_var_exported;
144
145  // CHECK: define linkonce_odr {{.*}}@_ZW6Module26used_inline_module_linkagev
146  used_inline_module_linkage();
147
148  // CHECK: declare {{.*}}@_ZW6Module24noninline_module_linkagev
149  noninline_module_linkage();
150
151  (void)&extern_var_module_linkage;
152  (void)&inline_var_module_linkage;
153
154  (void)&const_var_module_linkage; // FIXME: will be visible after P2788R0
155}
156
157//--- user.cpp
158
159// CHECK-DAG: @_ZW6Module19extern_var_exported = external {{(dso_local )?}}global
160// CHECK-DAG: @_ZW6Module19inline_var_exported = linkonce_odr {{(dso_local )?}}global
161// CHECK-DAG: @_ZW6Module18const_var_exported = available_externally {{(dso_local )?}}constant i32 3
162
163import Module;
164
165void use() {
166  // CHECK: define linkonce_odr {{.*}}@_ZW6Module20used_inline_exportedv
167  used_inline_exported();
168  // CHECK: declare {{.*}}@_ZW6Module18noninline_exportedv
169  noninline_exported();
170
171  (void)&extern_var_exported;
172  (void)&inline_var_exported;
173  (void)&const_var_exported;
174
175  // Internal-linkage declarations are not visible here.
176  // Module-linkage declarations are not visible here.
177}
178