1 // RUN: %clang_cc1 -fsyntax-only -pedantic-errors -verify %s
2
3 template<typename T> struct A {
4 template<typename U> struct B {
5 // FIXME: The standard does not seem to consider non-friend elaborated-type-specifiers that
6 // declare partial specializations/explicit specializations/explicit instantiations to be
7 // declarative, see https://lists.isocpp.org/core/2024/01/15325.php
8 struct C;
9 template<typename V> struct D;
10
11 void f();
12 template<typename V> void g();
13
14 static int x;
15 template<typename V> static int y;
16
17 enum class E;
18 };
19 };
20
21 template<typename T>
22 template<typename U>
23 struct A<T>::template B<U>::C { }; // expected-error{{'template' cannot be used after a declarative}}
24
25 template<>
26 template<>
27 struct A<int>::template B<bool>::C; // expected-error{{'template' cannot be used after a declarative}}
28
29 template<>
30 template<>
31 struct A<int>::template B<bool>::C { }; // expected-error{{'template' cannot be used after a declarative}}
32
33 template<typename T>
34 template<typename U>
35 template<typename V>
36 struct A<T>::template B<U>::D<V*>; // expected-error{{'template' cannot be used after a declarative}}
37
38 template<typename T>
39 template<typename U>
40 template<typename V>
41 struct A<T>::B<U>::template D<V**>; // expected-error{{'template' cannot be used after a declarative}}
42
43 template<typename T>
44 template<typename U>
45 template<typename V>
46 struct A<T>::template B<U>::D { }; // expected-error{{'template' cannot be used after a declarative}}
47
48 template<typename T>
49 template<typename U>
50 template<typename V>
51 struct A<T>::template B<U>::D<V*> { }; // expected-error{{'template' cannot be used after a declarative}}
52
53 template<typename T>
54 template<typename U>
55 template<typename V>
56 struct A<T>::B<U>::template D<V**> { }; // expected-error{{'template' cannot be used after a declarative}}
57
58 template<>
59 template<>
60 template<typename V>
61 struct A<int>::template B<bool>::D; // expected-error{{'template' cannot be used after a declarative}}
62
63 template<>
64 template<>
65 template<>
66 struct A<int>::template B<bool>::D<short>; // expected-error{{'template' cannot be used after a declarative}}
67
68 template<>
69 template<>
70 template<>
71 struct A<int>::B<bool>::template D<long>; // expected-error{{'template' cannot be used after a declarative}}
72
73 template<>
74 template<>
75 template<typename V>
76 struct A<int>::template B<bool>::D<V*>; // expected-error{{'template' cannot be used after a declarative}}
77
78 template<>
79 template<>
80 template<typename V>
81 struct A<int>::B<bool>::template D<V**>; // expected-error{{'template' cannot be used after a declarative}}
82
83 template<>
84 template<>
85 template<typename V>
86 struct A<int>::template B<bool>::D { }; // expected-error{{'template' cannot be used after a declarative}}
87
88 template<>
89 template<>
90 template<>
91 struct A<int>::template B<bool>::D<short> { }; // expected-error{{'template' cannot be used after a declarative}}
92
93 template<>
94 template<>
95 template<>
96 struct A<int>::B<bool>::template D<long> { }; // expected-error{{'template' cannot be used after a declarative}}
97
98 template<>
99 template<>
100 template<typename V>
101 struct A<int>::template B<bool>::D<V*> { }; // expected-error{{'template' cannot be used after a declarative}}
102
103 template<>
104 template<>
105 template<typename V>
106 struct A<int>::B<bool>::template D<V**> { }; // expected-error{{'template' cannot be used after a declarative}}
107
108 template<typename T>
109 template<typename U>
f()110 void A<T>::template B<U>::f() { } // expected-error{{'template' cannot be used after a declarative}}
111
112 template<>
113 template<>
f()114 void A<int>::template B<bool>::f() { } // expected-error{{'template' cannot be used after a declarative}}
115
116 template<typename T>
117 template<typename U>
118 template<typename V>
g()119 void A<T>::template B<U>::g() { } // expected-error{{'template' cannot be used after a declarative}}
120
121 template<>
122 template<>
123 template<>
g()124 void A<int>::B<bool>::template g<short>() { } // expected-error{{'template' cannot be used after a declarative}}
125
126 template<>
127 template<>
128 template<>
g()129 void A<int>::template B<bool>::g<long>() { } // expected-error{{'template' cannot be used after a declarative}}
130
131 template<>
132 template<>
133 template<typename V>
g()134 void A<int>::template B<bool>::g() { } // expected-error{{'template' cannot be used after a declarative}}
135
136 template<typename T>
137 template<typename U>
138 int A<T>::template B<U>::x = 0; // expected-error{{'template' cannot be used after a declarative}}
139
140 template<typename T>
141 template<typename U>
142 template<typename V>
143 int A<T>::template B<U>::y = 0; // expected-error{{'template' cannot be used after a declarative}}
144
145 template<typename T>
146 template<typename U>
147 template<typename V>
148 int A<T>::template B<U>::y<V*> = 0; // expected-error{{'template' cannot be used after a declarative}}
149
150 template<typename T>
151 template<typename U>
152 template<typename V>
153 int A<T>::B<U>::template y<V**> = 0; // expected-error{{'template' cannot be used after a declarative}}
154
155 template<>
156 template<>
157 template<typename V>
158 int A<int>::template B<bool>::y = 0; // expected-error{{'template' cannot be used after a declarative}}
159
160 template<>
161 template<>
162 template<>
163 int A<int>::template B<bool>::y<short> = 0; // expected-error{{'template' cannot be used after a declarative}}
164
165 template<>
166 template<>
167 template<>
168 int A<int>::B<bool>::template y<long> = 0; // expected-error{{'template' cannot be used after a declarative}}
169
170 template<>
171 template<>
172 template<typename V>
173 int A<int>::template B<bool>::y<V*> = 0; // expected-error{{'template' cannot be used after a declarative}}
174
175 template<>
176 template<>
177 template<typename V>
178 int A<int>::B<bool>::template y<V**> = 0; // expected-error{{'template' cannot be used after a declarative}}
179 template<typename T>
180 template<typename U>
181 enum class A<T>::template B<U>::E { a }; // expected-error{{'template' cannot be used after a declarative}}
182
183 template<>
184 template<>
185 enum class A<int>::template B<bool>::E; // expected-error{{'template' cannot be used after a declarative}}
186
187 template<>
188 template<>
189 enum class A<int>::template B<bool>::E { a }; // expected-error{{'template' cannot be used after a declarative}}
190
191 // FIXME: We don't call Sema::diagnoseQualifiedDeclaration for friend declarations right now
192 template<typename T>
193 struct F {
194 // FIXME: f should be assumed to name a template per [temp.names] p3.4
195 friend void T::f<int>();
196 // expected-error@-1{{use 'template' keyword to treat 'f' as a dependent template name}}
197 // expected-error@-2{{no candidate function template was found for}}
198
199 // FIXME: We should diagnose the presence of 'template' here
200 friend void T::template f<int>(); // expected-error{{no candidate function template was found for}}
201 friend void T::template U<int>::f();
202
203 // These should be allowed
204 friend class T::template U<int>;
205 friend class T::template U<int>::V;
206 };
207