• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 namespace N {
4   enum { C };
5   template<class T> class B {
6     void f(T);
7   };
8 }
9 
f(C)10 template<class C> void N::B<C>::f(C) {
11   C b;
12 }
13 
14 namespace N {
15   enum { D };
16   namespace M {
17     enum { C , D };
18     template<typename C> class X {
19       template<typename U> void f(C, U);
20 
g(C,D)21       template<typename D> void g(C, D) {
22         C c;
23         D d;
24       }
25     };
26 
27     struct Y {
28       template<typename U> void f(U);
29     };
30   }
31 
32   struct Y {
33     template<typename D> void f(D);
34   };
35 }
36 
37 template<typename C>
38 template<typename D>
f(C,D)39 void N::M::X<C>::f(C, D) {
40   C c;
41   D d;
42 }
43 
44 template<typename C>
f(C)45 void N::M::Y::f(C) {
46   C c;
47 }
48 
49 template<typename D>
f(D)50 void N::Y::f(D) {
51   D d;
52 }
53 
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
57 
58   struct Base {
59     using AA = void;
60     using BB = void;
61   };
62   struct BaseT : Base {
63     using T = void;
64   };
65   struct BaseU : Base {
66     using U = void;
67   };
68 
69   template<typename T> struct A {
70     using AA = void;
71     template<typename U> struct B {
72       using BB = void;
73       void f(U);
74       void g(U);
75       void h(T);
76       void i(T);
77       template<typename V> void j(V);
78       template<typename V> void k(U);
79 
80       // OK: these find the template parameter not the member.
lSearchClassBetweenTemplateParameterLists::A::B81       template<typename AA> void l(AA x) { AA aa; }
mSearchClassBetweenTemplateParameterLists::A::B82       template<typename BB> void m(BB x) { BB bb; }
83 
84       struct C : Base {
85         // All OK; these find the template parameters.
fSearchClassBetweenTemplateParameterLists::A::B::C86         template<typename> void f(T x) { T t; }
gSearchClassBetweenTemplateParameterLists::A::B::C87         template<typename> void g(U x) { U u; }
hSearchClassBetweenTemplateParameterLists::A::B::C88         template<typename AA> void h(AA x) { AA aa; }
iSearchClassBetweenTemplateParameterLists::A::B::C89         template<typename BB> void i(BB x) { BB bb; }
90       };
91 
92       struct CT : BaseT {
fSearchClassBetweenTemplateParameterLists::A::B::CT93         template<typename> void f(T x) { // expected-error {{void}}
94           T t; // expected-error {{incomplete}}
95         }
gSearchClassBetweenTemplateParameterLists::A::B::CT96         template<typename> void g(U x) { U u; }
hSearchClassBetweenTemplateParameterLists::A::B::CT97         template<typename AA> void h(AA x) { AA aa; }
iSearchClassBetweenTemplateParameterLists::A::B::CT98         template<typename BB> void i(BB x) { BB bb; }
99       };
100 
101       struct CU : BaseU {
fSearchClassBetweenTemplateParameterLists::A::B::CU102         template<typename> void f(T x) { T t; }
gSearchClassBetweenTemplateParameterLists::A::B::CU103         template<typename> void g(U x) { // expected-error {{void}}
104           U u; // expected-error {{incomplete}}
105         }
hSearchClassBetweenTemplateParameterLists::A::B::CU106         template<typename AA> void h(AA x) { AA aa; }
iSearchClassBetweenTemplateParameterLists::A::B::CU107         template<typename BB> void i(BB x) { BB bb; }
108       };
109     };
110   };
111 
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
118 
119   // OK, 'AA' found in (3)
120   template<typename T> template<typename AA>
f(AA)121   void A<T>::B<AA>::f(AA) {
122     AA aa;
123   }
124 
125   // error, 'BB' found in (2)
126   template<typename T> template<typename BB>
g(BB)127   void A<T>::B<BB>::g(BB) { // expected-error {{does not match}}
128     BB bb; // expected-error {{incomplete type}}
129   }
130 
131   // error, 'AA' found in (4)
132   template<typename AA> template<typename U>
h(AA)133   void A<AA>::B<U>::h(AA) { // expected-error {{does not match}}
134     AA aa; // expected-error {{incomplete type}}
135   }
136 
137   // error, 'BB' found in (2)
138   template<typename BB> template<typename U>
i(BB)139   void A<BB>::B<U>::i(BB) { // expected-error {{does not match}}
140     BB bb; // expected-error {{incomplete type}}
141   }
142 
143   // OK, 'BB' found in (1)
144   template<typename T> template<typename U> template<typename BB>
j(BB)145   void A<T>::B<U>::j(BB) {
146     BB bb;
147   }
148 
149   // error, 'BB' found in (2)
150   template<typename T> template<typename BB> template<typename V>
k(V)151   void A<T>::B<BB>::k(V) { // expected-error {{does not match}}
152     BB bb; // expected-error {{incomplete type}}
153   }
154 }
155