1 // RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++11-extensions -Wno-c++1y-extensions -DPRECXX11 2 // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s 3 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s 4 5 class A { 6 template<typename T> const T wrong; // expected-error {{member 'wrong' declared as a template}} 7 template<typename T> const T wrong_init = 5; // expected-error {{member 'wrong_init' declared as a template}} 8 template<typename T, typename T0> static const T right = T(100); 9 template<typename T> static const T right<T,int> = 5; 10 template<typename T> const int right<int,T>; // expected-error {{member 'right' declared as a template}} 11 template<typename T> const float right<float,T> = 5; // expected-error {{member 'right' declared as a template}} 12 template<> static const int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}} 13 template<> static const float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}} 14 template static const int right<int,int>; // expected-error {{template specialization requires 'template<>'}} \ 15 // expected-error {{explicit specialization of 'right' in class scope}} 16 }; 17 18 namespace out_of_line { 19 class B0 { 20 template<typename T, typename T0> static const T right = T(100); 21 template<typename T> static const T right<T,int> = T(5); 22 }; 23 template<> const int B0::right<int,int> = 7; 24 template const int B0::right<int,int>; 25 template<> const int B0::right<int,float>; 26 template const int B0::right<int,float>; 27 28 class B1 { 29 template<typename T, typename T0> static const T right; 30 template<typename T> static const T right<T,int>; 31 }; 32 template<typename T, typename T0> const T B1::right = T(100); 33 template<typename T> const T B1::right<T,int> = T(5); 34 35 class B2 { 36 template<typename T, typename T0> static const T right = T(100); // expected-note {{previous definition is here}} 37 template<typename T> static const T right<T,int> = T(5); // expected-note {{previous definition is here}} 38 }; 39 template<typename T, typename T0> const T B2::right = T(100); // expected-error {{redefinition of 'right'}} 40 template<typename T> const T B2::right<T,int> = T(5); // expected-error {{redefinition of 'right'}} 41 42 class B3 { 43 template<typename T, typename T0> static const T right = T(100); 44 template<typename T> static const T right<T,int> = T(5); 45 }; 46 template<typename T, typename T0> const T B3::right; // expected-error {{forward declaration of variable template cannot have a nested name specifier}} 47 template<typename T> const T B3::right<T,int>; // expected-error {{forward declaration of variable template partial specialization cannot have a nested name specifier}} 48 49 class B4 { 50 template<typename T, typename T0> static const T right; 51 template<typename T> static const T right<T,int>; 52 template<typename T, typename T0> static const T right_def = T(100); 53 template<typename T> static const T right_def<T,int>; // expected-note {{explicit instantiation refers here}} 54 }; 55 template<typename T, typename T0> const T B4::right; // expected-error {{forward declaration of variable template cannot have a nested name specifier}} 56 template<typename T> const T B4::right<T,int>; // expected-error {{forward declaration of variable template partial specialization cannot have a nested name specifier}} \ 57 // expected-note {{explicit instantiation refers here}} 58 template const int B4::right<int,int>; // expected-error {{explicit instantiation of undefined static data member template 'right' of class}} 59 template const int B4::right_def<int,int>; // expected-error {{explicit instantiation of undefined static data member template 'right_def' of class}} 60 } 61 62 namespace non_const_init { 63 class A { 64 template<typename T> static T wrong_inst = T(10); // expected-error {{non-const static data member must be initialized out of line}} 65 template<typename T> static T wrong_inst_fixed; 66 }; 67 template int A::wrong_inst<int>; // expected-note {{in instantiation of static data member 'non_const_init::A::wrong_inst<int>' requested here}} 68 template<typename T> T A::wrong_inst_fixed = T(10); 69 template int A::wrong_inst_fixed<int>; 70 71 class B { 72 template<typename T> static T wrong_inst; 73 template<typename T> static T wrong_inst<T*> = T(100); // expected-error {{non-const static data member must be initialized out of line}} 74 75 template<typename T> static T wrong_inst_fixed; 76 template<typename T> static T wrong_inst_fixed<T*>; 77 }; 78 template int B::wrong_inst<int*>; // expected-note {{in instantiation of static data member 'non_const_init::B::wrong_inst<int *>' requested here}} 79 template<typename T> T B::wrong_inst_fixed = T(100); 80 template int B::wrong_inst_fixed<int>; 81 82 class C { 83 template<typename T> static const T right_inst = T(10); 84 template<typename T> static const T right_inst<T*> = T(100); 85 }; 86 template const int C::right_inst<int>; 87 template const int C::right_inst<int*>; 88 89 namespace pointers { 90 91 struct C0 { 92 template<typename U> static U Data; 93 template<typename U> static const U Data<U*> = U(); // Okay 94 }; 95 template const int C0::Data<int*>; 96 97 struct C1a { 98 template<typename U> static U Data; 99 template<typename U> static U* Data<U>; // Okay, with out-of-line definition 100 }; 101 template<typename T> T* C1a::Data<T> = new T(); 102 template int* C1a::Data<int>; 103 104 struct C1b { 105 template<typename U> static U Data; 106 template<typename U> static const U* Data<U>; // Okay, with out-of-line definition 107 }; 108 template<typename T> const T* C1b::Data<T> = (T*)(0); 109 template const int* C1b::Data<int>; 110 111 struct C2a { 112 template<typename U> static U Data; 113 template<typename U> static U* Data<U> = new U(); // expected-error {{non-const static data member must be initialized out of line}} 114 }; 115 template int* C2a::Data<int>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2a::Data<int>' requested here}} 116 117 struct C2b { // FIXME: ?!? Should this be an error? pointer-types are automatically non-const? 118 template<typename U> static U Data; 119 template<typename U> static const U* Data<U> = (U*)(0); // expected-error {{non-const static data member must be initialized out of line}} 120 }; 121 template const int* C2b::Data<int>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2b::Data<int>' requested here}} 122 } 123 } 124 125 struct matrix_constants { 126 // TODO: (?) 127 }; 128 129 namespace in_class_template { 130 // FIXME: member data templates of class templates are not well supported yet. 131 132 template<typename T> 133 class D0 { 134 template<typename U> static U Data; 135 template<typename U> static const U Data<U*> = U(); 136 }; 137 138 template<typename T> 139 class D1 { 140 template<typename U> static U Data; 141 template<typename U> static U* Data<U*>; 142 }; 143 template<typename T> 144 template<typename U> U* D1<T>::Data<U*> = (U*)(0); 145 146 namespace to_be_fixed { 147 // FIXME: The following generate runtime exceptions! 148 149 //template<> 150 //template<typename U> U* D1<float>::Data<U*> = (U*)(0) + 1; 151 //template const int D0<float>::Data<int*>; 152 //template int* D1<float>::Data<int*>; 153 } 154 } 155 156 namespace in_nested_classes { 157 // TODO: 158 } 159 160