1 // RUN: %clang_cc1 -std=c++11 -verify %s 2 3 // The implicit specialization of a class template specialuzation causes the 4 // implicit instantiation of the declarations, but not the definitions or 5 // default arguments, of: 6 7 // FIXME: Many omitted cases 8 9 // - scoped member enumerations 10 namespace ScopedEnum { 11 template<typename T> struct ScopedEnum1 { 12 enum class E { 13 e = T::error // expected-error {{'double' cannot be used prior to '::'}} 14 }; 15 }; 16 ScopedEnum1<int> se1; // ok 17 18 template<typename T> struct ScopedEnum2 { 19 enum class E : T { // expected-error {{non-integral type 'void *' is an invalid underlying type}} 20 e = 0 21 }; 22 }; 23 ScopedEnum2<void*> se2; // expected-note {{here}} 24 25 template<typename T> struct UnscopedEnum3 { 26 enum class E : T { 27 e = 4 28 }; 29 int arr[(int)E::e]; 30 }; 31 UnscopedEnum3<int> ue3; // ok 32 33 ScopedEnum1<double>::E e1; // ok 34 ScopedEnum1<double>::E e2 = decltype(e2)::e; // expected-note {{in instantiation of enumeration 'ScopedEnum::ScopedEnum1<double>::E' requested here}} 35 36 // DR1484 specifies that enumerations cannot be separately instantiated, 37 // they will be instantiated with the rest of the template declaration. 38 template<typename T> f()39 int f() { 40 enum class E { 41 e = T::error // expected-error {{has no members}} 42 }; 43 return (int)E(); 44 } 45 int test1 = f<int>(); // expected-note {{here}} 46 47 template<typename T> g()48 int g() { 49 enum class E { 50 e = T::error // expected-error {{has no members}} 51 }; 52 return E::e; 53 } 54 int test2 = g<int>(); // expected-note {{here}} 55 } 56 57 // - static data members 58 namespace StaticDataMembers { 59 template<typename T> 60 struct A { 61 static const int n = T::error; // expected-error {{has no members}} 62 static inline int m = T::error; // expected-warning {{extension}} 63 }; 64 A<int> ai; // expected-note {{here}} 65 } 66 67 // And it cases the implicit instantiations of the definitions of: 68 69 // - unscoped member enumerations 70 namespace UnscopedEnum { 71 template<typename T> struct UnscopedEnum1 { 72 enum E { 73 e = T::error // expected-error {{'int' cannot be used prior to '::'}} 74 }; 75 }; 76 UnscopedEnum1<int> ue1; // expected-note {{here}} 77 78 template<typename T> struct UnscopedEnum2 { 79 enum E : T { // expected-error {{non-integral type 'void *' is an invalid underlying type}} 80 e = 0 81 }; 82 }; 83 UnscopedEnum2<void*> ue2; // expected-note {{here}} 84 85 template<typename T> struct UnscopedEnum3 { 86 enum E : T { 87 e = 4 88 }; 89 int arr[E::e]; 90 }; 91 UnscopedEnum3<int> ue3; // ok 92 93 template<typename T> f()94 int f() { 95 enum E { 96 e = T::error // expected-error {{has no members}} 97 }; 98 return (int)E(); 99 } 100 int test1 = f<int>(); // expected-note {{here}} 101 102 template<typename T> g()103 int g() { 104 enum E { 105 e = T::error // expected-error {{has no members}} 106 }; 107 return E::e; 108 } 109 int test2 = g<int>(); // expected-note {{here}} 110 } 111 112 // FIXME: 113 //- - member anonymous unions 114