p1.cpp revision f1c66b40213784a1c4612f04c14cafa2b0e89988
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
10namespace 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
61namespace 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