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> 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> 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 // And it cases the implicit instantiations of the definitions of: 58 59 // - unscoped member enumerations 60 namespace UnscopedEnum { 61 template<typename T> struct UnscopedEnum1 { 62 enum E { 63 e = T::error // expected-error {{'int' cannot be used prior to '::'}} 64 }; 65 }; 66 UnscopedEnum1<int> ue1; // expected-note {{here}} 67 68 template<typename T> struct UnscopedEnum2 { 69 enum E : T { // expected-error {{non-integral type 'void *' is an invalid underlying type}} 70 e = 0 71 }; 72 }; 73 UnscopedEnum2<void*> ue2; // expected-note {{here}} 74 75 template<typename T> struct UnscopedEnum3 { 76 enum E : T { 77 e = 4 78 }; 79 int arr[E::e]; 80 }; 81 UnscopedEnum3<int> ue3; // ok 82 83 template<typename T> 84 int f() { 85 enum E { 86 e = T::error // expected-error {{has no members}} 87 }; 88 return (int)E(); 89 } 90 int test1 = f<int>(); // expected-note {{here}} 91 92 template<typename T> 93 int g() { 94 enum E { 95 e = T::error // expected-error {{has no members}} 96 }; 97 return E::e; 98 } 99 int test2 = g<int>(); // expected-note {{here}} 100 } 101 102 // FIXME: 103 //- - member anonymous unions 104