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 | void overload1(const T &); |
88 | void overload1(const S &); |
89 | }; |
90 | |
91 | template<typename T, typename S> |
92 | void completeDependentMembers(TemplateClass<T, S> &object, |
93 | TemplateClass<int, S> *object2) { |
94 | object.field; |
95 | object2->field; |
96 | // CHECK-CC2: baseTemplateField (InBase) : [#T#][#BaseTemplate<T>::#]baseTemplateField |
97 | // CHECK-CC2: baseTemplateFunction (InBase) : [#T#][#BaseTemplate<T>::#]baseTemplateFunction() |
98 | // CHECK-CC2: field : [#T#]field |
99 | // CHECK-CC2: function : [#T#]function() |
100 | // CHECK-CC2: member1 (InBase) : [#int#][#Base1::#]member1 |
101 | // CHECK-CC2: member2 (InBase) : [#float#][#Base1::#]member2 |
102 | // CHECK-CC2: overload1 : [#void#]overload1(<#const T &#>) |
103 | // CHECK-CC2: overload1 : [#void#]overload1(<#const S &#>) |
104 | |
105 | // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:94:10 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s |
106 | // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:95:12 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s |
107 | } |
108 | |
109 | |
110 | void completeDependentSpecializedMembers(TemplateClass<int, double> &object, |
111 | TemplateClass<int, double> *object2) { |
112 | object.field; |
113 | object2->field; |
114 | // CHECK-CC3: baseTemplateField (InBase) : [#int#][#BaseTemplate<int>::#]baseTemplateField |
115 | // CHECK-CC3: baseTemplateFunction (InBase) : [#int#][#BaseTemplate<int>::#]baseTemplateFunction() |
116 | // CHECK-CC3: field : [#int#]field |
117 | // CHECK-CC3: function : [#int#]function() |
118 | // CHECK-CC3: member1 (InBase) : [#int#][#Base1::#]member1 |
119 | // CHECK-CC3: member2 (InBase) : [#float#][#Base1::#]member2 |
120 | // CHECK-CC3: overload1 : [#void#]overload1(<#const int &#>) |
121 | // CHECK-CC3: overload1 : [#void#]overload1(<#const double &#>) |
122 | |
123 | // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:112:10 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s |
124 | // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:113:12 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s |
125 | } |
126 | |
127 | template <typename T> |
128 | class Template { |
129 | public: |
130 | BaseTemplate<int> o1; |
131 | BaseTemplate<T> o2; |
132 | |
133 | void function() { |
134 | o1.baseTemplateField; |
135 | // CHECK-CC4: BaseTemplate : BaseTemplate:: |
136 | // CHECK-CC4: baseTemplateField : [#int#]baseTemplateField |
137 | // CHECK-CC4: baseTemplateFunction : [#int#]baseTemplateFunction() |
138 | // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:134:8 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s |
139 | o2.baseTemplateField; |
140 | // CHECK-CC5: BaseTemplate : BaseTemplate:: |
141 | // CHECK-CC5: baseTemplateField : [#T#]baseTemplateField |
142 | // CHECK-CC5: baseTemplateFunction : [#T#]baseTemplateFunction() |
143 | // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:139:8 %s -o - | FileCheck -check-prefix=CHECK-CC5 %s |
144 | this->o1; |
145 | // CHECK-CC6: [#void#]function() |
146 | // CHECK-CC6: o1 : [#BaseTemplate<int>#]o1 |
147 | // CHECK-CC6: o2 : [#BaseTemplate<T>#]o2 |
148 | // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:144:11 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s |
149 | } |
150 | |
151 | static void staticFn(T &obj); |
152 | |
153 | struct Nested { }; |
154 | }; |
155 | |
156 | template<typename T> |
157 | void dependentColonColonCompletion() { |
158 | Template<T>::staticFn(); |
159 | // CHECK-CC7: function : [#void#]function() |
160 | // CHECK-CC7: Nested : Nested |
161 | // CHECK-CC7: o1 : [#BaseTemplate<int>#]o1 |
162 | // CHECK-CC7: o2 : [#BaseTemplate<T>#]o2 |
163 | // CHECK-CC7: staticFn : [#void#]staticFn(<#T &obj#>) |
164 | // CHECK-CC7: Template : Template |
165 | // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:158:16 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s |
166 | typename Template<T>::Nested m; |
167 | // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:166:25 %s -o - | FileCheck -check-prefix=CHECK-CC7 %s |
168 | } |
169 | |
170 | class Proxy2 { |
171 | public: |
172 | Derived *operator->() const; |
173 | int member5; |
174 | }; |
175 | |
176 | void test2(const Proxy2 &p) { |
177 | p-> |
178 | } |
179 | |
180 | void test3(const Proxy2 &p) { |
181 | p. |
182 | } |
183 | |
184 | // RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:177:6 %s -o - | FileCheck -check-prefix=CHECK-CC8 --implicit-check-not="Derived : Derived(" %s |
185 | // CHECK-CC8: Base1 (InBase) : Base1:: |
186 | // CHECK-CC8: member1 (InBase) : [#int#][#Base1::#]member1 |
187 | // CHECK-CC8: member1 (InBase) : [#int#][#Base2::#]member1 |
188 | // CHECK-CC8: member2 (InBase) : [#float#][#Base1::#]member2 |
189 | // CHECK-CC8: member3 (InBase) : [#double#][#Base2::#]member3 |
190 | // CHECK-CC8: member4 : [#int#]member4 |
191 | // CHECK-CC8: member5 : [#int#]member5 (requires fix-it: {177:4-177:6} to ".") |
192 | // CHECK-CC8: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#float#>) |
193 | // CHECK-CC8: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#double#>)[# const#] |
194 | // CHECK-CC8: memfun1 (Hidden,InBase) : [#void#]Base2::memfun1(<#int#>) |
195 | // CHECK-CC8: memfun2 (InBase) : [#void#][#Base3::#]memfun2(<#int#>) |
196 | // CHECK-CC8: memfun3 : [#int#]memfun3(<#int#>) |
197 | // CHECK-CC8: operator-> : [#Derived *#]operator->()[# const#] (requires fix-it: {177:4-177:6} to ".") |
198 | |
199 | // RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:181:6 %s -o - | FileCheck -check-prefix=CHECK-CC9 --implicit-check-not="Derived : Derived(" %s |
200 | // CHECK-CC9: Base1 (InBase) : Base1:: |
201 | // CHECK-CC9: member1 (InBase) : [#int#][#Base1::#]member1 (requires fix-it: {181:4-181:5} to "->") |
202 | // CHECK-CC9: member1 (InBase) : [#int#][#Base2::#]member1 (requires fix-it: {181:4-181:5} to "->") |
203 | // CHECK-CC9: member2 (InBase) : [#float#][#Base1::#]member2 (requires fix-it: {181:4-181:5} to "->") |
204 | // CHECK-CC9: member3 (InBase) : [#double#][#Base2::#]member3 (requires fix-it: {181:4-181:5} to "->") |
205 | // CHECK-CC9: member4 : [#int#]member4 (requires fix-it: {181:4-181:5} to "->") |
206 | // CHECK-CC9: member5 : [#int#]member5 |
207 | // CHECK-CC9: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#float#>) (requires fix-it: {181:4-181:5} to "->") |
208 | // CHECK-CC9: memfun1 (InBase) : [#void#][#Base3::#]memfun1(<#double#>)[# const#] (requires fix-it: {181:4-181:5} to "->") |
209 | // CHECK-CC9: memfun1 (Hidden,InBase) : [#void#]Base2::memfun1(<#int#>) (requires fix-it: {181:4-181:5} to "->") |
210 | // CHECK-CC9: memfun2 (InBase) : [#void#][#Base3::#]memfun2(<#int#>) (requires fix-it: {181:4-181:5} to "->") |
211 | // CHECK-CC9: memfun3 : [#int#]memfun3(<#int#>) (requires fix-it: {181:4-181:5} to "->") |
212 | // CHECK-CC9: operator-> : [#Derived *#]operator->()[# const#] |
213 | |