• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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