xref: /llvm-project/clang/test/CodeCompletion/member-access.cpp (revision ba174855203403f6c3e2a46bdd79dbb3e27ac6a4)
1 struct Base1 {
2   int member1;
3   float member2;
4 };
5 
6 struct Base2 {
7   int member1;
8   double member3;
9   void memfun1(int);
10 };
11 
12 struct Base3 : Base1, Base2 {
13   void memfun1(float);
14   void memfun1(double) const;
15   void memfun2(int);
16 };
17 
18 struct Derived : Base3 {
19   template <typename T> Derived(T);
20   Derived(int);
21   int member4;
22   int memfun3(int);
23 };
24 
25 class Proxy {
26 public:
27   Derived *operator->() const;
28 };
29 
30 void test(const Proxy &p) {
31   p->
32 }
33 
34 struct Test1 {
35   Base1 b;
36 
37   static void sfunc() {
38     b. // expected-error {{invalid use of member 'b' in static member function}}
39   }
40 };
41 
42 struct Foo {
43   void foo() const;
44   static void foo(bool);
45 };
46 
47 struct Bar {
48   void foo(bool param) {
49     Foo::foo(  );// unresolved member expression with an implicit base
50   }
51 };
52 
53   // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:31:6 %s -o - | FileCheck -check-prefix=CHECK-CC1 --implicit-check-not="Derived : Derived(" %s
54   // CHECK-CC1: Base1 (InBase) : Base1::
55   // CHECK-CC1: member1 (InBase) : [#int#][#Base1::#]member1
56   // CHECK-CC1: member1 (InBase) : [#int#][#Base2::#]member1
57   // CHECK-CC1: member2 (InBase) : [#float#][#Base1::#]member2
58   // CHECK-CC1: member3 (InBase)
59   // CHECK-CC1: member4
60   // CHECK-CC1: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#float#>)
61   // CHECK-CC1: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#double#>)[# const#]
62   // CHECK-CC1: memfun1 (Hidden,InBase) : [#void#]Base2::memfun1(<#int#>)
63   // CHECK-CC1: memfun2 (InBase) : [#void#][#Base3::#]memfun2(<#int#>)
64   // CHECK-CC1: memfun3 : [#int#]memfun3(<#int#>)
65 
66 // Make sure this doesn't crash
67 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:38:7 %s -verify
68 
69 // Make sure this also doesn't crash
70 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:49:14 %s
71 
72 
73 template<typename T>
74 class BaseTemplate {
75 public:
76   T baseTemplateFunction();
77 
78   T baseTemplateField;
79 };
80 
81 template<typename T, typename S>
82 class TemplateClass: public Base1 , public BaseTemplate<T> {
83 public:
84   T function() { }
85   T field;
86 
87   TemplateClass<S, T> &relatedField;
88   BaseTemplate<S> &relatedFunction();
89 
90   void overload1(const T &);
91   void overload1(const S &);
92 };
93 
94 template<typename T, typename S>
95 void completeDependentMembers(TemplateClass<T, S> &object,
96                               TemplateClass<int, S> *object2) {
97   object.field;
98   object2->field;
99 // CHECK-CC2: baseTemplateField (InBase) : [#T#][#BaseTemplate<T>::#]baseTemplateField
100 // CHECK-CC2: baseTemplateFunction (InBase) : [#T#][#BaseTemplate<T>::#]baseTemplateFunction()
101 // CHECK-CC2: field : [#T#]field
102 // CHECK-CC2: function : [#T#]function()
103 // CHECK-CC2: member1 (InBase) : [#int#][#Base1::#]member1
104 // CHECK-CC2: member2 (InBase) : [#float#][#Base1::#]member2
105 // CHECK-CC2: overload1 : [#void#]overload1(<#const T &#>)
106 // CHECK-CC2: overload1 : [#void#]overload1(<#const S &#>)
107 
108 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:97:10 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
109 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:98:12 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
110 
111   auto copy_object = object;
112   auto copy_object2 = object2;
113   object.field;
114   object2->field;
115 // CHECK-AUTO: field : [#T#]field
116 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:113:10 %s -o - | FileCheck -check-prefix=CHECK-AUTO %s
117 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:114:12 %s -o - | FileCheck -check-prefix=CHECK-AUTO %s
118 
119   object.relatedField.relatedFunction().baseTemplateField;
120 // CHECK-DEP-CHAIN: baseTemplateField : [#T#]baseTemplateField
121 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:119:41 %s -o - | FileCheck -check-prefix=CHECK-DEP-CHAIN %s
122 }
123 
124 
125 void completeDependentSpecializedMembers(TemplateClass<int, double> &object,
126                                          TemplateClass<int, double> *object2) {
127   object.field;
128   object2->field;
129 // CHECK-CC3: baseTemplateField (InBase) : [#int#][#BaseTemplate<int>::#]baseTemplateField
130 // CHECK-CC3: baseTemplateFunction (InBase) : [#int#][#BaseTemplate<int>::#]baseTemplateFunction()
131 // CHECK-CC3: field : [#int#]field
132 // CHECK-CC3: function : [#int#]function()
133 // CHECK-CC3: member1 (InBase) : [#int#][#Base1::#]member1
134 // CHECK-CC3: member2 (InBase) : [#float#][#Base1::#]member2
135 // CHECK-CC3: overload1 : [#void#]overload1(<#const int &#>)
136 // CHECK-CC3: overload1 : [#void#]overload1(<#const double &#>)
137 
138 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:127:10 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
139 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:128:12 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
140 }
141 
142 template <typename T>
143 class Template {
144 public:
145   BaseTemplate<int> o1;
146   BaseTemplate<T> o2;
147 
148   void function() {
149     o1.baseTemplateField;
150 // CHECK-CC4: BaseTemplate : BaseTemplate::
151 // CHECK-CC4: baseTemplateField : [#int#]baseTemplateField
152 // CHECK-CC4: baseTemplateFunction : [#int#]baseTemplateFunction()
153 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:149:8 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s
154     o2.baseTemplateField;
155 // CHECK-CC5: BaseTemplate : BaseTemplate::
156 // CHECK-CC5: baseTemplateField : [#T#]baseTemplateField
157 // CHECK-CC5: baseTemplateFunction : [#T#]baseTemplateFunction()
158 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:154:8 %s -o - | FileCheck -check-prefix=CHECK-CC5 %s
159     this->o1;
160 // CHECK-CC6: [#void#]function()
161 // CHECK-CC6: o1 : [#BaseTemplate<int>#]o1
162 // CHECK-CC6: o2 : [#BaseTemplate<T>#]o2
163 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:159:11 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s
164   }
165 
166   static void staticFn(T &obj);
167 
168   struct Nested { };
169 };
170 
171 template<typename T>
172 void dependentColonColonCompletion() {
173   Template<T>::staticFn();
174 // CHECK-CC7: function : [#void#]function()
175 // CHECK-CC7: Nested : Nested
176 // CHECK-CC7: o1 : [#BaseTemplate<int>#]o1
177 // CHECK-CC7: o2 : [#BaseTemplate<T>#]o2
178 // CHECK-CC7: staticFn : [#void#]staticFn(<#T &obj#>)
179 // CHECK-CC7: Template : Template
180 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:173:16 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s
181   typename Template<T>::Nested m;
182 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:181:25 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s
183 }
184 
185 class Proxy2 {
186 public:
187   Derived *operator->() const;
188   int member5;
189 };
190 
191 void test2(const Proxy2 &p) {
192   p->
193 }
194 
195 void test3(const Proxy2 &p) {
196   p.
197 }
198 
199 // RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:192:6 %s -o - | FileCheck -check-prefix=CHECK-CC8 --implicit-check-not="Derived : Derived(" %s
200 // CHECK-CC8: Base1 (InBase) : Base1::
201 // CHECK-CC8: member1 (InBase) : [#int#][#Base1::#]member1
202 // CHECK-CC8: member1 (InBase) : [#int#][#Base2::#]member1
203 // CHECK-CC8: member2 (InBase) : [#float#][#Base1::#]member2
204 // CHECK-CC8: member3 (InBase) : [#double#][#Base2::#]member3
205 // CHECK-CC8: member4 : [#int#]member4
206 // CHECK-CC8: member5 : [#int#]member5 (requires fix-it: {192:4-192:6} to ".")
207 // CHECK-CC8: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#float#>)
208 // CHECK-CC8: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#double#>)[# const#]
209 // CHECK-CC8: memfun1 (Hidden,InBase) : [#void#]Base2::memfun1(<#int#>)
210 // CHECK-CC8: memfun2 (InBase) : [#void#][#Base3::#]memfun2(<#int#>)
211 // CHECK-CC8: memfun3 : [#int#]memfun3(<#int#>)
212 // CHECK-CC8: operator-> : [#Derived *#]operator->()[# const#] (requires fix-it: {192:4-192:6} to ".")
213 
214 // RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:196:6 %s -o - | FileCheck -check-prefix=CHECK-CC9 --implicit-check-not="Derived : Derived(" %s
215 // CHECK-CC9: Base1 (InBase) : Base1::
216 // CHECK-CC9: member1 (InBase) : [#int#][#Base1::#]member1 (requires fix-it: {196:4-196:5} to "->")
217 // CHECK-CC9: member1 (InBase) : [#int#][#Base2::#]member1 (requires fix-it: {196:4-196:5} to "->")
218 // CHECK-CC9: member2 (InBase) : [#float#][#Base1::#]member2 (requires fix-it: {196:4-196:5} to "->")
219 // CHECK-CC9: member3 (InBase) : [#double#][#Base2::#]member3 (requires fix-it: {196:4-196:5} to "->")
220 // CHECK-CC9: member4 : [#int#]member4 (requires fix-it: {196:4-196:5} to "->")
221 // CHECK-CC9: member5 : [#int#]member5
222 // CHECK-CC9: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#float#>) (requires fix-it: {196:4-196:5} to "->")
223 // CHECK-CC9: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#double#>)[# const#] (requires fix-it: {196:4-196:5} to "->")
224 // CHECK-CC9: memfun1 (Hidden,InBase) : [#void#]Base2::memfun1(<#int#>) (requires fix-it: {196:4-196:5} to "->")
225 // CHECK-CC9: memfun2 (InBase) : [#void#][#Base3::#]memfun2(<#int#>) (requires fix-it: {196:4-196:5} to "->")
226 // CHECK-CC9: memfun3 : [#int#]memfun3(<#int#>) (requires fix-it: {196:4-196:5} to "->")
227 // CHECK-CC9: operator-> : [#Derived *#]operator->()[# const#]
228 
229 // These overload sets differ only by return type and this-qualifiers.
230 // So for any given callsite, only one is available.
231 struct Overloads {
232   double ConstOverload(char);
233   int ConstOverload(char) const;
234 
235   int RefOverload(char) &;
236   double RefOverload(char) const&;
237   char RefOverload(char) &&;
238 };
239 void testLValue(Overloads& Ref) {
240   Ref.
241 }
242 void testConstLValue(const Overloads& ConstRef) {
243   ConstRef.
244 }
245 void testRValue() {
246   Overloads().
247 }
248 void testXValue(Overloads& X) {
249   static_cast<Overloads&&>(X).
250 }
251 
252 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:240:7 %s -o - | FileCheck -check-prefix=CHECK-LVALUE %s \
253 // RUN: --implicit-check-not="[#int#]ConstOverload(" \
254 // RUN: --implicit-check-not="[#double#]RefOverload(" \
255 // RUN: --implicit-check-not="[#char#]RefOverload("
256 // CHECK-LVALUE-DAG: [#double#]ConstOverload(
257 // CHECK-LVALUE-DAG: [#int#]RefOverload(
258 
259 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:243:12 %s -o - | FileCheck -check-prefix=CHECK-CONSTLVALUE %s \
260 // RUN: --implicit-check-not="[#double#]ConstOverload(" \
261 // RUN: --implicit-check-not="[#int#]RefOverload(" \
262 // RUN: --implicit-check-not="[#char#]RefOverload("
263 // CHECK-CONSTLVALUE: [#int#]ConstOverload(
264 // CHECK-CONSTLVALUE: [#double#]RefOverload(
265 
266 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:246:15 %s -o - | FileCheck -check-prefix=CHECK-PRVALUE %s \
267 // RUN: --implicit-check-not="[#int#]ConstOverload(" \
268 // RUN: --implicit-check-not="[#int#]RefOverload(" \
269 // RUN: --implicit-check-not="[#double#]RefOverload("
270 // CHECK-PRVALUE: [#double#]ConstOverload(
271 // CHECK-PRVALUE: [#char#]RefOverload(
272 
273 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:249:31 %s -o - | FileCheck -check-prefix=CHECK-XVALUE %s \
274 // RUN: --implicit-check-not="[#int#]ConstOverload(" \
275 // RUN: --implicit-check-not="[#int#]RefOverload(" \
276 // RUN: --implicit-check-not="[#double#]RefOverload("
277 // CHECK-XVALUE: [#double#]ConstOverload(
278 // CHECK-XVALUE: [#char#]RefOverload(
279 
280 void testOverloadOperator() {
281   struct S {
282     char operator=(int) const;
283     int operator=(int);
284   } s;
285   return s.
286 }
287 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:285:12 %s -o - | FileCheck -check-prefix=CHECK-OPER %s \
288 // RUN: --implicit-check-not="[#char#]operator=("
289 // CHECK-OPER: [#int#]operator=(
290 
291 struct S { int member; };
292 S overloaded(int);
293 S overloaded(double);
294 void foo() {
295   // No overload matches, but we have recovery-expr with the correct type.
296   overloaded().
297 }
298 // RUN: not %clang_cc1 -fsyntax-only -frecovery-ast -frecovery-ast-type -code-completion-at=%s:296:16 %s -o - | FileCheck -check-prefix=CHECK-RECOVERY %s
299 // CHECK-RECOVERY: [#int#]member
300 template <typename T>
301 void fooDependent(T t) {
302   // Overload not resolved, but we notice all candidates return the same type.
303   overloaded(t).
304 }
305 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:303:17 %s -o - | FileCheck -check-prefix=CHECK-OVERLOAD %s
306 // CHECK-OVERLOAD: [#int#]member
307 
308 struct Base4 {
309   Base4 base4();
310 };
311 
312 template <typename T>
313 struct Derived2 : Base4 {};
314 
315 template <typename T>
316 void testMembersFromBasesInDependentContext() {
317   Derived2<T> X;
318   (void)X.base4().base4();
319   // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:318:19 %s -o - | FileCheck -check-prefix=CHECK-MEMBERS-FROM-BASE-DEPENDENT %s
320   // CHECK-MEMBERS-FROM-BASE-DEPENDENT: [#Base4#]base4
321 }
322 
323 namespace members_using_fixits {
324   struct Bar {
325     void method();
326     int field;
327   };
328   struct Baz: Bar {
329     using Bar::method;
330     using Bar::field;
331   };
332   void testMethod(Baz* ptr) {
333     ptr.m
334   }
335   // RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:333:10 %s -o - | FileCheck -check-prefix=CHECK-METHOD-DECLARED-VIA-USING %s
336   // CHECK-METHOD-DECLARED-VIA-USING: [#void#]method() (requires fix-it: {333:8-333:9} to "->")
337 
338   void testField(Baz* ptr) {
339     ptr.f
340   }
341   // RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:339:10 %s -o - | FileCheck -check-prefix=CHECK-FIELD-DECLARED-VIA-USING %s
342   // CHECK-FIELD-DECLARED-VIA-USING: [#int#]field (requires fix-it: {339:8-339:9} to "->")
343 }
344 
345 namespace function_can_be_call {
346   struct S {
347     template <typename T, typename U, typename V = int>
348     T foo(U, V);
349   };
350 
351   void test() {
352     &S::f
353   }
354   // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:352:9 %s -o - | FileCheck -check-prefix=CHECK_FUNCTION_CAN_BE_CALL %s
355   // CHECK_FUNCTION_CAN_BE_CALL: COMPLETION: foo : [#T#]foo<<#typename T#>, <#typename U#>>(<#U#>, <#V#>)
356 }
357 
358 namespace deref_dependent_this {
359 template <typename T>
360 class A {
361   int field;
362 
363   void function() {
364     (*this).field;
365 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:364:13 %s -o - | FileCheck -check-prefix=CHECK-DEREF-THIS %s
366 // CHECK-DEREF-THIS: field : [#int#]field
367 // CHECK-DEREF-THIS: [#void#]function()
368   }
369 };
370 
371 template <typename Element>
372 struct RepeatedField {
373   void Add();
374 };
375 
376 template <typename T>
377 RepeatedField<T>* MutableRepeatedField() {}
378 
379 template <class T>
380 void Foo() {
381   auto& C = *MutableRepeatedField<T>();
382   C.
383 }
384 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:382:5 %s -o - | FileCheck -check-prefix=CHECK-DEREF-DEPENDENT %s
385 // CHECK-DEREF-DEPENDENT: [#void#]Add()
386 }
387 
388 namespace dependent_smart_pointer {
389 template <typename T>
390 struct smart_pointer {
391   T* operator->();
392 };
393 
394 template <typename T>
395 struct node {
396   smart_pointer<node<T>> next;
397   void foo() {
398     next->next;
399     // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:398:11 %s -o - | FileCheck -check-prefix=CHECK-DEPENDENT-SMARTPTR %s
400     // CHECK-DEPENDENT-SMARTPTR: [#smart_pointer<node<T>>#]next
401   }
402 };
403 }
404 
405 namespace dependent_nested_class {
406 template <typename T>
407 struct Foo {
408   struct Bar {
409     int field;
410   };
411 };
412 template <typename T>
413 void f() {
414   typename Foo<T>::Bar bar;
415   bar.field;
416   // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:415:7 %s -o - | FileCheck -check-prefix=CHECK-DEPENDENT-NESTEDCLASS %s
417   // CHECK-DEPENDENT-NESTEDCLASS: [#int#]field
418 }
419 }
420