1 // RUN: %clang_cc1 -fsyntax-only -verify %s
5 template<class T
> class B
{
10 template<class C
> void N::B
<C
>::f(C
) {
18 template<typename C
> class X
{
19 template<typename U
> void f(C
, U
);
21 template<typename D
> void g(C
, D
) {
28 template<typename U
> void f(U
);
33 template<typename D
> void f(D
);
39 void N::M::X
<C
>::f(C
, D
) {
54 // Ensure we properly interleave the searches within classes and template parameter lists.
55 namespace SearchClassBetweenTemplateParameterLists
{
56 int AA
, BB
; // none of the below lookups should ever consider these
69 template<typename T
> struct A
{
71 template<typename U
> struct B
{
77 template<typename V
> void j(V
);
78 template<typename V
> void k(U
);
80 // OK: these find the template parameter not the member.
81 template<typename AA
> void l(AA x
) { AA aa
; }
82 template<typename BB
> void m(BB x
) { BB bb
; }
85 // All OK; these find the template parameters.
86 template<typename
> void f(T x
) { T t
; }
87 template<typename
> void g(U x
) { U u
; }
88 template<typename AA
> void h(AA x
) { AA aa
; }
89 template<typename BB
> void i(BB x
) { BB bb
; }
93 template<typename
> void f(T x
) { // expected-error {{void}}
94 T t
; // expected-error {{incomplete}}
96 template<typename
> void g(U x
) { U u
; }
97 template<typename AA
> void h(AA x
) { AA aa
; }
98 template<typename BB
> void i(BB x
) { BB bb
; }
102 template<typename
> void f(T x
) { T t
; }
103 template<typename
> void g(U x
) { // expected-error {{void}}
104 U u
; // expected-error {{incomplete}}
106 template<typename AA
> void h(AA x
) { AA aa
; }
107 template<typename BB
> void i(BB x
) { BB bb
; }
112 // Search order for the below is:
113 // 1) template parameter scope of the function itself (if any)
114 // 2) class of which function is a member
115 // 3) template parameter scope of inner class
116 // 4) class of which class is a member
117 // 5) template parameter scope of outer class
119 // OK, 'AA' found in (3)
120 template<typename T
> template<typename AA
>
121 void A
<T
>::B
<AA
>::f(AA
) {
125 // error, 'BB' found in (2)
126 template<typename T
> template<typename BB
>
127 void A
<T
>::B
<BB
>::g(BB
) { // expected-error {{does not match}}
128 BB bb
; // expected-error {{incomplete type}}
131 // error, 'AA' found in (4)
132 template<typename AA
> template<typename U
>
133 void A
<AA
>::B
<U
>::h(AA
) { // expected-error {{does not match}}
134 AA aa
; // expected-error {{incomplete type}}
137 // error, 'BB' found in (2)
138 template<typename BB
> template<typename U
>
139 void A
<BB
>::B
<U
>::i(BB
) { // expected-error {{does not match}}
140 BB bb
; // expected-error {{incomplete type}}
143 // OK, 'BB' found in (1)
144 template<typename T
> template<typename U
> template<typename BB
>
145 void A
<T
>::B
<U
>::j(BB
) {
149 // error, 'BB' found in (2)
150 template<typename T
> template<typename BB
> template<typename V
>
151 void A
<T
>::B
<BB
>::k(V
) { // expected-error {{does not match}}
152 BB bb
; // expected-error {{incomplete type}}