1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
2 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s |
3 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s |
4 | |
5 | namespace PR8965 { |
6 | template<typename T> |
7 | struct X { |
8 | typedef int type; |
9 | |
10 | T field; // expected-note{{in instantiation of member class}} |
11 | }; |
12 | |
13 | template<typename T> |
14 | struct Y { |
15 | struct Inner; |
16 | |
17 | typedef typename X<Inner>::type // expected-note{{in instantiation of template class}} |
18 | type; // expected-note{{not-yet-instantiated member is declared here}} |
19 | |
20 | struct Inner { |
21 | typedef type field; // expected-error{{no member 'type' in 'PR8965::Y<int>'; it has not yet been instantiated}} |
22 | }; |
23 | }; |
24 | |
25 | Y<int> y; // expected-note{{in instantiation of template class}} |
26 | } |
27 | |
28 | template<typename T> |
29 | class X { |
30 | public: |
31 | struct C { T &foo(); }; |
32 | |
33 | struct D { |
34 | struct E { T &bar(); }; // expected-error{{cannot form a reference to 'void'}} |
35 | struct F; // expected-note{{member is declared here}} |
36 | }; |
37 | }; |
38 | |
39 | X<int>::C *c1; |
40 | X<float>::C *c2; |
41 | |
42 | X<int>::X *xi; // expected-error{{qualified reference to 'X' is a constructor name rather than a type}} |
43 | X<float>::X *xf; // expected-error{{qualified reference to 'X' is a constructor name rather than a type}} |
44 | |
45 | void test_naming() { |
46 | c1 = c2; // expected-error{{assigning to 'X<int>::C *' from incompatible type 'X<float>::C *'}} |
47 | xi = xf; // expected-error{{assigning to 'X<int>::X<int> *' from incompatible type 'X<float>::X<float> *'}} |
48 | // FIXME: error above doesn't print the type X<int>::X cleanly! |
49 | } |
50 | |
51 | void test_instantiation(X<double>::C *x, |
52 | X<float>::D::E *e, |
53 | X<float>::D::F *f) { |
54 | double &dr = x->foo(); |
55 | float &fr = e->bar(); |
56 | f->foo(); // expected-error{{implicit instantiation of undefined member 'X<float>::D::F'}} |
57 | |
58 | } |
59 | |
60 | |
61 | X<void>::C *c3; // okay |
62 | X<void>::D::E *e1; // okay |
63 | X<void>::D::E e2; // expected-note{{in instantiation of member class 'X<void>::D::E' requested here}} |
64 | |
65 | // Redeclarations. |
66 | namespace test1 { |
67 | template <typename T> struct Registry { |
68 | struct node; |
69 | static node *Head; |
70 | struct node { |
71 | node(int v) { Head = this; } |
72 | }; |
73 | }; |
74 | void test() { |
75 | Registry<int>::node node(0); |
76 | } |
77 | } |
78 | |
79 | // Redeclarations during explicit instantiations. |
80 | namespace test2 { |
81 | template <typename T> class A { |
82 | class Foo; |
83 | class Foo { |
84 | int foo(); |
85 | }; |
86 | }; |
87 | template class A<int>; |
88 | |
89 | template <typename T> class B { |
90 | class Foo; |
91 | class Foo { |
92 | public: |
93 | typedef int X; |
94 | }; |
95 | typename Foo::X x; |
96 | }; |
97 | template class B<int>; |
98 | |
99 | template <typename T> class C { |
100 | class Foo; |
101 | }; |
102 | template <typename T> class C<T>::Foo { |
103 | int x; |
104 | }; |
105 | template class C<int>; |
106 | } |
107 | |
108 | namespace AliasTagDef { |
109 | template<typename T> |
110 | struct F { |
111 | using S = struct U { |
112 | #if __cplusplus <= 199711L |
113 | // expected-warning@-2 {{alias declarations are a C++11 extension}} |
114 | #endif |
115 | T g() { |
116 | return T(); |
117 | } |
118 | }; |
119 | }; |
120 | |
121 | int m = F<int>::S().g(); |
122 | int n = F<int>::U().g(); |
123 | } |
124 | |
125 | namespace rdar10397846 { |
126 | template<int I> struct A |
127 | { |
128 | struct B |
129 | { |
130 | struct C { C() { int *ptr = I; } }; |
131 | #if __cplusplus >= 201103L |
132 | // expected-error@-2 {{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} |
133 | #else |
134 | // expected-warning@-4 {{expression which evaluates to zero treated as a null pointer constant of type 'int *'}} |
135 | #endif |
136 | // expected-error@-6 {{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} |
137 | }; |
138 | }; |
139 | |
140 | template<int N> void foo() |
141 | { |
142 | class A<N>::B::C X; // expected-note 2 {{in instantiation of member function}} |
143 | int A<N+1>::B::C::*member = 0; |
144 | } |
145 | |
146 | void bar() |
147 | { |
148 | foo<0>(); // expected-note{{in instantiation of function template}} |
149 | foo<1>(); // expected-note{{in instantiation of function template}} |
150 | } |
151 | } |
152 | |