File: module-initializer-guard-elision.cpp

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (130 lines) | stat: -rw-r--r-- 4,278 bytes parent folder | download | duplicates (7)
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
// RUN: rm -rf %t
// RUN: split-file %s %t
// RUN: cd %t

// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 O.cpp \
// RUN:    -emit-module-interface -o O.pcm
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 O.pcm -emit-llvm \
// RUN:  -o - | FileCheck %s --check-prefix=CHECK-O

// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 P.cpp \
// RUN:    -emit-module-interface -fprebuilt-module-path=%t -o P.pcm
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 P.pcm -emit-llvm \
// RUN:   -fprebuilt-module-path=%t -o - | FileCheck %s --check-prefix=CHECK-P

// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 Q.cpp \
// RUN:    -emit-module-interface -o Q.pcm
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 Q.pcm -emit-llvm \
// RUN:    -o - | FileCheck %s --check-prefix=CHECK-Q

// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 R.cpp \
// RUN:    -emit-module-interface -fprebuilt-module-path=%t -o R.pcm
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 R.pcm -emit-llvm \
// RUN:    -fprebuilt-module-path=%t -o - | FileCheck %s --check-prefix=CHECK-R

// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 S.cpp \
// RUN:    -emit-module-interface -fprebuilt-module-path=%t -o S.pcm
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 S.pcm -emit-llvm \
// RUN:    -fprebuilt-module-path=%t -o - | FileCheck %s --check-prefix=CHECK-S

// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 T.cpp \
// RUN:    -emit-module-interface -fprebuilt-module-path=%t -o T.pcm
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 T.pcm -emit-llvm \
// RUN:    -fprebuilt-module-path=%t -o - | FileCheck %s --check-prefix=CHECK-T

// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 U.cpp \
// RUN:    -emit-module-interface -fprebuilt-module-path=%t -o U.pcm
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 U.pcm -emit-llvm \
// RUN:    -fprebuilt-module-path=%t -o - | FileCheck %s --check-prefix=CHECK-U

// Testing cases where we can elide the module initializer guard variable.

// This module has no global inits and does not import any other module
//--- O.cpp

export module O;

export int foo ();

// CHECK-O: define void @_ZGIW1O
// CHECK-O-LABEL: entry
// CHECK-O-NEXT: ret void
// CHECK-O-NOT: @_ZGIW1O__in_chrg

// This has no global inits and all the imported modules don't need inits. So
// guard variable is not needed.
//--- P.cpp

export module P;

export import O;
export int bar ();

// CHECK-P: define void @_ZGIW1P
// CHECK-P-LABEL: entry
// CHECK-P-NEXT: ret void
// CHECK-P-NOT: @_ZGIW1P__in_chrg

// This has global inits, so needs a guard.
//--- Q.cpp

export module Q;

export struct Quack {
  Quack(){};
};

export Quack Duck;

export int baz ();

// CHECK-Q: define internal void @__cxx_global_var_init
// CHECK-Q: call {{.*}} @_ZNW1Q5QuackC1Ev
// CHECK-Q: define void @_ZGIW1Q
// CHECK-Q: store i8 1, ptr @_ZGIW1Q__in_chrg
// CHECK-Q: call void @__cxx_global_var_init

// This doesn't have a global init, but it imports a module which needs global
// init, so needs a guard
//--- R.cpp

export module R;
export import Q;

// CHECK-R: define void @_ZGIW1R
// CHECK-R: store i8 1, ptr @_ZGIW1R__in_chrg
// CHECK-R: call{{.*}}@_ZGIW1Q

// This doesn't have a global init and the imported module doesn't have variables needs
// dynamic initialization.
// But the imported module contains modules initialization. So needs a guard.
//--- S.cpp

export module S;
export import R;

// CHECK-S: define void @_ZGIW1S
// CHECK-S: store i8 1, ptr @_ZGIW1S__in_chrg
// CHECK-S: call{{.*}}@_ZGIW1R

// The module itself doesn't have a global init and it doesn't import any module.
// But the global module fragment imports a module that needs an init. So needs a guard.
//--- T.cpp
module;
import S;
export module T;

// CHECK-T: define void @_ZGIW1T
// CHECK-T: store i8 1, ptr @_ZGIW1T__in_chrg
// CHECK-T: call{{.*}}@_ZGIW1S

// The module itself doesn't have a global init and it doesn't import any module.
// But the private module fragment imports a module that needs an init. So needs a guard.
//--- U.cpp
export module U;
module :private;
import T;

// CHECK-U: define void @_ZGIW1U
// CHECK-U: store i8 1, ptr @_ZGIW1U__in_chrg
// CHECK-U: call{{.*}}@_ZGIW1T