// RUN: %clang_cc1 -no-opaque-pointers -fms-extensions -fno-threadsafe-statics -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
// CHECK: @llvm.global_ctors = appending global [5 x { i32, void ()*, i8* }] [
// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__Eselectany1@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?selectany1@@3US@@A", i32 0, i32 0) },
// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__Eselectany2@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?selectany2@@3US@@A", i32 0, i32 0) },
// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__E?s@?$ExportedTemplate@H@@2US@@A@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0) },
// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"??__E?foo@?$B@H@@2VA@@A@@YAXXZ", i8* bitcast (%class.A* @"?foo@?$B@H@@2VA@@A" to i8*) },
// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp, i8* null }
// CHECK: ]
;
S s;
// CHECK: define internal void @"??__Es@@YAXXZ"()
// CHECK: call x86_thiscallcc noundef %struct.S* @"??0S@@QAE@XZ"
// CHECK: call i32 @atexit(void ()* @"??__Fs@@YAXXZ")
// CHECK: ret void
// CHECK: define internal void @"??__Fs@@YAXXZ"()
// CHECK: call x86_thiscallcc void @"??1S@@QAE@XZ"
// CHECK: ret void
// These globals should have initializers comdat associative with the global.
// See @llvm.global_ctors above.
__declspec S selectany1;
__declspec S selectany2;
// CHECK: define linkonce_odr dso_local void @"??__Eselectany1@@YAXXZ"() {{.*}} comdat
// CHECK-NOT: @"??_Bselectany1
// CHECK: call x86_thiscallcc noundef %struct.S* @"??0S@@QAE@XZ"
// CHECK: ret void
// CHECK: define linkonce_odr dso_local void @"??__Eselectany2@@YAXXZ"() {{.*}} comdat
// CHECK-NOT: @"??_Bselectany2
// CHECK: call x86_thiscallcc noundef %struct.S* @"??0S@@QAE@XZ"
// CHECK: ret void
// The implicitly instantiated static data member should have initializer
// comdat associative with the global.
;
S ExportedTemplate<T>::s;
void
void
// CHECK-LABEL: define dso_local void @"?StaticLocal@@YAXXZ"()
// CHECK: load i32, i32* @"?$S1@?1??StaticLocal@@YAXXZ@4IA"
// CHECK: store i32 {{.*}}, i32* @"?$S1@?1??StaticLocal@@YAXXZ@4IA"
// CHECK: ret
void
// CHECK-LABEL: define dso_local void @"?MultipleStatics@@YAXXZ"()
// CHECK: load i32, i32* @"?$S1@?1??MultipleStatics@@YAXXZ@4IA"
// CHECK: and i32 {{.*}}, 1
// CHECK: and i32 {{.*}}, 2
// CHECK: and i32 {{.*}}, 4
// CHECK: and i32 {{.*}}, 8
// CHECK: and i32 {{.*}}, 16
// ...
// CHECK: and i32 {{.*}}, -2147483648
// CHECK: load i32, i32* @"?$S1@?1??MultipleStatics@@YAXXZ@4IA.1"
// CHECK: and i32 {{.*}}, 1
// CHECK: and i32 {{.*}}, 2
// CHECK: and i32 {{.*}}, 4
// CHECK: ret
// Force WeakODRLinkage by using templates
;
;
A B<T>::foo;
inline S &
// CHECK-LABEL: define linkonce_odr dso_local noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %struct.S* @"?UnreachableStatic@@YAAAUS@@XZ"() {{.*}} comdat
// CHECK: and i32 {{.*}}, 2
// CHECK: or i32 {{.*}}, 2
// CHECK: ret
inline S &
// CHECK-LABEL: define linkonce_odr dso_local noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) %struct.S* @"?getS@@YAAAUS@@XZ"() {{.*}} comdat
// CHECK: load i32, i32* @"??_B?1??getS@@YAAAUS@@XZ@51"
// CHECK: and i32 {{.*}}, 1
// CHECK: icmp eq i32 {{.*}}, 0
// CHECK: br i1
// init:
// CHECK: or i32 {{.*}}, 1
// CHECK: store i32 {{.*}}, i32* @"??_B?1??getS@@YAAAUS@@XZ@51"
// CHECK: call x86_thiscallcc noundef %struct.S* @"??0S@@QAE@XZ"(%struct.S* {{[^,]*}} @"?TheS@?1??getS@@YAAAUS@@XZ@4U2@A")
// CHECK: call i32 @atexit(void ()* @"??__FTheS@?1??getS@@YAAAUS@@XZ@YAXXZ")
// CHECK: br label
// init.end:
// CHECK: ret %struct.S* @"?TheS@?1??getS@@YAAAUS@@XZ@4U2@A"
inline int ;
;
inline int
int ;
inline void
void
// CHECK: define linkonce_odr dso_local void @"??__E?foo@?$B@H@@2VA@@A@@YAXXZ"() {{.*}} comdat
// CHECK-NOT: and
// CHECK-NOT: ?_Bfoo@
// CHECK: call x86_thiscallcc noundef %class.A* @"??0A@@QAE@XZ"
// CHECK: call i32 @atexit(void ()* @"??__F?foo@?$B@H@@2VA@@A@@YAXXZ")
// CHECK: ret void
// CHECK: define linkonce_odr dso_local x86_thiscallcc noundef %class.A* @"??0A@@QAE@XZ"({{.*}}) {{.*}} comdat
// CHECK: define linkonce_odr dso_local x86_thiscallcc void @"??1A@@QAE@XZ"({{.*}}) {{.*}} comdat
// CHECK: define internal void @"??__F?foo@?$B@H@@2VA@@A@@YAXXZ"
// CHECK: call x86_thiscallcc void @"??1A@@QAE@XZ"{{.*}}foo
// CHECK: ret void
// CHECK: define internal void @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp()
// CHECK: call void @"??__Es@@YAXXZ"()
// CHECK: ret void