summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2012-05-01 06:13:13 +0000
committerJohn McCall <rjmccall@apple.com>2012-05-01 06:13:13 +0000
commitc84ed6a3365d73c00ce9b5cb48eadfaf21f6129b (patch)
treeea721094e985593d9ae976713ab05c99711d31a6 /clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
parent7afed5e5bf340d6716413acf82ff52f66f77b56b (diff)
downloadbcm5719-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.cpp52
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
OpenPOWER on IntegriCloud