aboutsummaryrefslogtreecommitdiff
path: root/clang/test/CXX/module/basic/basic.def.odr/p4.cppm
blob: 7e88cbe78b4e37f1fa1c0053f330dfddc5b8c5da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: split-file %s %t
//
// RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %t/Module.cppm --implicit-check-not unused
//
// RUN: %clang_cc1 -std=c++20 %t/Module.cppm -triple %itanium_abi_triple -emit-module-interface -o %t/Module.pcm
// 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
//
// 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

//--- Module.cppm
// CHECK-DAG: @extern_var_global_module = external {{(dso_local )?}}global
// CHECK-DAG: @inline_var_global_module = linkonce_odr {{(dso_local )?}}global
// CHECK-DAG: @_ZL24static_var_global_module = internal global
// CHECK-DAG: @_ZL23const_var_global_module = internal constant
//
// With strong-ownership, the module is mangled into exported symbols
// that are attached to a named module.
// CHECK-DAG: @_ZW6Module19extern_var_exported = external {{(dso_local )?}}global
// FIXME: Should this be 'weak_odr global'? Presumably it must be, since we
// can discard this global and its initializer (if any), and other TUs are not
// permitted to run the initializer for this variable.
// CHECK-DAG: @_ZW6Module19inline_var_exported = linkonce_odr {{(dso_local )?}}global
// CHECK-DAG: @_ZW6Module18const_var_exported = {{(dso_local )?}}constant
//
// CHECK-DAG: @_ZW6Module25extern_var_module_linkage = external {{(dso_local )?}}global
// FIXME: Should this be 'weak_odr global'? Presumably it must be, since we
// can discard this global and its initializer (if any), and other TUs are not
// permitted to run the initializer for this variable.
// CHECK-DAG: @_ZW6Module25inline_var_module_linkage = linkonce_odr {{(dso_local )?}}global
// CHECK-DAG: @_ZL25static_var_module_linkage = internal
// CHECK-DAG: @_ZW6Module24const_var_module_linkage = {{(dso_local )?}}constant
//
// CHECK-DAG: @_ZW6Module25unused_var_module_linkage = {{(dso_local )?}}global i32 4

module;

static void unused_static_global_module() {}
static void used_static_global_module() {}

inline void unused_inline_global_module() {}
inline void used_inline_global_module() {}

extern int extern_var_global_module;
inline int inline_var_global_module;
static int static_var_global_module;
const int const_var_global_module = 3;

// CHECK: define {{(dso_local )?}}void {{.*}}@_Z23noninline_global_modulev
void noninline_global_module() {
  // FIXME: This should be promoted to module linkage and given a
  // module-mangled name, if it's called from an inline function within
  // the module interface.
  // (We should try to avoid this when it's not reachable from outside
  // the module interface unit.)
  // CHECK: define internal {{.*}}@_ZL25used_static_global_modulev
  used_static_global_module();
  // CHECK: define linkonce_odr {{.*}}@_Z25used_inline_global_modulev
  used_inline_global_module();

  (void)&extern_var_global_module;
  (void)&inline_var_global_module;
  (void)&static_var_global_module;
  (void)&const_var_global_module;
}

export module Module;

export {
  inline void unused_inline_exported() {}
  inline void used_inline_exported() {}

  extern int extern_var_exported;
  inline int inline_var_exported;
  const int const_var_exported = 3;

  // CHECK: define {{(dso_local )?}}void {{.*}}@_ZW6Module18noninline_exportedv
  void noninline_exported() {
    (void)&extern_var_exported;
    (void)&inline_var_exported;
    (void)&const_var_exported;
  }
}

static void unused_static_module_linkage() {}

static void used_static_module_linkage() {}

inline void unused_inline_module_linkage() {}
inline void used_inline_module_linkage() {}

extern int extern_var_module_linkage;
inline int inline_var_module_linkage;
static int static_var_module_linkage;
const int const_var_module_linkage = 3;

// CHECK: define {{(dso_local )?}}void {{.*}}@_ZW6Module24noninline_module_linkagev
// CHECK: define {{.*}}void {{.*}}@_ZL26used_static_module_linkagev
void noninline_module_linkage() {
  used_static_module_linkage();
  // CHECK: define linkonce_odr {{.*}}@_ZW6Module26used_inline_module_linkagev
  used_inline_module_linkage();

  (void)&extern_var_module_linkage;
  (void)&inline_var_module_linkage;
  (void)&static_var_module_linkage;
  (void)&const_var_module_linkage;
}

int unused_var_module_linkage = 4;
static int unused_static_var_module_linkage = 5;
inline int unused_inline_var_module_linkage = 6;
const int unused_const_var_module_linkage = 7;

struct a {
  struct b {};
  struct c {};
};
// CHECK: define {{(dso_local )?}}void @_ZW6Module1fNS_1a1bENS0_1cE(
void f(a::b, a::c) {}

//--- module.cpp

// CHECK-DAG: @_ZW6Module19extern_var_exported = external {{(dso_local )?}}global
// CHECK-DAG: @_ZW6Module19inline_var_exported = linkonce_odr {{(dso_local )?}}global
// CHECK-DAG: @_ZW6Module18const_var_exported = available_externally {{(dso_local )?}}constant i32 3,
//
// CHECK-DAG: @_ZW6Module25extern_var_module_linkage = external {{(dso_local )?}}global
// CHECK-DAG: @_ZW6Module25inline_var_module_linkage = linkonce_odr {{(dso_local )?}}global
// CHECK-DAG: @_ZW6Module24const_var_module_linkage = available_externally {{(dso_local )?}}constant i32 3,

module Module;

void use() {
  // CHECK: define linkonce_odr {{.*}}@_ZW6Module20used_inline_exportedv
  used_inline_exported();
  // CHECK: declare {{.*}}@_ZW6Module18noninline_exportedv
  noninline_exported();

  (void)&extern_var_exported;
  (void)&inline_var_exported;
  (void)&const_var_exported;

  // CHECK: define linkonce_odr {{.*}}@_ZW6Module26used_inline_module_linkagev
  used_inline_module_linkage();

  // CHECK: declare {{.*}}@_ZW6Module24noninline_module_linkagev
  noninline_module_linkage();

  (void)&extern_var_module_linkage;
  (void)&inline_var_module_linkage;

  (void)&const_var_module_linkage; // FIXME: will be visible after P2788R0
}

//--- user.cpp

// CHECK-DAG: @_ZW6Module19extern_var_exported = external {{(dso_local )?}}global
// CHECK-DAG: @_ZW6Module19inline_var_exported = linkonce_odr {{(dso_local )?}}global
// CHECK-DAG: @_ZW6Module18const_var_exported = available_externally {{(dso_local )?}}constant i32 3

import Module;

void use() {
  // CHECK: define linkonce_odr {{.*}}@_ZW6Module20used_inline_exportedv
  used_inline_exported();
  // CHECK: declare {{.*}}@_ZW6Module18noninline_exportedv
  noninline_exported();

  (void)&extern_var_exported;
  (void)&inline_var_exported;
  (void)&const_var_exported;

  // Internal-linkage declarations are not visible here.
  // Module-linkage declarations are not visible here.
}