2020-05-28 05:04:43 +08:00
|
|
|
// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
|
2020-06-19 07:52:34 +08:00
|
|
|
// RUN: -std=c++2a < %s | \
|
2020-05-28 05:04:43 +08:00
|
|
|
// RUN: FileCheck --check-prefixes=CHECK,CHECK32 %s
|
|
|
|
|
|
|
|
// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
|
2020-06-19 07:52:34 +08:00
|
|
|
// RUN: -std=c++2a < %s | \
|
2020-05-28 05:04:43 +08:00
|
|
|
// RUN: FileCheck --check-prefixes=CHECK,CHECK64 %s
|
|
|
|
|
|
|
|
namespace test1 {
|
|
|
|
struct Test1 {
|
|
|
|
Test1();
|
|
|
|
~Test1();
|
|
|
|
} t1, t2;
|
|
|
|
} // namespace test1
|
|
|
|
|
|
|
|
namespace test2 {
|
|
|
|
int foo() { return 3; }
|
|
|
|
int x = foo();
|
|
|
|
} // namespace test2
|
|
|
|
|
|
|
|
namespace test3 {
|
|
|
|
struct Test3 {
|
|
|
|
constexpr Test3() {};
|
|
|
|
~Test3() {};
|
|
|
|
};
|
|
|
|
|
|
|
|
constinit Test3 t;
|
|
|
|
} // namespace test3
|
|
|
|
|
|
|
|
namespace test4 {
|
|
|
|
struct Test4 {
|
|
|
|
Test4();
|
|
|
|
~Test4();
|
|
|
|
};
|
|
|
|
|
|
|
|
void f() {
|
|
|
|
static Test4 staticLocal;
|
|
|
|
}
|
|
|
|
} // namespace test4
|
|
|
|
|
|
|
|
// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit80000000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
|
|
|
|
// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm80000000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
|
|
|
|
|
|
|
|
// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
|
|
|
|
// CHECK: %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t1E)
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: define internal void @__dtor__ZN5test12t1E() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: declare i32 @atexit(void ()*)
|
|
|
|
|
|
|
|
// CHECK: define internal void @__finalize__ZN5test12t1E() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t1E)
|
|
|
|
// CHECK: %needs_destruct = icmp eq i32 %0, 0
|
|
|
|
// CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end
|
|
|
|
|
|
|
|
// CHECK: destruct.call:
|
|
|
|
// CHECK: call void @__dtor__ZN5test12t1E()
|
|
|
|
// CHECK: br label %destruct.end
|
|
|
|
|
|
|
|
// CHECK: destruct.end:
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: declare i32 @unatexit(void ()*)
|
|
|
|
|
|
|
|
// CHECK: define internal void @__cxx_global_var_init.1() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
|
|
|
|
// CHECK: %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E)
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: define internal void @__dtor__ZN5test12t2E() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: define internal void @__finalize__ZN5test12t2E() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E)
|
|
|
|
// CHECK: %needs_destruct = icmp eq i32 %0, 0
|
|
|
|
// CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end
|
|
|
|
|
|
|
|
// CHECK: destruct.call:
|
|
|
|
// CHECK: call void @__dtor__ZN5test12t2E()
|
|
|
|
// CHECK: br label %destruct.end
|
|
|
|
|
|
|
|
// CHECK: destruct.end:
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: define internal void @__cxx_global_var_init.2() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK32: %call = call i32 @_ZN5test23fooEv()
|
|
|
|
// CHECK64: %call = call signext i32 @_ZN5test23fooEv()
|
|
|
|
// CHECK: store i32 %call, i32* @_ZN5test21xE
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: define internal void @__cxx_global_var_init.3() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: %0 = call i32 @atexit(void ()* @__dtor__ZN5test31tE)
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: define internal void @__dtor__ZN5test31tE() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: call void @_ZN5test35Test3D1Ev(%"struct.test3::Test3"* @_ZN5test31tE)
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: define internal void @__finalize__ZN5test31tE() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZN5test31tE)
|
|
|
|
// CHECK: %needs_destruct = icmp eq i32 %0, 0
|
|
|
|
// CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end
|
|
|
|
|
|
|
|
// CHECK: destruct.call:
|
|
|
|
// CHECK: call void @__dtor__ZN5test31tE()
|
|
|
|
// CHECK: br label %destruct.end
|
|
|
|
|
|
|
|
// CHECK: destruct.end:
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: define void @_ZN5test41fEv() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: %0 = load atomic i8, i8* bitcast (i64* @_ZGVZN5test41fEvE11staticLocal to i8*) acquire
|
|
|
|
// CHECK: %guard.uninitialized = icmp eq i8 %0, 0
|
|
|
|
// CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end
|
|
|
|
|
|
|
|
// CHECK: init.check:
|
|
|
|
// CHECK: %1 = call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test41fEvE11staticLocal)
|
|
|
|
// CHECK: %tobool = icmp ne i32 %1, 0
|
|
|
|
// CHECK: br i1 %tobool, label %init, label %init.end
|
|
|
|
|
|
|
|
// CHECK: init:
|
|
|
|
// CHECK: call void @_ZN5test45Test4C1Ev(%"struct.test4::Test4"* @_ZZN5test41fEvE11staticLocal)
|
|
|
|
// CHECK: %2 = call i32 @atexit(void ()* @__dtor__ZZN5test41fEvE11staticLocal)
|
|
|
|
// CHECK: call void @__cxa_guard_release(i64* @_ZGVZN5test41fEvE11staticLocal)
|
|
|
|
// CHECK: br label %init.end
|
|
|
|
|
|
|
|
// CHECK: init.end:
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: define internal void @__dtor__ZZN5test41fEvE11staticLocal() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: call void @_ZN5test45Test4D1Ev(%"struct.test4::Test4"* @_ZZN5test41fEvE11staticLocal)
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: define internal void @__finalize__ZZN5test41fEvE11staticLocal() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: %0 = call i32 @unatexit(void ()* @__dtor__ZZN5test41fEvE11staticLocal)
|
|
|
|
// CHECK: %needs_destruct = icmp eq i32 %0, 0
|
|
|
|
// CHECK: br i1 %needs_destruct, label %destruct.call, label %destruct.end
|
|
|
|
|
|
|
|
// CHECK: destruct.call:
|
|
|
|
// CHECK: call void @__dtor__ZZN5test41fEvE11staticLocal()
|
|
|
|
// CHECK: br label %destruct.end
|
|
|
|
|
|
|
|
// CHECK: destruct.end:
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: define void @__sinit80000000_clang_1145401da454a7baad10bfe313c46638() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: call void @__cxx_global_var_init()
|
|
|
|
// CHECK: call void @__cxx_global_var_init.1()
|
|
|
|
// CHECK: call void @__cxx_global_var_init.2()
|
|
|
|
// CHECK: call void @__cxx_global_var_init.3()
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|
|
|
|
|
|
|
|
// CHECK: define void @__sterm80000000_clang_1145401da454a7baad10bfe313c46638() [[ATTR:#[0-9]+]] {
|
|
|
|
// CHECK: entry:
|
|
|
|
// CHECK: call void @__finalize__ZZN5test41fEvE11staticLocal()
|
|
|
|
// CHECK: call void @__finalize__ZN5test31tE()
|
|
|
|
// CHECK: call void @__finalize__ZN5test12t2E()
|
|
|
|
// CHECK: call void @__finalize__ZN5test12t1E()
|
|
|
|
// CHECK: ret void
|
|
|
|
// CHECK: }
|