Home | History | Annotate | Download | only in temp.inst
      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>
     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>
     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>
     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>
     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