diff options
| author | John McCall <rjmccall@apple.com> | 2012-05-01 06:13:13 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2012-05-01 06:13:13 +0000 |
| commit | c84ed6a3365d73c00ce9b5cb48eadfaf21f6129b (patch) | |
| tree | ea721094e985593d9ae976713ab05c99711d31a6 /clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp | |
| parent | 7afed5e5bf340d6716413acf82ff52f66f77b56b (diff) | |
| download | bcm5719-llvm-c84ed6a3365d73c00ce9b5cb48eadfaf21f6129b.tar.gz bcm5719-llvm-c84ed6a3365d73c00ce9b5cb48eadfaf21f6129b.zip | |
Abstract the emission of global destructors into ABI-specific code
and only consider using __cxa_atexit in the Itanium logic. The
default logic is to use atexit().
Emit "guarded" initializers in Microsoft mode unconditionally.
This is definitely not correct, but it's closer to correct than
just not emitting the initializer.
Based on a patch by Timur Iskhodzhanov!
llvm-svn: 155894
Diffstat (limited to 'clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp')
| -rw-r--r-- | clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp new file mode 100644 index 00000000000..4ccd6bafecf --- /dev/null +++ b/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s + +struct S { + S() {} + ~S() {} +} s; + +// CHECK: define internal void [[INIT_s:@.*global_var.*]] nounwind +// CHECK: call void @"\01??0S@@QAE@XZ" +// CHECK: call i32 @atexit(void ()* @"__dtor_\01?s@@3US@@A") +// CHECK: ret void + +// CHECK: define internal void @"__dtor_\01?s@@3US@@A"() nounwind { +// CHECK: call void @"\01??1S@@QAE@XZ" +// CHECK: ret void + +// Force WeakODRLinkage by using templates +class A { + public: + A() {} + ~A() {} +}; + +template<typename T> +class B { + public: + static A foo; +}; + +template<typename T> A B<T>::foo; + +void force_usage() { + (void)B<int>::foo; // (void) - force usage +} + +// CHECK: define internal void [[INIT_foo:@.*global_var.*]] nounwind +// CHECK: call void @"\01??0A@@QAE@XZ" +// CHECK: call i32 @atexit(void ()* [[FOO_DTOR:@"__dtor_.*foo@.*]]) +// CHECK: ret void + +// CHECK: define linkonce_odr void @"\01??0A@@QAE@XZ" + +// CHECK: define linkonce_odr void @"\01??1A@@QAE@XZ" + +// CHECK: define internal void [[FOO_DTOR]] +// CHECK: call void @"\01??1A@@QAE@XZ"{{.*}}foo +// CHECK: ret void + +// CHECK: define internal void @_GLOBAL__I_a() nounwind { +// CHECK: call void [[INIT_s]] +// CHECK: call void [[INIT_foo]] +// CHECK: ret void |

