1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++11-extensions -Wno-c++1y-extensions -DPRECXX11 2f4a2713aSLionel Sambuc // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s 3f4a2713aSLionel Sambuc // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s 4f4a2713aSLionel Sambuc 5f4a2713aSLionel Sambuc #define CONST const 6f4a2713aSLionel Sambuc 7f4a2713aSLionel Sambuc #ifdef PRECXX11 8f4a2713aSLionel Sambuc #define static_assert(expr, msg) typedef int static_assert[(expr) ? 1 : -1]; 9f4a2713aSLionel Sambuc #endif 10f4a2713aSLionel Sambuc 11f4a2713aSLionel Sambuc class A { 12f4a2713aSLionel Sambuc template<typename T> CONST T wrong; // expected-error {{member 'wrong' declared as a template}} 13f4a2713aSLionel Sambuc template<typename T> CONST T wrong_init = 5; // expected-error {{member 'wrong_init' declared as a template}} 14f4a2713aSLionel Sambuc template<typename T, typename T0> static CONST T right = T(100); 15f4a2713aSLionel Sambuc template<typename T> static CONST T right<T,int> = 5; 16f4a2713aSLionel Sambuc template<typename T> CONST int right<int,T>; // expected-error {{member 'right' declared as a template}} 17f4a2713aSLionel Sambuc template<typename T> CONST float right<float,T> = 5; // expected-error {{member 'right' declared as a template}} 18f4a2713aSLionel Sambuc template<> static CONST int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}} 19f4a2713aSLionel Sambuc template<> static CONST float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}} 20f4a2713aSLionel Sambuc template static CONST int right<int,int>; // expected-error {{template specialization requires 'template<>'}} \ 21f4a2713aSLionel Sambuc // expected-error {{explicit specialization of 'right' in class scope}} 22f4a2713aSLionel Sambuc }; 23f4a2713aSLionel Sambuc 24f4a2713aSLionel Sambuc namespace out_of_line { 25f4a2713aSLionel Sambuc class B0 { 26f4a2713aSLionel Sambuc template<typename T, typename T0> static CONST T right = T(100); 27f4a2713aSLionel Sambuc template<typename T> static CONST T right<T,int> = T(5); 28f4a2713aSLionel Sambuc }; 29f4a2713aSLionel Sambuc template<> CONST int B0::right<int,int> = 7; 30f4a2713aSLionel Sambuc template CONST int B0::right<int,int>; 31f4a2713aSLionel Sambuc template<> CONST int B0::right<int,float>; 32f4a2713aSLionel Sambuc template CONST int B0::right<int,float>; 33f4a2713aSLionel Sambuc 34f4a2713aSLionel Sambuc class B1 { 35f4a2713aSLionel Sambuc template<typename T, typename T0> static CONST T right; 36f4a2713aSLionel Sambuc template<typename T> static CONST T right<T,int>; 37f4a2713aSLionel Sambuc }; 38f4a2713aSLionel Sambuc template<typename T, typename T0> CONST T B1::right = T(100); 39f4a2713aSLionel Sambuc template<typename T> CONST T B1::right<T,int> = T(5); 40f4a2713aSLionel Sambuc 41f4a2713aSLionel Sambuc class B2 { 42*0a6a1f1dSLionel Sambuc template<typename T, typename T0> static CONST T right = T(100); // expected-note {{previous initialization is here}} 43*0a6a1f1dSLionel Sambuc template<typename T> static CONST T right<T,int> = T(5); // expected-note {{previous initialization is here}} 44f4a2713aSLionel Sambuc }; 45*0a6a1f1dSLionel Sambuc template<typename T, typename T0> CONST T B2::right = T(100); // expected-error {{static data member 'right' already has an initializer}} 46*0a6a1f1dSLionel Sambuc template<typename T> CONST T B2::right<T,int> = T(5); // expected-error {{static data member 'right' already has an initializer}} 47f4a2713aSLionel Sambuc 48f4a2713aSLionel Sambuc class B3 { 49f4a2713aSLionel Sambuc template<typename T, typename T0> static CONST T right = T(100); 50f4a2713aSLionel Sambuc template<typename T> static CONST T right<T,int> = T(5); 51f4a2713aSLionel Sambuc }; 52f4a2713aSLionel Sambuc template<typename T, typename T0> CONST T B3::right; 53f4a2713aSLionel Sambuc template<typename T> CONST T B3::right<T,int>; 54f4a2713aSLionel Sambuc 55f4a2713aSLionel Sambuc class B4 { 56f4a2713aSLionel Sambuc template<typename T, typename T0> static CONST T a; 57f4a2713aSLionel Sambuc template<typename T> static CONST T a<T,int> = T(100); 58f4a2713aSLionel Sambuc template<typename T, typename T0> static CONST T b = T(100); 59f4a2713aSLionel Sambuc template<typename T> static CONST T b<T,int>; 60f4a2713aSLionel Sambuc }; 61*0a6a1f1dSLionel Sambuc template<typename T, typename T0> CONST T B4::a; // expected-error {{default initialization of an object of const type 'const int'}} expected-note {{add an explicit initializer to initialize 'a<int, char>'}} 62f4a2713aSLionel Sambuc template<typename T> CONST T B4::a<T,int>; 63f4a2713aSLionel Sambuc template CONST int B4::a<int,char>; // expected-note {{in instantiation of}} 64f4a2713aSLionel Sambuc template CONST int B4::a<int,int>; 65f4a2713aSLionel Sambuc 66f4a2713aSLionel Sambuc template<typename T, typename T0> CONST T B4::b; 67*0a6a1f1dSLionel Sambuc template<typename T> CONST T B4::b<T,int>; // expected-error {{default initialization of an object of const type 'const int'}} expected-note {{add an explicit initializer to initialize 'b<int, int>'}} 68f4a2713aSLionel Sambuc template CONST int B4::b<int,char>; 69f4a2713aSLionel Sambuc template CONST int B4::b<int,int>; // expected-note {{in instantiation of}} 70f4a2713aSLionel Sambuc } 71f4a2713aSLionel Sambuc 72f4a2713aSLionel Sambuc namespace non_const_init { 73f4a2713aSLionel Sambuc class A { 74f4a2713aSLionel Sambuc template<typename T> static T wrong_inst_undefined = T(10); // expected-note {{refers here}} 75f4a2713aSLionel Sambuc template<typename T> static T wrong_inst_defined = T(10); // expected-error {{non-const static data member must be initialized out of line}} 76f4a2713aSLionel Sambuc template<typename T> static T wrong_inst_out_of_line; 77f4a2713aSLionel Sambuc }; 78f4a2713aSLionel Sambuc 79f4a2713aSLionel Sambuc template const int A::wrong_inst_undefined<const int>; // expected-error {{undefined}} 80f4a2713aSLionel Sambuc 81f4a2713aSLionel Sambuc template<typename T> T A::wrong_inst_defined; 82f4a2713aSLionel Sambuc template const int A::wrong_inst_defined<const int>; 83f4a2713aSLionel Sambuc template int A::wrong_inst_defined<int>; // expected-note {{in instantiation of static data member 'non_const_init::A::wrong_inst_defined<int>' requested here}} 84f4a2713aSLionel Sambuc 85f4a2713aSLionel Sambuc template<typename T> T A::wrong_inst_out_of_line = T(10); 86f4a2713aSLionel Sambuc template int A::wrong_inst_out_of_line<int>; 87f4a2713aSLionel Sambuc 88f4a2713aSLionel Sambuc class B { 89f4a2713aSLionel Sambuc template<typename T> static T wrong_inst; // expected-note {{refers here}} 90f4a2713aSLionel Sambuc template<typename T> static T wrong_inst<T*> = T(100); // expected-error {{non-const static data member must be initialized out of line}} expected-note {{refers here}} 91f4a2713aSLionel Sambuc 92f4a2713aSLionel Sambuc template<typename T> static T wrong_inst_fixed; 93f4a2713aSLionel Sambuc template<typename T> static T wrong_inst_fixed<T*>; 94f4a2713aSLionel Sambuc }; 95f4a2713aSLionel Sambuc template int B::wrong_inst<int>; // expected-error {{undefined}} 96f4a2713aSLionel Sambuc // FIXME: It'd be better to produce the 'explicit instantiation of undefined 97f4a2713aSLionel Sambuc // template' diagnostic here, not the 'must be initialized out of line' 98f4a2713aSLionel Sambuc // diagnostic. 99f4a2713aSLionel Sambuc template int B::wrong_inst<int*>; // expected-note {{in instantiation of static data member 'non_const_init::B::wrong_inst<int *>' requested here}} 100f4a2713aSLionel Sambuc template const int B::wrong_inst<const int*>; // expected-error {{undefined}} 101f4a2713aSLionel Sambuc template<typename T> T B::wrong_inst_fixed = T(100); 102f4a2713aSLionel Sambuc template int B::wrong_inst_fixed<int>; 103f4a2713aSLionel Sambuc 104f4a2713aSLionel Sambuc class C { 105f4a2713aSLionel Sambuc template<typename T> static CONST T right_inst = T(10); // expected-note {{here}} 106f4a2713aSLionel Sambuc template<typename T> static CONST T right_inst<T*> = T(100); // expected-note {{here}} 107f4a2713aSLionel Sambuc }; 108f4a2713aSLionel Sambuc template CONST int C::right_inst<int>; // expected-error {{undefined variable template}} 109f4a2713aSLionel Sambuc template CONST int C::right_inst<int*>; // expected-error {{undefined variable template}} 110f4a2713aSLionel Sambuc 111f4a2713aSLionel Sambuc namespace pointers { 112f4a2713aSLionel Sambuc 113f4a2713aSLionel Sambuc struct C0 { 114f4a2713aSLionel Sambuc template<typename U> static U Data; 115f4a2713aSLionel Sambuc template<typename U> static CONST U Data<U*> = U(); // expected-note {{here}} 116f4a2713aSLionel Sambuc 117f4a2713aSLionel Sambuc template<typename U> static U Data2; 118f4a2713aSLionel Sambuc template<typename U> static CONST U Data2<U*> = U(); 119f4a2713aSLionel Sambuc }; 120f4a2713aSLionel Sambuc const int c0_test = C0::Data<int*>; 121f4a2713aSLionel Sambuc static_assert(c0_test == 0, ""); 122f4a2713aSLionel Sambuc template const int C0::Data<int*>; // expected-error {{undefined}} 123f4a2713aSLionel Sambuc 124f4a2713aSLionel Sambuc template<typename U> const U C0::Data2<U*>; 125f4a2713aSLionel Sambuc template const int C0::Data2<int*>; 126f4a2713aSLionel Sambuc 127f4a2713aSLionel Sambuc struct C1a { 128f4a2713aSLionel Sambuc template<typename U> static U Data; 129f4a2713aSLionel Sambuc template<typename U> static U* Data<U*>; // Okay, with out-of-line definition 130f4a2713aSLionel Sambuc }; 131f4a2713aSLionel Sambuc template<typename T> T* C1a::Data<T*> = new T(); 132f4a2713aSLionel Sambuc template int* C1a::Data<int*>; 133f4a2713aSLionel Sambuc 134f4a2713aSLionel Sambuc struct C1b { 135f4a2713aSLionel Sambuc template<typename U> static U Data; 136f4a2713aSLionel Sambuc template<typename U> static CONST U* Data<U*>; // Okay, with out-of-line definition 137f4a2713aSLionel Sambuc }; 138f4a2713aSLionel Sambuc template<typename T> CONST T* C1b::Data<T*> = (T*)(0); 139f4a2713aSLionel Sambuc template CONST int* C1b::Data<int*>; 140f4a2713aSLionel Sambuc 141f4a2713aSLionel Sambuc struct C2a { 142f4a2713aSLionel Sambuc template<typename U> static int Data; 143f4a2713aSLionel Sambuc template<typename U> static U* Data<U*> = new U(); // expected-error {{non-const static data member must be initialized out of line}} 144f4a2713aSLionel Sambuc }; 145f4a2713aSLionel Sambuc template int* C2a::Data<int*>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2a::Data<int *>' requested here}} 146f4a2713aSLionel Sambuc 147f4a2713aSLionel Sambuc struct C2b { 148f4a2713aSLionel Sambuc template<typename U> static int Data; 149f4a2713aSLionel Sambuc template<typename U> static U *const Data<U*> = (U*)(0); // expected-error {{static data member of type 'int *const'}} 150f4a2713aSLionel Sambuc }; 151f4a2713aSLionel Sambuc template<typename U> U *const C2b::Data<U*>; 152f4a2713aSLionel Sambuc template int *const C2b::Data<int*>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2b::Data<int *>' requested here}} 153f4a2713aSLionel Sambuc } 154f4a2713aSLionel Sambuc } 155f4a2713aSLionel Sambuc 156f4a2713aSLionel Sambuc #ifndef PRECXX11 157f4a2713aSLionel Sambuc namespace constexpred { 158f4a2713aSLionel Sambuc class A { 159f4a2713aSLionel Sambuc template<typename T> constexpr T wrong; // expected-error {{member 'wrong' declared as a template}} \ 160f4a2713aSLionel Sambuc // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}} 161f4a2713aSLionel Sambuc template<typename T> constexpr T wrong_init = 5; // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}} 162f4a2713aSLionel Sambuc template<typename T, typename T0> static constexpr T right = T(100); 163f4a2713aSLionel Sambuc template<typename T> static constexpr T right<T,int> = 5; 164f4a2713aSLionel Sambuc template<typename T> constexpr int right<int,T>; // expected-error {{member 'right' declared as a template}} \ 165f4a2713aSLionel Sambuc // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}} 166f4a2713aSLionel Sambuc template<typename T> constexpr float right<float,T> = 5; // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}} 167f4a2713aSLionel Sambuc template<> static constexpr int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}} 168f4a2713aSLionel Sambuc template<> static constexpr float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}} 169f4a2713aSLionel Sambuc template static constexpr int right<int,int>; // expected-error {{template specialization requires 'template<>'}} \ 170f4a2713aSLionel Sambuc // expected-error {{explicit specialization of 'right' in class scope}} 171f4a2713aSLionel Sambuc }; 172f4a2713aSLionel Sambuc } 173f4a2713aSLionel Sambuc #endif 174f4a2713aSLionel Sambuc 175f4a2713aSLionel Sambuc namespace in_class_template { 176f4a2713aSLionel Sambuc 177f4a2713aSLionel Sambuc template<typename T> 178f4a2713aSLionel Sambuc class D0 { 179f4a2713aSLionel Sambuc template<typename U> static U Data; // expected-note {{here}} 180f4a2713aSLionel Sambuc template<typename U> static CONST U Data<U*> = U(); 181f4a2713aSLionel Sambuc }; 182f4a2713aSLionel Sambuc template CONST int D0<float>::Data<int*>; 183f4a2713aSLionel Sambuc template int D0<float>::Data<int>; // expected-error {{undefined}} 184f4a2713aSLionel Sambuc template<typename T> template<typename U> const U D0<T>::Data<U*>; 185f4a2713aSLionel Sambuc 186f4a2713aSLionel Sambuc template<typename T> 187f4a2713aSLionel Sambuc class D1 { 188f4a2713aSLionel Sambuc template<typename U> static U Data; 189f4a2713aSLionel Sambuc template<typename U> static U* Data<U*>; 190f4a2713aSLionel Sambuc }; 191f4a2713aSLionel Sambuc template<typename T> 192f4a2713aSLionel Sambuc template<typename U> U* D1<T>::Data<U*> = (U*)(0); 193f4a2713aSLionel Sambuc template int* D1<float>::Data<int*>; // expected-note {{previous}} 194f4a2713aSLionel Sambuc template int* D1<float>::Data<int*>; // expected-error {{duplicate explicit instantiation}} 195f4a2713aSLionel Sambuc 196f4a2713aSLionel Sambuc template<typename T> 197f4a2713aSLionel Sambuc class D2 { 198f4a2713aSLionel Sambuc template<typename U> static U Data; 199f4a2713aSLionel Sambuc template<typename U> static U* Data<U*>; 200f4a2713aSLionel Sambuc }; 201f4a2713aSLionel Sambuc template<> 202f4a2713aSLionel Sambuc template<typename U> U* D2<float>::Data<U*> = (U*)(0) + 1; 203f4a2713aSLionel Sambuc template int* D2<float>::Data<int*>; // expected-note {{previous}} 204f4a2713aSLionel Sambuc template int* D2<float>::Data<int*>; // expected-error {{duplicate explicit instantiation}} 205f4a2713aSLionel Sambuc 206f4a2713aSLionel Sambuc template<typename T> 207f4a2713aSLionel Sambuc struct D3 { 208f4a2713aSLionel Sambuc template<typename U> static CONST U Data = U(100); // expected-note {{here}} 209f4a2713aSLionel Sambuc }; 210f4a2713aSLionel Sambuc static_assert(D3<float>::Data<int> == 100, ""); 211f4a2713aSLionel Sambuc template const char D3<float>::Data<char>; // expected-error {{undefined}} 212f4a2713aSLionel Sambuc 213f4a2713aSLionel Sambuc namespace bug_files { 214f4a2713aSLionel Sambuc template<typename T> 215f4a2713aSLionel Sambuc class D0a { 216f4a2713aSLionel Sambuc template<typename U> static U Data; 217f4a2713aSLionel Sambuc template<typename U> static CONST U Data<U*> = U(10); // expected-note {{previous definition is here}} 218f4a2713aSLionel Sambuc }; 219f4a2713aSLionel Sambuc template<> 220f4a2713aSLionel Sambuc template<typename U> U D0a<float>::Data<U*> = U(100); // expected-error {{redefinition of 'Data'}} 221f4a2713aSLionel Sambuc 222f4a2713aSLionel Sambuc // FIXME: We should accept this, and the corresponding case for class 223f4a2713aSLionel Sambuc // templates. 224f4a2713aSLionel Sambuc // 225f4a2713aSLionel Sambuc // [temp.class.spec.mfunc]/2: If the primary member template is explicitly 226f4a2713aSLionel Sambuc // specialized for a given specialization of the enclosing class template, 227f4a2713aSLionel Sambuc // the partial specializations of the member template are ignored 228f4a2713aSLionel Sambuc template<typename T> 229f4a2713aSLionel Sambuc class D1 { 230f4a2713aSLionel Sambuc template<typename U> static U Data; 231f4a2713aSLionel Sambuc template<typename U> static CONST U Data<U*> = U(10); // expected-note {{previous definition is here}} 232f4a2713aSLionel Sambuc }; 233f4a2713aSLionel Sambuc template<> 234f4a2713aSLionel Sambuc template<typename U> U D1<float>::Data = U(10); 235f4a2713aSLionel Sambuc template<> 236f4a2713aSLionel Sambuc template<typename U> U D1<float>::Data<U*> = U(100); // expected-error{{redefinition of 'Data'}} 237f4a2713aSLionel Sambuc } 238f4a2713aSLionel Sambuc 239f4a2713aSLionel Sambuc namespace definition_after_outer_instantiation { 240f4a2713aSLionel Sambuc template<typename A> struct S { 241f4a2713aSLionel Sambuc template<typename B> static const int V1; 242f4a2713aSLionel Sambuc template<typename B> static const int V2; 243f4a2713aSLionel Sambuc }; 244f4a2713aSLionel Sambuc template struct S<int>; 245f4a2713aSLionel Sambuc template<typename A> template<typename B> const int S<A>::V1 = 123; 246f4a2713aSLionel Sambuc template<typename A> template<typename B> const int S<A>::V2<B*> = 456; 247f4a2713aSLionel Sambuc 248f4a2713aSLionel Sambuc static_assert(S<int>::V1<int> == 123, ""); 249f4a2713aSLionel Sambuc 250f4a2713aSLionel Sambuc // FIXME: The first and third case below possibly should be accepted. We're 251f4a2713aSLionel Sambuc // not picking up partial specializations added after the primary template 252f4a2713aSLionel Sambuc // is instantiated. This is kind of implied by [temp.class.spec.mfunc]/2, 253f4a2713aSLionel Sambuc // and matches our behavior for member class templates, but it's not clear 254f4a2713aSLionel Sambuc // that this is intentional. See PR17294 and core-24030. 255f4a2713aSLionel Sambuc static_assert(S<int>::V2<int*> == 456, ""); // FIXME expected-error {{}} 256f4a2713aSLionel Sambuc static_assert(S<int>::V2<int&> == 789, ""); // expected-error {{}} 257f4a2713aSLionel Sambuc 258f4a2713aSLionel Sambuc template<typename A> template<typename B> const int S<A>::V2<B&> = 789; 259f4a2713aSLionel Sambuc static_assert(S<int>::V2<int&> == 789, ""); // FIXME expected-error {{}} 260f4a2713aSLionel Sambuc 261f4a2713aSLionel Sambuc // All is OK if the partial specialization is declared before the implicit 262f4a2713aSLionel Sambuc // instantiation of the class template specialization. 263f4a2713aSLionel Sambuc static_assert(S<char>::V1<int> == 123, ""); 264f4a2713aSLionel Sambuc static_assert(S<char>::V2<int*> == 456, ""); 265f4a2713aSLionel Sambuc static_assert(S<char>::V2<int&> == 789, ""); 266f4a2713aSLionel Sambuc } 267f4a2713aSLionel Sambuc 268f4a2713aSLionel Sambuc namespace incomplete_array { 269f4a2713aSLionel Sambuc template<typename T> extern T var[]; 270f4a2713aSLionel Sambuc template<typename T> T var[] = { 1, 2, 3 }; 271f4a2713aSLionel Sambuc template<> char var<char>[] = "hello"; 272f4a2713aSLionel Sambuc template<typename T> char var<T*>[] = "pointer"; 273f4a2713aSLionel Sambuc 274f4a2713aSLionel Sambuc static_assert(sizeof(var<int>) == 12, ""); 275f4a2713aSLionel Sambuc static_assert(sizeof(var<char>) == 6, ""); 276f4a2713aSLionel Sambuc static_assert(sizeof(var<void*>) == 8, ""); 277f4a2713aSLionel Sambuc 278f4a2713aSLionel Sambuc template<typename...> struct tuple; 279f4a2713aSLionel Sambuc 280f4a2713aSLionel Sambuc template<typename T> struct A { 281f4a2713aSLionel Sambuc template<typename U> static T x[]; 282f4a2713aSLionel Sambuc template<typename U> static T y[]; 283f4a2713aSLionel Sambuc 284f4a2713aSLionel Sambuc template<typename...U> static T y<tuple<U...> >[]; 285f4a2713aSLionel Sambuc }; 286f4a2713aSLionel Sambuc 287f4a2713aSLionel Sambuc int *use_before_definition = A<int>::x<char>; 288f4a2713aSLionel Sambuc template<typename T> template<typename U> T A<T>::x[sizeof(U)]; 289f4a2713aSLionel Sambuc static_assert(sizeof(A<int>::x<char>) == 4, ""); 290f4a2713aSLionel Sambuc 291f4a2713aSLionel Sambuc template<typename T> template<typename...U> T A<T>::y<tuple<U...> >[] = { U()... }; 292f4a2713aSLionel Sambuc static_assert(sizeof(A<int>::y<tuple<char, char, char> >) == 12, ""); 293f4a2713aSLionel Sambuc } 294*0a6a1f1dSLionel Sambuc 295*0a6a1f1dSLionel Sambuc namespace bad_reference { 296*0a6a1f1dSLionel Sambuc struct S { 297*0a6a1f1dSLionel Sambuc template<typename T> static int A; // expected-note 4{{here}} 298*0a6a1f1dSLionel Sambuc }; 299*0a6a1f1dSLionel Sambuc f()300*0a6a1f1dSLionel Sambuc template<typename T> void f() { 301*0a6a1f1dSLionel Sambuc typename T::template A<int> a; // expected-error {{template name refers to non-type template 'S::A'}} 302*0a6a1f1dSLionel Sambuc } g()303*0a6a1f1dSLionel Sambuc template<typename T> void g() { 304*0a6a1f1dSLionel Sambuc T::template A<int>::B = 0; // expected-error {{template name refers to non-type template 'S::A'}} 305*0a6a1f1dSLionel Sambuc } h()306*0a6a1f1dSLionel Sambuc template<typename T> void h() { 307*0a6a1f1dSLionel Sambuc class T::template A<int> c; // expected-error {{template name refers to non-type template 'S::A'}} 308*0a6a1f1dSLionel Sambuc } 309*0a6a1f1dSLionel Sambuc 310*0a6a1f1dSLionel Sambuc template<typename T> 311*0a6a1f1dSLionel Sambuc struct X : T::template A<int> {}; // expected-error {{template name refers to non-type template 'S::A'}} 312*0a6a1f1dSLionel Sambuc 313*0a6a1f1dSLionel Sambuc template void f<S>(); // expected-note {{in instantiation of}} 314*0a6a1f1dSLionel Sambuc template void g<S>(); // expected-note {{in instantiation of}} 315*0a6a1f1dSLionel Sambuc template void h<S>(); // expected-note {{in instantiation of}} 316*0a6a1f1dSLionel Sambuc template struct X<S>; // expected-note {{in instantiation of}} 317*0a6a1f1dSLionel Sambuc } 318f4a2713aSLionel Sambuc } 319f4a2713aSLionel Sambuc 320f4a2713aSLionel Sambuc namespace in_nested_classes { 321f4a2713aSLionel Sambuc // TODO: 322f4a2713aSLionel Sambuc } 323f4a2713aSLionel Sambuc 324*0a6a1f1dSLionel Sambuc namespace bitfield { 325*0a6a1f1dSLionel Sambuc struct S { 326*0a6a1f1dSLionel Sambuc template <int I> 327*0a6a1f1dSLionel Sambuc static int f : I; // expected-error {{static member 'f' cannot be a bit-field}} 328*0a6a1f1dSLionel Sambuc }; 329*0a6a1f1dSLionel Sambuc } 330