diff options
author | Jordan Rupprecht <rupprecht@google.com> | 2019-05-14 21:58:59 +0000 |
---|---|---|
committer | Jordan Rupprecht <rupprecht@google.com> | 2019-05-14 21:58:59 +0000 |
commit | b35a2aa71f76a334a9c98c0a3c3995b5d902d2b9 (patch) | |
tree | cdff4a5d1a715d4ad622fd8f190128b54bebe440 /test/CodeGenCXX/microsoft-abi-template-static-init.cpp | |
parent | 3748d41833787fcbf59cc5624e8d2b042a8991bc (diff) | |
parent | 741e05796da92b46d4f7bcbee00702ff37df6489 (diff) |
Creating branches/google/stable and tags/google/stable/2019-05-14 from r360103upstream/google/stable
git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/google/stable@360714 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/microsoft-abi-template-static-init.cpp')
-rw-r--r-- | test/CodeGenCXX/microsoft-abi-template-static-init.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/test/CodeGenCXX/microsoft-abi-template-static-init.cpp b/test/CodeGenCXX/microsoft-abi-template-static-init.cpp new file mode 100644 index 0000000000..3b419c18c0 --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-template-static-init.cpp @@ -0,0 +1,92 @@ +// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s + +struct S { + S(); + ~S(); +}; + +template <typename T> struct __declspec(dllexport) ExportedTemplate { + static S s; +}; +template <typename T> S ExportedTemplate<T>::s; +void useExportedTemplate(ExportedTemplate<int> x) { + (void)x.s; +} +int f(); +namespace selectany_init { +// MS don't put selectany static var in the linker directive, init routine +// f() is not getting called if x is not referenced. +int __declspec(selectany) x = f(); +inline int __declspec(selectany) x1 = f(); +} + +namespace explicit_template_instantiation { +template <typename T> struct A { static int x; }; +template <typename T> int A<T>::x = f(); +template struct A<int>; +} + +namespace implicit_template_instantiation { +template <typename T> struct A { static int x; }; +template <typename T> int A<T>::x = f(); +int g() { return A<int>::x; } +} + + +template <class T> +struct X_ { + static T ioo; + static T init(); +}; +template <class T> T X_<T>::ioo = X_<T>::init(); +template struct X_<int>; + +template <class T> +struct X { + static T ioo; + static T init(); +}; +// template specialized static data don't need in llvm.used, +// the static init routine get call from _GLOBAL__sub_I_ routines. +template <> int X<int>::ioo = X<int>::init(); +template struct X<int>; +class a { +public: + a(); +}; +// For the static var inside unnamed namespace, the object is local to TU. +// No need to put static var in the linker directive. +// The static init routine is called before main. +namespace { +template <int> class aj { +public: + static a al; +}; +template <int am> a aj<am>::al; +class b : aj<3> { + void c(); +}; +void b::c() { al; } +} + +// C++17, inline static data member also need to use +struct A +{ + A(); + ~A(); +}; + +struct S1 +{ + inline static A aoo; // C++17 inline variable, thus also a definition +}; + +int foo(); +inline int zoo = foo(); +inline static int boo = foo(); + + +// CHECK: @llvm.used = appending global [7 x i8*] [i8* bitcast (i32* @"?x1@selectany_init@@3HA" to i8*), i8* bitcast (i32* @"?x@?$A@H@explicit_template_instantiation@@2HA" to i8*), i8* bitcast (i32* @"?ioo@?$X_@H@@2HA" to i8*), i8* getelementptr inbounds (%struct.A, %struct.A* @"?aoo@S1@@2UA@@A", i32 0, i32 0), i8* bitcast (i32* @"?zoo@@3HA" to i8*), i8* getelementptr inbounds (%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0), i8* bitcast (i32* @"?x@?$A@H@implicit_template_instantiation@@2HA" to i8*)], section "llvm.metadata" |