• 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   // DR1484 specifies that enumerations cannot be separately instantiated,
37   // they will be instantiated with the rest of the template declaration.
38   template<typename T>
f()39   int f() {
40     enum class E {
41       e = T::error // expected-error {{has no members}}
42     };
43     return (int)E();
44   }
45   int test1 = f<int>(); // expected-note {{here}}
46 
47   template<typename T>
g()48   int g() {
49     enum class E {
50       e = T::error // expected-error {{has no members}}
51     };
52     return E::e;
53   }
54   int test2 = g<int>(); // expected-note {{here}}
55 }
56 
57 // - static data members
58 namespace StaticDataMembers {
59   template<typename T>
60   struct A {
61     static const int n = T::error; // expected-error {{has no members}}
62     static inline int m = T::error; // expected-warning {{extension}}
63   };
64   A<int> ai; // expected-note {{here}}
65 }
66 
67 // And it cases the implicit instantiations of the definitions of:
68 
69 // - unscoped member enumerations
70 namespace UnscopedEnum {
71   template<typename T> struct UnscopedEnum1 {
72     enum E {
73       e = T::error // expected-error {{'int' cannot be used prior to '::'}}
74     };
75   };
76   UnscopedEnum1<int> ue1; // expected-note {{here}}
77 
78   template<typename T> struct UnscopedEnum2 {
79     enum E : T { // expected-error {{non-integral type 'void *' is an invalid underlying type}}
80       e = 0
81     };
82   };
83   UnscopedEnum2<void*> ue2; // expected-note {{here}}
84 
85   template<typename T> struct UnscopedEnum3 {
86     enum E : T {
87       e = 4
88     };
89     int arr[E::e];
90   };
91   UnscopedEnum3<int> ue3; // ok
92 
93   template<typename T>
f()94   int f() {
95     enum E {
96       e = T::error // expected-error {{has no members}}
97     };
98     return (int)E();
99   }
100   int test1 = f<int>(); // expected-note {{here}}
101 
102   template<typename T>
g()103   int g() {
104     enum E {
105       e = T::error // expected-error {{has no members}}
106     };
107     return E::e;
108   }
109   int test2 = g<int>(); // expected-note {{here}}
110 }
111 
112 // FIXME:
113 //- - member anonymous unions
114