14b38ded6SRichard Smith // RUN: %clang_cc1 -std=c++11 -verify %s 24b38ded6SRichard Smith 34b38ded6SRichard Smith // The implicit specialization of a class template specialuzation causes the 44b38ded6SRichard Smith // implicit instantiation of the declarations, but not the definitions or 54b38ded6SRichard Smith // default arguments, of: 64b38ded6SRichard Smith 74b38ded6SRichard Smith // FIXME: Many omitted cases 84b38ded6SRichard Smith 94b38ded6SRichard Smith // - scoped member enumerations 104b38ded6SRichard Smith namespace ScopedEnum { 114b38ded6SRichard Smith template<typename T> struct ScopedEnum1 { 124b38ded6SRichard Smith enum class E { 134b38ded6SRichard Smith e = T::error // expected-error {{'double' cannot be used prior to '::'}} 144b38ded6SRichard Smith }; 154b38ded6SRichard Smith }; 164b38ded6SRichard Smith ScopedEnum1<int> se1; // ok 174b38ded6SRichard Smith 184b38ded6SRichard Smith template<typename T> struct ScopedEnum2 { 194b38ded6SRichard Smith enum class E : T { // expected-error {{non-integral type 'void *' is an invalid underlying type}} 204b38ded6SRichard Smith e = 0 214b38ded6SRichard Smith }; 224b38ded6SRichard Smith }; 234b38ded6SRichard Smith ScopedEnum2<void*> se2; // expected-note {{here}} 244b38ded6SRichard Smith 254b38ded6SRichard Smith template<typename T> struct UnscopedEnum3 { 264b38ded6SRichard Smith enum class E : T { 274b38ded6SRichard Smith e = 4 284b38ded6SRichard Smith }; 294b38ded6SRichard Smith int arr[(int)E::e]; 304b38ded6SRichard Smith }; 314b38ded6SRichard Smith UnscopedEnum3<int> ue3; // ok 324b38ded6SRichard Smith 334b38ded6SRichard Smith ScopedEnum1<double>::E e1; // ok 344b38ded6SRichard Smith ScopedEnum1<double>::E e2 = decltype(e2)::e; // expected-note {{in instantiation of enumeration 'ScopedEnum::ScopedEnum1<double>::E' requested here}} 354b38ded6SRichard Smith 36192d1798SDavid Majnemer // DR1484 specifies that enumerations cannot be separately instantiated, 37192d1798SDavid Majnemer // they will be instantiated with the rest of the template declaration. 384b38ded6SRichard Smith template<typename T> f()394b38ded6SRichard Smith int f() { 404b38ded6SRichard Smith enum class E { 41192d1798SDavid Majnemer e = T::error // expected-error {{has no members}} 424b38ded6SRichard Smith }; 434b38ded6SRichard Smith return (int)E(); 444b38ded6SRichard Smith } 45192d1798SDavid Majnemer int test1 = f<int>(); // expected-note {{here}} 464b38ded6SRichard Smith 474b38ded6SRichard Smith template<typename T> g()484b38ded6SRichard Smith int g() { 494b38ded6SRichard Smith enum class E { 504b38ded6SRichard Smith e = T::error // expected-error {{has no members}} 514b38ded6SRichard Smith }; 52192d1798SDavid Majnemer return E::e; 534b38ded6SRichard Smith } 544b38ded6SRichard Smith int test2 = g<int>(); // expected-note {{here}} 554b38ded6SRichard Smith } 564b38ded6SRichard Smith 57*62f19e70SRichard Smith // - static data members 58*62f19e70SRichard Smith namespace StaticDataMembers { 59*62f19e70SRichard Smith template<typename T> 60*62f19e70SRichard Smith struct A { 61*62f19e70SRichard Smith static const int n = T::error; // expected-error {{has no members}} 62*62f19e70SRichard Smith static inline int m = T::error; // expected-warning {{extension}} 63*62f19e70SRichard Smith }; 64*62f19e70SRichard Smith A<int> ai; // expected-note {{here}} 65*62f19e70SRichard Smith } 66*62f19e70SRichard Smith 674b38ded6SRichard Smith // And it cases the implicit instantiations of the definitions of: 684b38ded6SRichard Smith 694b38ded6SRichard Smith // - unscoped member enumerations 704b38ded6SRichard Smith namespace UnscopedEnum { 714b38ded6SRichard Smith template<typename T> struct UnscopedEnum1 { 724b38ded6SRichard Smith enum E { 734b38ded6SRichard Smith e = T::error // expected-error {{'int' cannot be used prior to '::'}} 744b38ded6SRichard Smith }; 754b38ded6SRichard Smith }; 764b38ded6SRichard Smith UnscopedEnum1<int> ue1; // expected-note {{here}} 774b38ded6SRichard Smith 784b38ded6SRichard Smith template<typename T> struct UnscopedEnum2 { 794b38ded6SRichard Smith enum E : T { // expected-error {{non-integral type 'void *' is an invalid underlying type}} 804b38ded6SRichard Smith e = 0 814b38ded6SRichard Smith }; 824b38ded6SRichard Smith }; 834b38ded6SRichard Smith UnscopedEnum2<void*> ue2; // expected-note {{here}} 844b38ded6SRichard Smith 854b38ded6SRichard Smith template<typename T> struct UnscopedEnum3 { 864b38ded6SRichard Smith enum E : T { 874b38ded6SRichard Smith e = 4 884b38ded6SRichard Smith }; 894b38ded6SRichard Smith int arr[E::e]; 904b38ded6SRichard Smith }; 914b38ded6SRichard Smith UnscopedEnum3<int> ue3; // ok 924b38ded6SRichard Smith 934b38ded6SRichard Smith template<typename T> f()944b38ded6SRichard Smith int f() { 954b38ded6SRichard Smith enum E { 964b38ded6SRichard Smith e = T::error // expected-error {{has no members}} 974b38ded6SRichard Smith }; 984b38ded6SRichard Smith return (int)E(); 994b38ded6SRichard Smith } 1004b38ded6SRichard Smith int test1 = f<int>(); // expected-note {{here}} 1014b38ded6SRichard Smith 1024b38ded6SRichard Smith template<typename T> g()1034b38ded6SRichard Smith int g() { 1044b38ded6SRichard Smith enum E { 1054b38ded6SRichard Smith e = T::error // expected-error {{has no members}} 1064b38ded6SRichard Smith }; 1074b38ded6SRichard Smith return E::e; 1084b38ded6SRichard Smith } 1094b38ded6SRichard Smith int test2 = g<int>(); // expected-note {{here}} 1104b38ded6SRichard Smith } 1114b38ded6SRichard Smith 1124b38ded6SRichard Smith // FIXME: 1134b38ded6SRichard Smith //- - member anonymous unions 114