Mercurial > hg > CbC > CbC_llvm
comparison clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | 0572611fdcc8 |
comparison
equal
deleted
inserted
replaced
147:c2174574ed3a | 150:1d019706d866 |
---|---|
1 // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s | |
2 | |
3 | |
4 template <class T> | |
5 class A { | |
6 public: | |
7 void f(T a) { }// expected-note 2{{must qualify identifier to find this declaration in dependent base class}} | |
8 void g();// expected-note 2{{must qualify identifier to find this declaration in dependent base class}} | |
9 }; | |
10 | |
11 template <class T> | |
12 class B : public A<T> { | |
13 public: | |
14 void z(T a) | |
15 { | |
16 f(a); // expected-warning 2{{use of identifier 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
17 g(); // expected-warning 2{{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
18 } | |
19 }; | |
20 | |
21 template class B<int>; // expected-note {{requested here}} | |
22 template class B<char>; // expected-note {{requested here}} | |
23 | |
24 void test() | |
25 { | |
26 B<int> b; | |
27 b.z(3); | |
28 } | |
29 | |
30 struct A2 { | |
31 template<class T> void f(T) { | |
32 XX; //expected-error {{use of undeclared identifier 'XX'}} | |
33 A2::XX; //expected-error {{no member named 'XX' in 'A2'}} | |
34 } | |
35 }; | |
36 template void A2::f(int); | |
37 | |
38 template<class T0> | |
39 struct A3 { | |
40 template<class T1> void f(T1) { | |
41 XX; //expected-error {{use of undeclared identifier 'XX'}} | |
42 } | |
43 }; | |
44 template void A3<int>::f(int); | |
45 | |
46 template<class T0> | |
47 struct A4 { | |
48 void f(char) { | |
49 XX; //expected-error {{use of undeclared identifier 'XX'}} | |
50 } | |
51 }; | |
52 template class A4<int>; | |
53 | |
54 | |
55 namespace lookup_dependent_bases_id_expr { | |
56 | |
57 template<class T> class A { | |
58 public: | |
59 int var; | |
60 }; | |
61 | |
62 | |
63 template<class T> | |
64 class B : public A<T> { | |
65 public: | |
66 void f() { | |
67 var = 3; // expected-warning {{use of undeclared identifier 'var'; unqualified lookup into dependent bases of class template 'B' is a Microsoft extension}} | |
68 } | |
69 }; | |
70 | |
71 template class B<int>; | |
72 | |
73 } | |
74 | |
75 | |
76 | |
77 namespace lookup_dependent_base_class_static_function { | |
78 | |
79 template <class T> | |
80 class A { | |
81 public: | |
82 static void static_func();// expected-note {{must qualify identifier to find this declaration in dependent base class}} | |
83 void func();// expected-note {{must qualify identifier to find this declaration in dependent base class}} | |
84 }; | |
85 | |
86 | |
87 template <class T> | |
88 class B : public A<T> { | |
89 public: | |
90 static void z2(){ | |
91 static_func(); // expected-warning {{use of identifier 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
92 func(); // expected-warning {{use of identifier 'func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}} | |
93 } | |
94 }; | |
95 template class B<int>; // expected-note {{requested here}} | |
96 | |
97 } | |
98 | |
99 | |
100 | |
101 namespace lookup_dependent_base_class_default_argument { | |
102 | |
103 template<class T> | |
104 class A { | |
105 public: | |
106 static int f1(); // expected-note {{must qualify identifier to find this declaration in dependent base class}} | |
107 int f2(); // expected-note {{must qualify identifier to find this declaration in dependent base class}} | |
108 }; | |
109 | |
110 template<class T> | |
111 class B : public A<T> { | |
112 public: | |
113 void g1(int p = f1());// expected-warning {{use of identifier 'f1' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
114 void g2(int p = f2());// expected-warning {{use of identifier 'f2' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}} | |
115 }; | |
116 | |
117 void foo() | |
118 { | |
119 B<int> b; | |
120 b.g1(); // expected-note {{required here}} | |
121 b.g2(); // expected-note {{required here}} | |
122 } | |
123 | |
124 } | |
125 | |
126 | |
127 namespace lookup_dependent_base_class_friend { | |
128 | |
129 template <class T> | |
130 class B { | |
131 public: | |
132 static void g(); // expected-note {{must qualify identifier to find this declaration in dependent base class}} | |
133 }; | |
134 | |
135 template <class T> | |
136 class A : public B<T> { | |
137 public: | |
138 friend void foo(A<T> p){ | |
139 g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
140 } | |
141 }; | |
142 | |
143 int main2() | |
144 { | |
145 A<int> a; | |
146 foo(a); // expected-note {{requested here}} | |
147 } | |
148 | |
149 } | |
150 | |
151 | |
152 namespace lookup_dependent_base_no_typo_correction { | |
153 | |
154 class C { | |
155 public: | |
156 int m_hWnd; | |
157 }; | |
158 | |
159 template <class T> | |
160 class A : public T { | |
161 public: | |
162 void f(int hWnd) { | |
163 m_hWnd = 1; // expected-warning {{use of undeclared identifier 'm_hWnd'; unqualified lookup into dependent bases of class template 'A' is a Microsoft extension}} | |
164 } | |
165 }; | |
166 | |
167 template class A<C>; | |
168 | |
169 } | |
170 | |
171 namespace PR12701 { | |
172 | |
173 class A {}; | |
174 class B {}; | |
175 | |
176 template <class T> | |
177 class Base { | |
178 public: | |
179 bool base_fun(void* p) { return false; } // expected-note {{must qualify identifier to find this declaration in dependent base class}} | |
180 operator T*() const { return 0; } | |
181 }; | |
182 | |
183 template <class T> | |
184 class Container : public Base<T> { | |
185 public: | |
186 template <typename S> | |
187 bool operator=(const Container<S>& rhs) { | |
188 return base_fun(rhs); // expected-warning {{use of identifier 'base_fun' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
189 } | |
190 }; | |
191 | |
192 void f() { | |
193 Container<A> text_provider; | |
194 Container<B> text_provider2; | |
195 text_provider2 = text_provider; // expected-note {{in instantiation of function template specialization}} | |
196 } | |
197 | |
198 } // namespace PR12701 | |
199 | |
200 namespace PR16014 { | |
201 | |
202 struct A { | |
203 int a; | |
204 static int sa; | |
205 }; | |
206 template <typename T> struct B : T { | |
207 int foo() { return a; } // expected-warning {{lookup into dependent bases}} | |
208 int *bar() { return &a; } // expected-warning {{lookup into dependent bases}} | |
209 int baz() { return T::a; } | |
210 int T::*qux() { return &T::a; } | |
211 static int T::*stuff() { return &T::a; } | |
212 static int stuff1() { return T::sa; } | |
213 static int *stuff2() { return &T::sa; } | |
214 static int stuff3() { return sa; } // expected-warning {{lookup into dependent bases}} | |
215 static int *stuff4() { return &sa; } // expected-warning {{lookup into dependent bases}} | |
216 }; | |
217 | |
218 template <typename T> struct C : T { | |
219 int foo() { return b; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}} | |
220 int *bar() { return &b; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}} | |
221 int baz() { return T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}} | |
222 int T::*qux() { return &T::b; } // expected-error {{no member named 'b' in 'PR16014::A'}} | |
223 int T::*fuz() { return &U::a; } // expected-error {{use of undeclared identifier 'U'}} \ | |
224 // expected-warning {{unqualified lookup into dependent bases of class template 'C'}} | |
225 }; | |
226 | |
227 template struct B<A>; | |
228 template struct C<A>; // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}} | |
229 | |
230 template <typename T> struct D : T { | |
231 struct Inner { | |
232 int foo() { | |
233 // FIXME: MSVC can find this in D's base T! Even worse, if ::sa exists, | |
234 // clang will use it instead. | |
235 return sa; // expected-error {{use of undeclared identifier 'sa'}} | |
236 } | |
237 }; | |
238 }; | |
239 template struct D<A>; | |
240 | |
241 } | |
242 | |
243 namespace PR19233 { | |
244 template <class T> | |
245 struct A : T { | |
246 void foo() { | |
247 ::undef(); // expected-error {{no member named 'undef' in the global namespace}} | |
248 } | |
249 void bar() { | |
250 ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}} | |
251 } | |
252 void baz() { | |
253 B::qux(); // expected-error {{use of undeclared identifier 'B'}} \ | |
254 // expected-warning {{unqualified lookup into dependent bases of class template 'A'}} | |
255 } | |
256 }; | |
257 | |
258 struct B { void qux(); }; | |
259 struct C : B { }; | |
260 template struct A<C>; // No error! B is a base of A<C>, and qux is available. | |
261 | |
262 struct D { }; | |
263 template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}} | |
264 | |
265 } | |
266 | |
267 namespace nonmethod_missing_this { | |
268 template <typename T> struct Base { int y = 42; }; | |
269 template <typename T> struct Derived : Base<T> { | |
270 int x = y; // expected-warning {{lookup into dependent bases}} | |
271 auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}} | |
272 return y * j; // expected-warning {{lookup into dependent bases}} | |
273 } | |
274 int bar() { | |
275 return [&] { return y; }(); // expected-warning {{lookup into dependent bases}} | |
276 } | |
277 }; | |
278 template struct Derived<int>; | |
279 } | |
280 | |
281 namespace typedef_in_base { | |
282 template <typename T> struct A { typedef T NameFromBase; }; | |
283 template <typename T> struct B : A<T> { | |
284 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}} | |
285 }; | |
286 static_assert(sizeof(B<int>) == 4, ""); | |
287 } | |
288 | |
289 namespace struct_in_base { | |
290 template <typename T> struct A { struct NameFromBase {}; }; | |
291 template <typename T> struct B : A<T> { | |
292 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}} | |
293 }; | |
294 static_assert(sizeof(B<int>) == 1, ""); | |
295 } | |
296 | |
297 namespace enum_in_base { | |
298 template <typename T> struct A { enum NameFromBase { X }; }; | |
299 template <typename T> struct B : A<T> { | |
300 NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}} | |
301 }; | |
302 static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), ""); | |
303 } | |
304 | |
305 namespace two_types_in_base { | |
306 template <typename T> struct A { typedef T NameFromBase; }; // expected-note {{member found by ambiguous name lookup}} | |
307 template <typename T> struct B { struct NameFromBase { T m; }; }; // expected-note {{member found by ambiguous name lookup}} | |
308 template <typename T> struct C : A<T>, B<T> { | |
309 NameFromBase m; // expected-error {{member 'NameFromBase' found in multiple base classes of different types}} expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
310 }; | |
311 static_assert(sizeof(C<int>) != 0, ""); // expected-note {{in instantiation of template class 'two_types_in_base::C<int>' requested here}} | |
312 } | |
313 | |
314 namespace type_and_decl_in_base { | |
315 template <typename T> struct A { typedef T NameFromBase; }; | |
316 template <typename T> struct B { static const T NameFromBase = 42; }; | |
317 template <typename T> struct C : A<T>, B<T> { | |
318 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} | |
319 }; | |
320 } | |
321 | |
322 namespace classify_type_from_base { | |
323 template <typename T> struct A { struct NameFromBase {}; }; | |
324 template <typename T> struct B : A<T> { | |
325 A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}} | |
326 }; | |
327 } | |
328 | |
329 namespace classify_nontype_from_base { | |
330 // MSVC does not do lookup of non-type declarations from dependent template base | |
331 // classes. The extra lookup only applies to types. | |
332 template <typename T> struct A { void NameFromBase() {} }; | |
333 template <void (*F)()> struct B { }; | |
334 template <typename T> struct C : A<T> { | |
335 B<C::NameFromBase> a; // correct | |
336 B<NameFromBase> b; // expected-error {{use of undeclared identifier 'NameFromBase'}} | |
337 }; | |
338 } | |
339 | |
340 namespace template_in_base { | |
341 template <typename T> struct A { | |
342 template <typename U> struct NameFromBase { U x; }; | |
343 }; | |
344 template <typename T> struct B : A<T> { | |
345 // Correct form. | |
346 typename B::template NameFromBase<T> m; | |
347 }; | |
348 template <typename T> struct C : A<T> { | |
349 // Incorrect form. | |
350 NameFromBase<T> m; // expected-error {{no template named 'NameFromBase'}} | |
351 }; | |
352 } | |
353 | |
354 namespace type_in_inner_class_in_base { | |
355 template <typename T> | |
356 struct A { | |
357 struct B { typedef T NameFromBase; }; | |
358 }; | |
359 template <typename T> | |
360 struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} | |
361 } | |
362 | |
363 namespace type_in_inner_template_class_in_base { | |
364 template <typename T> | |
365 struct A { | |
366 template <typename U> struct B { typedef U InnerType; }; | |
367 }; | |
368 template <typename T> | |
369 struct C : A<T>::template B<T> { | |
370 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} | |
371 }; | |
372 } | |
373 | |
374 namespace have_nondependent_base { | |
375 template <typename T> | |
376 struct A { | |
377 // Nothing, lookup should fail. | |
378 }; | |
379 template <typename T> | |
380 struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} | |
381 struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}} | |
382 } | |
383 | |
384 namespace type_in_base_of_dependent_base { | |
385 struct A { typedef int NameFromBase; }; | |
386 template <typename T> | |
387 struct B : A {}; | |
388 template <typename T> | |
389 struct C : B<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
390 } | |
391 | |
392 namespace type_in_second_dependent_base { | |
393 template <typename T> | |
394 struct A {}; | |
395 template<typename T> | |
396 struct B { typedef T NameFromBase; }; | |
397 template <typename T> | |
398 struct D : A<T>, B<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
399 } | |
400 | |
401 namespace type_in_second_non_dependent_base { | |
402 struct A {}; | |
403 struct B { typedef int NameFromBase; }; | |
404 template<typename T> | |
405 struct C : A, B {}; | |
406 template <typename T> | |
407 struct D : C<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
408 } | |
409 | |
410 namespace type_in_virtual_base_of_dependent_base { | |
411 template <typename T> | |
412 struct A { typedef T NameFromBase; }; | |
413 template <typename T> | |
414 struct B : virtual A<T> {}; | |
415 template <typename T> | |
416 struct C : B<T>, virtual A<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
417 C<int> c; | |
418 } | |
419 | |
420 namespace type_in_base_of_multiple_dependent_bases { | |
421 template <typename T> | |
422 struct A { typedef T NameFromBase; }; | |
423 template <typename T> | |
424 struct B : public A<T> {}; | |
425 template <typename T> | |
426 struct C : B<T>, public A<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-warning {{direct base 'A<int>' is inaccessible due to ambiguity:}} | |
427 C<int> c; // expected-note {{in instantiation of template class 'type_in_base_of_multiple_dependent_bases::C<int>' requested here}} | |
428 } | |
429 | |
430 namespace type_in_dependent_base_of_non_dependent_type { | |
431 template<typename T> struct A { typedef int NameFromBase; }; | |
432 template<typename T> struct B : A<T> { | |
433 struct C; | |
434 template<typename TT> | |
435 struct D : C { | |
436 NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
437 }; | |
438 struct E : C { | |
439 NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
440 }; | |
441 }; | |
442 template<typename T> struct B<T>::C : B { | |
443 NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} | |
444 }; | |
445 template<typename T> struct F : B<T>::C { | |
446 NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}} | |
447 }; | |
448 } | |
449 | |
450 namespace lookup_in_function_contexts { | |
451 template <typename T> struct A { typedef T NameFromBase; }; | |
452 template <typename T> | |
453 struct B : A<T> { | |
454 // expected-warning@+1 {{lookup into dependent bases}} | |
455 static auto lateSpecifiedFunc() -> decltype(NameFromBase()) { | |
456 return {}; | |
457 } | |
458 | |
459 static void memberFunc() { | |
460 NameFromBase x; // expected-warning {{lookup into dependent bases}} | |
461 } | |
462 | |
463 static void funcLocalClass() { | |
464 struct X { | |
465 NameFromBase x; // expected-warning {{lookup into dependent bases}} | |
466 } y; | |
467 } | |
468 | |
469 void localClassMethod() { | |
470 struct X { | |
471 void bar() { | |
472 NameFromBase m; // expected-warning {{lookup into dependent bases}} | |
473 } | |
474 } x; | |
475 x.bar(); | |
476 } | |
477 | |
478 static void funcLambda() { | |
479 auto l = []() { | |
480 NameFromBase x; // expected-warning {{lookup into dependent bases}} | |
481 }; | |
482 l(); | |
483 } | |
484 | |
485 static constexpr int constexprFunc() { | |
486 NameFromBase x = {}; // expected-warning {{lookup into dependent bases}} | |
487 return sizeof(x); | |
488 } | |
489 | |
490 static auto autoFunc() { | |
491 NameFromBase x; // expected-warning {{lookup into dependent bases}} | |
492 return x; | |
493 } | |
494 }; | |
495 | |
496 // Force us to parse the methods. | |
497 template struct B<int>; | |
498 } | |
499 | |
500 namespace function_template_deduction { | |
501 // Overloaded function templates. | |
502 template <int N> int f() { return N; } | |
503 template <typename T> int f() { return sizeof(T); } | |
504 | |
505 // Dependent base class with type. | |
506 template <typename T> | |
507 struct A { typedef T NameFromBase; }; | |
508 template <typename T> | |
509 struct B : A<T> { | |
510 // expected-warning@+1 {{found via unqualified lookup into dependent bases}} | |
511 int x = f<NameFromBase>(); | |
512 }; | |
513 | |
514 // Dependent base class with enum. | |
515 template <typename T> struct C { enum { NameFromBase = 4 }; }; | |
516 template <typename T> struct D : C<T> { | |
517 // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}} | |
518 int x = f<NameFromBase>(); | |
519 }; | |
520 } | |
521 | |
522 namespace function_template_undef_impl { | |
523 template<class T> | |
524 void f() { | |
525 Undef::staticMethod(); // expected-error {{use of undeclared identifier 'Undef'}} | |
526 UndefVar.method(); // expected-error {{use of undeclared identifier 'UndefVar'}} | |
527 } | |
528 } | |
529 | |
530 namespace PR20716 { | |
531 template <template <typename T> class A> | |
532 struct B : A<int> | |
533 { | |
534 XXX x; // expected-error {{unknown type name}} | |
535 }; | |
536 | |
537 template <typename T> | |
538 struct C {}; | |
539 | |
540 template <typename T> | |
541 using D = C<T>; | |
542 | |
543 template <typename T> | |
544 struct E : D<T> | |
545 { | |
546 XXX x; // expected-error {{unknown type name}} | |
547 }; | |
548 } | |
549 | |
550 namespace PR23810 { | |
551 void f(int); | |
552 struct Base { | |
553 void f(); // expected-note{{must qualify identifier to find this declaration in dependent base class}} | |
554 }; | |
555 template <typename T> struct Template : T { | |
556 void member() { | |
557 f(); // expected-warning {{found via unqualified lookup into dependent bases}} | |
558 } | |
559 }; | |
560 void test() { | |
561 Template<Base> x; | |
562 x.member(); // expected-note{{requested here}} | |
563 }; | |
564 } | |
565 | |
566 namespace PR23823 { | |
567 // Don't delay lookup in SFINAE context. | |
568 template <typename T> decltype(g(T())) check(); // expected-note{{candidate template ignored: substitution failure [with T = int]: use of undeclared identifier 'g'}} | |
569 decltype(check<int>()) x; // expected-error{{no matching function for call to 'check'}} | |
570 | |
571 void h(); | |
572 template <typename T> decltype(h(T())) check2(); // expected-note{{candidate template ignored: substitution failure [with T = int]: no matching function for call to 'h'}} | |
573 decltype(check2<int>()) y; // expected-error{{no matching function for call to 'check2'}} | |
574 } | |
575 | |
576 // We also allow unqualified lookup into bases in contexts where the we know the | |
577 // undeclared identifier *must* be a type, such as a new expression or catch | |
578 // parameter type. | |
579 template <typename T> | |
580 struct UseUnqualifiedTypeNames : T { | |
581 void foo() { | |
582 void *P = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}} | |
583 size_t x = __builtin_offsetof(TheType, f2); // expected-warning {{unqualified lookup}} expected-error {{no type}} | |
584 try { | |
585 } catch (TheType) { // expected-warning {{unqualified lookup}} expected-error {{no type}} | |
586 } | |
587 enum E : IntegerType { E0 = 42 }; // expected-warning {{unqualified lookup}} expected-error {{no type}} | |
588 _Atomic(TheType) a; // expected-warning {{unqualified lookup}} expected-error {{no type}} | |
589 } | |
590 void out_of_line(); | |
591 }; | |
592 template <typename T> | |
593 void UseUnqualifiedTypeNames<T>::out_of_line() { | |
594 void *p = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}} | |
595 } | |
596 struct Base { | |
597 typedef int IntegerType; | |
598 struct TheType { | |
599 int f1, f2; | |
600 }; | |
601 }; | |
602 template struct UseUnqualifiedTypeNames<Base>; | |
603 struct BadBase { }; | |
604 template struct UseUnqualifiedTypeNames<BadBase>; // expected-note-re 2 {{in instantiation {{.*}} requested here}} | |
605 | |
606 namespace partial_template_lookup { | |
607 | |
608 class Bar; | |
609 class Spare; | |
610 | |
611 template <class T, class X = Bar> | |
612 class FooTemplated; | |
613 | |
614 class FooBase { | |
615 public: | |
616 typedef int BaseTypedef; | |
617 }; | |
618 | |
619 // Partial template spec (unused) | |
620 template <class T> | |
621 class FooTemplated<T, Spare> {}; | |
622 | |
623 // Partial template spec (used) | |
624 template <class T> | |
625 class FooTemplated<T, Bar> : public FooBase {}; | |
626 | |
627 // Full template spec | |
628 template <class T, class X> | |
629 class FooTemplated : public FooTemplated<T, Bar> { | |
630 public: | |
631 BaseTypedef Member; // expected-warning {{unqualified lookup}} | |
632 }; | |
633 } |