xref: /llvm-project/clang/test/CXX/temp/temp.spec/temp.inst/p1.cpp (revision 62f19e700d3126415bb443162501eefe22cf1811)
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