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 // The behavior for enums defined within function templates is not clearly 37 // specified by the standard. We follow the rules for enums defined within 38 // class templates. 39 template<typename T> f()40 int f() { 41 enum class E { 42 e = T::error 43 }; 44 return (int)E(); 45 } 46 int test1 = f<int>(); 47 48 template<typename T> g()49 int g() { 50 enum class E { 51 e = T::error // expected-error {{has no members}} 52 }; 53 return E::e; // expected-note {{here}} 54 } 55 int test2 = g<int>(); // expected-note {{here}} 56 } 57 58 // And it cases the implicit instantiations of the definitions of: 59 60 // - unscoped member enumerations 61 namespace UnscopedEnum { 62 template<typename T> struct UnscopedEnum1 { 63 enum E { 64 e = T::error // expected-error {{'int' cannot be used prior to '::'}} 65 }; 66 }; 67 UnscopedEnum1<int> ue1; // expected-note {{here}} 68 69 template<typename T> struct UnscopedEnum2 { 70 enum E : T { // expected-error {{non-integral type 'void *' is an invalid underlying type}} 71 e = 0 72 }; 73 }; 74 UnscopedEnum2<void*> ue2; // expected-note {{here}} 75 76 template<typename T> struct UnscopedEnum3 { 77 enum E : T { 78 e = 4 79 }; 80 int arr[E::e]; 81 }; 82 UnscopedEnum3<int> ue3; // ok 83 84 template<typename T> f()85 int f() { 86 enum E { 87 e = T::error // expected-error {{has no members}} 88 }; 89 return (int)E(); 90 } 91 int test1 = f<int>(); // expected-note {{here}} 92 93 template<typename T> g()94 int g() { 95 enum E { 96 e = T::error // expected-error {{has no members}} 97 }; 98 return E::e; 99 } 100 int test2 = g<int>(); // expected-note {{here}} 101 } 102 103 // FIXME: 104 //- - member anonymous unions 105