diff options
author | Reid Kleckner <reid@kleckner.net> | 2013-09-04 00:54:24 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2013-09-04 00:54:24 +0000 |
commit | 2753324e82d4404da579fd359e8ba5ef46c9a320 (patch) | |
tree | 10fb1240d5c1d3e3653b3dcc8ef219d64467ab6f /clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp | |
parent | 959aebf873a32c7b16e929e48cf8d94a816a8074 (diff) | |
download | bcm5719-llvm-2753324e82d4404da579fd359e8ba5ef46c9a320.tar.gz bcm5719-llvm-2753324e82d4404da579fd359e8ba5ef46c9a320.zip |
Order initializers of static data members of explicit specializations
I tried to implement this properly in r189051, but I didn't have enough
test coverage. Richard kindly provided more test cases than I could
possibly imagine and now we should have the correct condition.
llvm-svn: 189898
Diffstat (limited to 'clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp b/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp index e499efd2d03..a069e8bd724 100644 --- a/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp +++ b/clang/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp @@ -1,7 +1,10 @@ // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s // CHECK: ; ModuleID -template<typename> struct A { static int a; }; +extern "C" int foo(); + +template<typename T> struct A { static int a; }; +template<typename T> int A<T>::a = foo(); // CHECK-NOT: @_ZN1AIcE1aE template<> int A<char>::a; @@ -9,28 +12,60 @@ template<> int A<char>::a; // CHECK: @_ZN1AIbE1aE = global i32 10 template<> int A<bool>::a = 10; -// CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()* }] -// CHECK: [{ i32, void ()* } { i32 65535, void ()* @__cxx_global_var_init }, +// CHECK: @llvm.global_ctors = appending global [5 x { i32, void ()* }] +// CHECK: [{ i32, void ()* } { i32 65535, void ()* @[[unordered1:[^ ]*]] }, +// CHECK: { i32, void ()* } { i32 65535, void ()* @[[unordered2:[^ ]*]] }, +// CHECK: { i32, void ()* } { i32 65535, void ()* @[[unordered3:[^ ]*]] }, +// CHECK: { i32, void ()* } { i32 65535, void ()* @[[unordered4:[^ ]*]] }, // CHECK: { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }] -extern "C" int foo(); -template<> int A<short>::a = foo(); // Separate global_ctor entry -int b = foo(); // Goes in _GLOBAL__I_a -int c = foo(); // Goes in _GLOBAL__I_a +template int A<short>::a; // Unordered +int b = foo(); +int c = foo(); +int d = A<void>::a; // Unordered // An explicit specialization is ordered, and goes in __GLOBAL_I_a. template<> struct A<int> { static int a; }; int A<int>::a = foo(); -// CHECK: define internal void @__cxx_global_var_init() +template<typename T> struct S { static T x; static T y; }; +template<> int S<int>::x = foo(); +template<> int S<int>::y = S<int>::x; + +template<typename T> T x = foo(); +template short x<short>; // Unordered +template<> int x<int> = foo(); +int e = x<char>; // Unordered + +// CHECK: define internal void @[[unordered1]] // CHECK: call i32 @foo() // CHECK: store {{.*}} @_ZN1AIsE1aE // CHECK: ret +// CHECK: define internal void @[[unordered2]] +// CHECK: call i32 @foo() +// CHECK: store {{.*}} @_Z1xIsE +// CHECK: ret + +// CHECK: define internal void @[[unordered3]] +// CHECK: call i32 @foo() +// CHECK: store {{.*}} @_ZN1AIvE1aE +// CHECK: ret + +// CHECK: define internal void @[[unordered4]] +// CHECK: call i32 @foo() +// CHECK: store {{.*}} @_Z1xIcE +// CHECK: ret + // CHECK: define internal void @_GLOBAL__I_a() // We call unique stubs for every ordered dynamic initializer in the TU. // CHECK: call // CHECK: call // CHECK: call +// CHECK: call +// CHECK: call +// CHECK: call +// CHECK: call +// CHECK: call // CHECK-NOT: call // CHECK: ret |