Commit | Line | Data |
---|---|---|
b811d2c2 | 1 | # Copyright 2017-2020 Free Software Foundation, Inc. |
8955eb2d PA |
2 | |
3 | # This program is free software; you can redistribute it and/or modify | |
4 | # it under the terms of the GNU General Public License as published by | |
5 | # the Free Software Foundation; either version 3 of the License, or | |
6 | # (at your option) any later version. | |
7 | # | |
8 | # This program is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
13 | # You should have received a copy of the GNU General Public License | |
14 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
15 | ||
16 | # This file is part of the gdb testsuite. | |
17 | ||
18 | load_lib completion-support.exp | |
19 | ||
20 | standard_testfile cpls.cc cpls2.cc cpls-hyphen.cc | |
21 | ||
22 | if {[prepare_for_testing "failed to prepare" $testfile \ | |
23 | [list $srcfile $srcfile2 $srcfile3] {debug}]} { | |
24 | return -1 | |
25 | } | |
26 | ||
4ee9b0c5 SL |
27 | # Tests below are about tab-completion, which doesn't work if readline |
28 | # library isn't used. Check it first. | |
29 | ||
30 | if { ![readline_is_used] } { | |
31 | untested "no tab completion support without readline" | |
32 | return -1 | |
33 | } | |
34 | ||
8955eb2d PA |
35 | # Disable the completion limit for the whole testcase. |
36 | gdb_test_no_output "set max-completions unlimited" | |
37 | ||
38 | # Start of tests. | |
39 | ||
40 | # Test completion of all parameter prefixes, crossing "(" and ")", | |
41 | # with and without whitespace. | |
42 | ||
43 | proc_with_prefix all-param-prefixes {} { | |
44 | ||
45 | # Test both linespecs and explicit locations. | |
46 | foreach cmd_prefix {"b" "b -function"} { | |
47 | set line "$cmd_prefix param_prefixes_test_long(long)" | |
48 | set start [index_after "test_long" $line] | |
49 | test_complete_prefix_range $line $start | |
50 | ||
51 | # Same, but with extra spaces. Note that the original spaces in | |
52 | # the input line are preserved after completion. | |
53 | test_gdb_complete_unique \ | |
54 | "$cmd_prefix param_prefixes_test_long(long " \ | |
55 | "$cmd_prefix param_prefixes_test_long(long )" | |
56 | test_gdb_complete_unique \ | |
57 | "$cmd_prefix param_prefixes_test_long( long " \ | |
58 | "$cmd_prefix param_prefixes_test_long( long )" | |
59 | test_gdb_complete_unique \ | |
60 | "$cmd_prefix param_prefixes_test_long ( long " \ | |
61 | "$cmd_prefix param_prefixes_test_long ( long )" | |
62 | ||
63 | # Complete all parameter prefixes between "(i" and "(int*, int&)". | |
64 | # Note that this exercises completing when the point is at the | |
65 | # space in "param_prefixes_test_intp_intr(int*, ". | |
66 | set line "$cmd_prefix param_prefixes_test_intp_intr(int*, int&)" | |
67 | set start [index_after "intp_intr" $line] | |
68 | test_complete_prefix_range $line $start | |
69 | ||
70 | # Similar, but with extra spaces. | |
71 | test_gdb_complete_unique \ | |
72 | "$cmd_prefix param_prefixes_test_intp_intr ( int* " \ | |
73 | "$cmd_prefix param_prefixes_test_intp_intr ( int* , int&)" | |
74 | ||
75 | test_gdb_complete_unique \ | |
76 | "$cmd_prefix param_prefixes_test_intp_intr ( int *" \ | |
77 | "$cmd_prefix param_prefixes_test_intp_intr ( int *, int&)" | |
78 | ||
79 | test_gdb_complete_unique \ | |
80 | "$cmd_prefix param_prefixes_test_intp_intr ( int *, int " \ | |
81 | "$cmd_prefix param_prefixes_test_intp_intr ( int *, int &)" | |
82 | ||
83 | test_gdb_complete_unique \ | |
84 | "$cmd_prefix param_prefixes_test_intp_intr ( int *, int & " \ | |
85 | "$cmd_prefix param_prefixes_test_intp_intr ( int *, int & )" | |
86 | } | |
87 | } | |
88 | ||
89 | # Test completion of an overloaded function. | |
90 | ||
91 | proc_with_prefix overload {} { | |
92 | set completion_list { | |
93 | "overload_ambiguous_test(int, int)" | |
94 | "overload_ambiguous_test(int, long)" | |
95 | "overload_ambiguous_test(long)" | |
96 | } | |
97 | ||
98 | foreach cmd_prefix {"b" "b -function"} { | |
99 | test_gdb_complete_multiple \ | |
100 | "$cmd_prefix " "overload_ambiguous_" "test(" \ | |
101 | $completion_list | |
102 | check_bp_locations_match_list \ | |
103 | "$cmd_prefix overload_ambiguous_test" \ | |
104 | $completion_list | |
105 | ||
106 | # Test disambiguating by typing enough to pick the "int" as | |
107 | # first parameter type. This then tests handling ambiguity in | |
108 | # the second parameter, which checks that tab completion when | |
109 | # the point is at the whitespace behaves naturally, by showing | |
110 | # the remaining matching overloads to the user. | |
111 | test_gdb_complete_multiple \ | |
112 | "$cmd_prefix " "overload_ambiguous_test(i" "nt, " { | |
113 | "overload_ambiguous_test(int, int)" | |
114 | "overload_ambiguous_test(int, long)" | |
115 | } | |
116 | ||
117 | # Add a few more characters to make the completion | |
118 | # unambiguous. | |
119 | test_gdb_complete_unique \ | |
120 | "$cmd_prefix overload_ambiguous_test(int, i" \ | |
121 | "$cmd_prefix overload_ambiguous_test(int, int)" | |
122 | check_bp_locations_match_list \ | |
123 | "$cmd_prefix overload_ambiguous_test(int, int)" { | |
124 | "overload_ambiguous_test(int, int)" | |
125 | } | |
126 | } | |
127 | } | |
128 | ||
a20714ff PA |
129 | # Test completion of a function that is defined in different scopes |
130 | # with different parameters. | |
131 | ||
132 | proc_with_prefix overload-2 {} { | |
133 | with_test_prefix "all" { | |
134 | set completion_list { | |
135 | "(anonymous namespace)::overload2_function(overload2_arg3)" | |
136 | "(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg4)" | |
137 | "ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)" | |
138 | "ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)" | |
139 | "ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)" | |
140 | "ns_overload2_test::(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg8)" | |
141 | "ns_overload2_test::overload2_function(overload2_arg5)" | |
142 | "ns_overload2_test::struct_overload2_test::overload2_function(overload2_arg6)" | |
143 | "overload2_function(overload2_arg1)" | |
144 | "struct_overload2_test::overload2_function(overload2_arg2)" | |
145 | } | |
146 | foreach cmd_prefix {"b" "b -function"} { | |
147 | test_gdb_complete_multiple \ | |
148 | "$cmd_prefix " "overload2_func" "tion(overload2_arg" $completion_list | |
149 | check_bp_locations_match_list \ | |
150 | "$cmd_prefix overload2_function" $completion_list | |
151 | } | |
152 | } | |
153 | ||
154 | # Same, but restrict to functions/methods in some scope. | |
155 | with_test_prefix "restrict scope" { | |
156 | set completion_list { | |
157 | "ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)" | |
158 | "ns_overload2_test::overload2_function(overload2_arg5)" | |
159 | } | |
160 | foreach cmd_prefix {"b" "b -function"} { | |
161 | test_gdb_complete_multiple \ | |
162 | "$cmd_prefix " "ns_overload2_test::overload2_func" "tion(overload2_arg" $completion_list | |
163 | check_bp_locations_match_list \ | |
164 | "$cmd_prefix ns_overload2_test::overload2_function" $completion_list | |
165 | } | |
166 | } | |
167 | ||
168 | # Restrict to anonymous namespace scopes. | |
169 | with_test_prefix "restrict scope 2" { | |
170 | set completion_list { | |
171 | "(anonymous namespace)::overload2_function(overload2_arg3)" | |
172 | "ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)" | |
173 | } | |
174 | foreach cmd_prefix {"b" "b -function"} { | |
175 | test_gdb_complete_multiple \ | |
176 | "$cmd_prefix " "(anonymous namespace)::overload2_func" "tion(overload2_arg" $completion_list | |
177 | check_bp_locations_match_list \ | |
178 | "$cmd_prefix (anonymous namespace)::overload2_function" $completion_list | |
179 | } | |
180 | } | |
181 | ||
182 | # Add enough scopes, and we get a unique completion. | |
183 | with_test_prefix "unique completion" { | |
184 | foreach cmd_prefix {"b" "b -function"} { | |
185 | test_gdb_complete_unique \ | |
186 | "$cmd_prefix ns_overload2_test::(anonymous namespace)::overload2_func" \ | |
187 | "$cmd_prefix ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)" | |
188 | check_setting_bp_fails "$cmd_prefix ns_overload2_test::(anonymous namespace)::overload2_func" | |
189 | check_bp_locations_match_list \ | |
190 | "$cmd_prefix ns_overload2_test::(anonymous namespace)::overload2_function" \ | |
191 | {"ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"} | |
192 | } | |
193 | } | |
194 | } | |
195 | ||
196 | # Test linespecs / locations using fully-qualified names. | |
197 | ||
198 | proc_with_prefix fqn {} { | |
199 | ||
200 | # "-qualified" works with both explicit locations and linespecs. | |
201 | # Also test that combining a source file with a function name | |
202 | # still results in a full match, with both linespecs and explicit | |
203 | # locations. | |
204 | foreach cmd_prefix { | |
205 | "b -qualified " | |
206 | "b -qualified -function " | |
207 | "b -qualified cpls.cc:" | |
208 | "b -qualified -source cpls.cc -function " | |
209 | "b -source cpls.cc -qualified -function " | |
210 | } { | |
211 | test_gdb_complete_unique \ | |
212 | "${cmd_prefix}overload2_func" \ | |
213 | "${cmd_prefix}overload2_function(overload2_arg1)" | |
214 | ||
215 | # Drill down until we find a unique completion. | |
216 | test_gdb_complete_multiple "${cmd_prefix}" "ns_overload2_test::" "" { | |
217 | "ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)" | |
218 | "ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)" | |
219 | "ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)" | |
220 | "ns_overload2_test::(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg8)" | |
221 | "ns_overload2_test::overload2_function(overload2_arg5)" | |
222 | "ns_overload2_test::struct_overload2_test::overload2_function(overload2_arg6)" | |
223 | } | |
224 | ||
225 | test_gdb_complete_multiple "${cmd_prefix}" "ns_overload2_test::(anonymous namespace)::" "" { | |
226 | "ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)" | |
227 | "ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)" | |
228 | "ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)" | |
229 | "ns_overload2_test::(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg8)" | |
230 | } | |
231 | ||
232 | test_gdb_complete_multiple "${cmd_prefix}" "ns_overload2_test::(anonymous namespace)::ns_overload2_test::" "" { | |
233 | "ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)" | |
234 | "ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)" | |
235 | } | |
236 | ||
237 | test_gdb_complete_unique \ | |
238 | "${cmd_prefix}ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_func" \ | |
239 | "${cmd_prefix}ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)" | |
240 | ||
241 | } | |
242 | } | |
243 | ||
244 | # Check that a fully-qualified lookup name doesn't match symbols in | |
245 | # nested scopes. | |
246 | ||
247 | proc_with_prefix fqn-2 {} { | |
248 | set linespec "struct_overload2_test::overload2_function(overload2_arg6)" | |
249 | set cmd_prefix "b -qualified" | |
250 | check_setting_bp_fails "$cmd_prefix $linespec" | |
251 | test_gdb_complete_none "$cmd_prefix $linespec" | |
252 | ||
253 | # Check that using the same name, but not fully-qualifying it, | |
254 | # would find something, just to make sure the test above is | |
255 | # testing what we intend to test. | |
256 | set cmd_prefix "b -function" | |
257 | test_gdb_complete_unique "$cmd_prefix $linespec" "$cmd_prefix $linespec" | |
258 | check_bp_locations_match_list \ | |
259 | "$cmd_prefix $linespec" \ | |
260 | {"ns_overload2_test::struct_overload2_test::overload2_function(overload2_arg6)"} | |
261 | } | |
262 | ||
263 | # Test completion of functions in different scopes that have the same | |
264 | # name and parameters. Restricting the scopes should find fewer and | |
265 | # fewer matches. | |
266 | ||
267 | proc_with_prefix overload-3 {} { | |
268 | with_test_prefix "all overloads" { | |
269 | set completion_list { | |
270 | "(anonymous namespace)::overload3_function(int)" | |
271 | "(anonymous namespace)::overload3_function(long)" | |
272 | "(anonymous namespace)::struct_overload3_test::overload3_function(int)" | |
273 | "(anonymous namespace)::struct_overload3_test::overload3_function(long)" | |
274 | "ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(int)" | |
275 | "ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(long)" | |
276 | "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(int)" | |
277 | "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(long)" | |
278 | "ns_overload3_test::(anonymous namespace)::overload3_function(int)" | |
279 | "ns_overload3_test::(anonymous namespace)::overload3_function(long)" | |
280 | "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(int)" | |
281 | "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(long)" | |
282 | "ns_overload3_test::overload3_function(int)" | |
283 | "ns_overload3_test::overload3_function(long)" | |
284 | "ns_overload3_test::struct_overload3_test::overload3_function(int)" | |
285 | "ns_overload3_test::struct_overload3_test::overload3_function(long)" | |
286 | "overload3_function(int)" | |
287 | "overload3_function(long)" | |
288 | "struct_overload3_test::overload3_function(int)" | |
289 | "struct_overload3_test::overload3_function(long)" | |
290 | } | |
291 | foreach cmd_prefix {"b" "b -function"} { | |
292 | test_gdb_complete_multiple "$cmd_prefix " "overload3_func" "tion(" $completion_list | |
293 | check_bp_locations_match_list "$cmd_prefix overload3_function" $completion_list | |
294 | } | |
295 | } | |
296 | ||
297 | with_test_prefix "restrict overload" { | |
298 | foreach cmd_prefix {"b" "b -function"} { | |
299 | test_gdb_complete_unique \ | |
300 | "$cmd_prefix overload3_function(int)" \ | |
301 | "$cmd_prefix overload3_function(int)" | |
302 | check_bp_locations_match_list "$cmd_prefix overload3_function(int)" { | |
303 | "(anonymous namespace)::overload3_function(int)" | |
304 | "(anonymous namespace)::struct_overload3_test::overload3_function(int)" | |
305 | "ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(int)" | |
306 | "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(int)" | |
307 | "ns_overload3_test::(anonymous namespace)::overload3_function(int)" | |
308 | "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(int)" | |
309 | "ns_overload3_test::overload3_function(int)" | |
310 | "ns_overload3_test::struct_overload3_test::overload3_function(int)" | |
311 | "overload3_function(int)" | |
312 | "struct_overload3_test::overload3_function(int)" | |
313 | } | |
314 | } | |
315 | } | |
316 | ||
317 | with_test_prefix "restrict scope" { | |
318 | set completion_list { | |
319 | "(anonymous namespace)::struct_overload3_test::overload3_function(int)" | |
320 | "(anonymous namespace)::struct_overload3_test::overload3_function(long)" | |
321 | "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(int)" | |
322 | "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(long)" | |
323 | "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(int)" | |
324 | "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(long)" | |
325 | "ns_overload3_test::struct_overload3_test::overload3_function(int)" | |
326 | "ns_overload3_test::struct_overload3_test::overload3_function(long)" | |
327 | "struct_overload3_test::overload3_function(int)" | |
328 | "struct_overload3_test::overload3_function(long)" | |
329 | } | |
330 | foreach cmd_prefix {"b" "b -function"} { | |
331 | test_gdb_complete_multiple \ | |
332 | "$cmd_prefix " "struct_overload3_test::overload3_func" "tion(" \ | |
333 | $completion_list | |
334 | check_bp_locations_match_list \ | |
335 | "$cmd_prefix struct_overload3_test::overload3_function" \ | |
336 | $completion_list | |
337 | } | |
338 | } | |
339 | } | |
340 | ||
341 | # Test completing an overloaded template method. | |
342 | ||
343 | proc_with_prefix template-overload {} { | |
344 | set completion_list { | |
345 | "template_struct<int>::template_overload_fn(int)" | |
346 | "template_struct<long>::template_overload_fn(long)" | |
347 | } | |
348 | foreach cmd_prefix {"b" "b -function"} { | |
349 | test_gdb_complete_multiple "$cmd_prefix " "template_overload_fn" "(" $completion_list | |
350 | check_bp_locations_match_list "$cmd_prefix template_overload_fn" $completion_list | |
351 | check_bp_locations_match_list \ | |
352 | "$cmd_prefix template_struct<int>::template_overload_fn" \ | |
353 | "template_struct<int>::template_overload_fn(int)" | |
354 | } | |
355 | } | |
356 | ||
357 | # Test completing template methods with non-void return type. | |
358 | ||
359 | proc_with_prefix template-ret-type {} { | |
360 | set method_name "template2_fn<int, int>" | |
361 | set param_list "(template2_ret_type<int>, int, int)" | |
362 | set struct_type "template2_struct<template2_ret_type<int> >" | |
363 | set ret_type "template2_ret_type<int>" | |
364 | ||
365 | # Templates are listed both with and without return type, making | |
366 | # "template2_<tab>" ambiguous. | |
367 | foreach cmd_prefix {"b" "b -function"} { | |
368 | set completion_list \ | |
369 | [list \ | |
370 | "${ret_type} ${struct_type}::${method_name}${param_list}" \ | |
371 | "${struct_type}::${method_name}${param_list}"] | |
372 | test_gdb_complete_multiple "$cmd_prefix " "template2_" "" $completion_list | |
373 | ||
374 | # Add one character more after "2_", and the linespec becomes | |
375 | # unambiguous. Test completing the whole prefix range after that, | |
376 | # thus testing completing either with or without return type. | |
377 | foreach {s t} [list \ | |
378 | "template2_r" \ | |
379 | "${ret_type} ${struct_type}::${method_name}${param_list}" \ | |
380 | "template2_s" \ | |
381 | "${struct_type}::${method_name}${param_list}"] { | |
382 | set linespec $t | |
383 | set complete_line "$cmd_prefix $linespec" | |
384 | set start [index_after $s $complete_line] | |
385 | test_complete_prefix_range $complete_line $start | |
386 | } | |
387 | ||
388 | # Setting a breakpoint without the template params doesn't work. | |
389 | check_setting_bp_fails "$cmd_prefix template2_fn" | |
390 | # However, setting a breakpoint with template params and without | |
391 | # the method params does work, just like with non-template | |
392 | # functions. It also works with or without return type. | |
393 | foreach linespec [list \ | |
394 | "${method_name}" \ | |
395 | "${method_name}${param_list}" \ | |
396 | "${struct_type}::${method_name}" \ | |
397 | "${struct_type}::${method_name}${param_list}" \ | |
398 | "${ret_type} ${struct_type}::${method_name}" \ | |
399 | "${ret_type} ${struct_type}::${method_name}${param_list}"] { | |
400 | check_bp_locations_match_list \ | |
401 | "$cmd_prefix $linespec" \ | |
402 | [list "${struct_type}::${method_name}${param_list}"] | |
403 | } | |
404 | } | |
405 | } | |
406 | ||
407 | # Test completion of a const-overloaded funtion (const-overload). | |
408 | # Note that "const" appears after the function/method parameters. | |
409 | ||
410 | proc_with_prefix const-overload {} { | |
411 | set completion_list { | |
412 | "struct_with_const_overload::const_overload_fn()" | |
413 | "struct_with_const_overload::const_overload_fn() const" | |
414 | } | |
415 | foreach cmd_prefix {"b" "b -function"} { | |
416 | test_gdb_complete_multiple \ | |
417 | "$cmd_prefix " "const_overload_fn" "()" \ | |
418 | $completion_list | |
419 | test_gdb_complete_multiple \ | |
420 | "$cmd_prefix " "const_overload_fn ( " ")" \ | |
421 | $completion_list | |
422 | test_gdb_complete_multiple \ | |
423 | "$cmd_prefix " "const_overload_fn()" "" \ | |
424 | $completion_list | |
425 | ||
426 | check_bp_locations_match_list \ | |
427 | "$cmd_prefix const_overload_fn" \ | |
428 | {"struct_with_const_overload::const_overload_fn()" | |
429 | "struct_with_const_overload::const_overload_fn() const"} | |
430 | ||
431 | check_setting_bp_fails "$cmd_prefix const_overload_fn(" | |
432 | check_bp_locations_match_list \ | |
433 | "$cmd_prefix const_overload_fn()" \ | |
434 | {"struct_with_const_overload::const_overload_fn()"} | |
435 | check_bp_locations_match_list \ | |
436 | "$cmd_prefix const_overload_fn() const" \ | |
437 | {"struct_with_const_overload::const_overload_fn() const"} | |
438 | } | |
439 | } | |
440 | ||
441 | # Same but quote-enclose the function name. This makes the overload | |
442 | # no longer be ambiguous. | |
443 | ||
444 | proc_with_prefix const-overload-quoted {} { | |
445 | foreach cmd_prefix {"b" "b -function"} { | |
446 | set linespec "'const_overload_fn()'" | |
447 | test_gdb_complete_unique "$cmd_prefix $linespec" "$cmd_prefix $linespec" | |
448 | check_bp_locations_match_list \ | |
449 | "$cmd_prefix $linespec" { | |
450 | "struct_with_const_overload::const_overload_fn()" | |
451 | } | |
452 | ||
453 | set linespec "'const_overload_fn() const'" | |
454 | test_gdb_complete_unique "$cmd_prefix $linespec" "$cmd_prefix $linespec" | |
455 | check_bp_locations_match_list \ | |
456 | "$cmd_prefix $linespec" { | |
457 | "struct_with_const_overload::const_overload_fn() const" | |
458 | } | |
459 | } | |
460 | } | |
461 | ||
8955eb2d PA |
462 | # Test that when the function is unambiguous, linespec completion |
463 | # appends the end quote char automatically, both ' and ". | |
464 | ||
465 | proc_with_prefix append-end-quote-char-when-unambiguous {} { | |
466 | foreach cmd_prefix {"b" "b -function"} { | |
467 | foreach qc $completion::all_quotes_list { | |
468 | set linespec "${qc}not_overloaded_fn()${qc}" | |
469 | foreach cmd [list "$cmd_prefix ${qc}not_overloaded_fn()" \ | |
470 | "$cmd_prefix ${qc}not_overloaded_fn" \ | |
471 | "$cmd_prefix ${qc}not_overloaded_"] { | |
472 | test_gdb_complete_unique $cmd "$cmd_prefix $linespec" | |
473 | } | |
474 | check_bp_locations_match_list \ | |
475 | "$cmd_prefix $linespec" {"not_overloaded_fn()"} | |
476 | } | |
477 | } | |
478 | } | |
479 | ||
480 | # Test completing symbols of source files. | |
481 | ||
482 | proc_with_prefix in-source-file-unconstrained {} { | |
483 | # First test that unconstrained matching picks up functions from | |
484 | # multiple files. | |
485 | test_gdb_complete_multiple "b " "file_constrained_test" "_cpls" { | |
486 | "file_constrained_test_cpls2_function(int)" | |
487 | "file_constrained_test_cpls_function(int)" | |
488 | } | |
489 | check_setting_bp_fails "b file_constrained_test_cpls" | |
490 | } | |
491 | ||
492 | # Test an unambiguous completion that would be ambiguous if it weren't | |
493 | # for the source file component, due to | |
494 | # "file_constrained_test_cpls_function" in cpls.cc. Test with | |
495 | # different components quoted, and with whitespace before the function | |
496 | # name. | |
497 | ||
498 | proc_with_prefix in-source-file-unambiguous {} { | |
499 | foreach sqc $completion::maybe_quoted_list { | |
500 | foreach fqc $completion::maybe_quoted_list { | |
501 | # Linespec. | |
502 | foreach sep {":" ": "} { | |
503 | set linespec \ | |
504 | "${sqc}cpls2.cc${sqc}${sep}${fqc}file_constrained_test_cpls2_function(int)${fqc}" | |
505 | set complete_line "b $linespec" | |
506 | set start [index_after "constrained_test" $complete_line] | |
507 | set input_line [string range $complete_line 0 $start] | |
508 | test_gdb_complete_unique $input_line ${complete_line} | |
509 | check_bp_locations_match_list "b $linespec" { | |
510 | "file_constrained_test_cpls2_function(int)" | |
511 | } | |
512 | } | |
513 | ||
514 | # Explicit location. | |
515 | set source_opt "-source ${sqc}cpls2.cc${sqc}" | |
516 | set function_opt "-function ${fqc}file_constrained_test_cpls2_function(int)${fqc}" | |
517 | set complete_line "b $source_opt $function_opt" | |
518 | set start [index_after "cpls2_functio" $complete_line] | |
519 | set input_line [string range $complete_line 0 $start] | |
520 | test_gdb_complete_unique $input_line ${complete_line} | |
521 | check_bp_locations_match_list "$complete_line" { | |
522 | "file_constrained_test_cpls2_function(int)" | |
523 | } | |
524 | } | |
525 | } | |
526 | } | |
527 | ||
528 | # Test an ambiguous completion constrained by a source file. Test | |
529 | # with different components quoted, and with whitespace before the | |
530 | # function name. | |
531 | ||
532 | proc_with_prefix in-source-file-ambiguous {} { | |
533 | foreach sqc $completion::maybe_quoted_list { | |
534 | foreach fqc $completion::maybe_quoted_list { | |
535 | # Linespec. | |
536 | foreach sep {":" ": "} { | |
537 | set cmd_prefix "b ${sqc}cpls2.cc${sqc}${sep}" | |
538 | test_gdb_complete_multiple "${cmd_prefix}" ${fqc} "" { | |
539 | "another_file_constrained_test_cpls2_function(int)" | |
540 | "file_constrained_test_cpls2_function(int)" | |
541 | } ${fqc} ${fqc} | |
542 | } | |
543 | ||
544 | # Explicit location. | |
545 | test_gdb_complete_multiple \ | |
546 | "b -source ${sqc}cpls2.cc${sqc} -function " ${fqc} "" { | |
547 | "another_file_constrained_test_cpls2_function(int)" | |
548 | "file_constrained_test_cpls2_function(int)" | |
549 | } ${fqc} ${fqc} | |
550 | } | |
551 | } | |
552 | } | |
553 | ||
554 | # Check that completing a file name in a linespec auto-appends a colon | |
555 | # instead of a whitespace character. | |
556 | ||
557 | proc_with_prefix source-complete-appends-colon {} { | |
558 | # Test with quotes to make sure the end quote char is put at the | |
559 | # right place. | |
560 | foreach qc $completion::maybe_quoted_list { | |
561 | test_gdb_complete_unique \ | |
562 | "b ${qc}cpls2." \ | |
563 | "b ${qc}cpls2.cc${qc}" ":" | |
564 | test_gdb_complete_unique \ | |
565 | "b ${qc}cpls2.c" \ | |
566 | "b ${qc}cpls2.cc${qc}" ":" | |
567 | test_gdb_complete_unique \ | |
568 | "b ${qc}cpls2.cc" \ | |
569 | "b ${qc}cpls2.cc${qc}" ":" | |
570 | ||
571 | # Same, but with a filename with an hyphen (which is normally | |
572 | # a language word break char). | |
573 | test_gdb_complete_unique \ | |
574 | "b ${qc}cpls-" \ | |
575 | "b ${qc}cpls-hyphen.cc${qc}" ":" | |
576 | test_gdb_complete_unique \ | |
577 | "b ${qc}cpls-hyphen" \ | |
578 | "b ${qc}cpls-hyphen.cc${qc}" ":" | |
579 | } | |
580 | ||
581 | # Test the same, but with the name of a nonexisting file. | |
582 | ||
583 | # Cursor at the end of the string. | |
584 | test_gdb_complete_none "b nonexistingfilename.cc" | |
585 | # Cursor past the end of the string. | |
586 | test_gdb_complete_multiple "b nonexistingfilename.cc " "" "" \ | |
587 | $completion::keyword_list | |
588 | foreach qc $completion::all_quotes_list { | |
589 | # Unterminated quote. | |
590 | test_gdb_complete_none "b ${qc}nonexistingfilename.cc" | |
591 | test_gdb_complete_none "b ${qc}nonexistingfilename.cc " | |
592 | # Terminated quote, cursor at the quote. | |
593 | test_gdb_complete_unique \ | |
594 | "b ${qc}nonexistingfilename.cc${qc}" \ | |
595 | "b ${qc}nonexistingfilename.cc${qc}" | |
596 | # Terminated quote, cursor past the quote. | |
597 | test_gdb_complete_multiple \ | |
598 | "b ${qc}nonexistingfilename.cc${qc} " "" "" \ | |
599 | $completion::keyword_list | |
600 | } | |
601 | } | |
602 | ||
603 | #################################################################### | |
604 | ||
605 | # Test that a colon at the end of the linespec is understood as an | |
606 | # incomplete scope operator (incomplete-scope-colon), instead of a | |
607 | # source/function separator. | |
608 | ||
609 | proc_with_prefix incomplete-scope-colon {} { | |
610 | ||
611 | # Helper for the loop below to simplify it. Tests completion of | |
612 | # the range defined by the RANGE_SS found in the constructed line. | |
613 | # | |
614 | # E.g., with: | |
615 | # | |
616 | # source="source.cc" | |
617 | # fqc="'" | |
618 | # prototype="ns::function()" | |
619 | # range_ss="s::f" | |
620 | # | |
621 | # we'd try completing with the cursor set in each of the | |
622 | # underlined range's positions of: | |
623 | # | |
624 | # b source.cc:'ns::function()'" | |
625 | # ^^^^ | |
626 | # | |
627 | # Also test that setting a breakpoint at the constructed line | |
628 | # finds the same breakpoint location as completion does. | |
629 | # | |
630 | proc incomplete_scope_colon_helper {prototype range_ss {skip_check_bp 0}} { | |
631 | foreach source {"" "cpls.cc"} { | |
632 | # Test with and without source quoting. | |
633 | foreach sqc $completion::maybe_quoted_list { | |
634 | if {$source == "" && $sqc != ""} { | |
635 | # Invalid combination. | |
636 | continue | |
637 | } | |
638 | ||
639 | # Test with and without function quoting. | |
640 | foreach fqc $completion::maybe_quoted_list { | |
641 | if {$source == ""} { | |
642 | set linespec_source "" | |
643 | set explicit_source "" | |
644 | } else { | |
645 | set linespec_source "${sqc}${source}${sqc}:" | |
646 | set explicit_source "-source ${sqc}${source}${sqc}" | |
647 | } | |
648 | ||
649 | # Even though this use case is trickier with | |
650 | # linespecs due to the ":" as separator, test both | |
651 | # linespecs and explicit locations for | |
652 | # completeness. | |
653 | foreach location [list \ | |
654 | "${linespec_source}${fqc}$prototype${fqc}" \ | |
655 | "${explicit_source} -function ${fqc}$prototype${fqc}"] { | |
656 | set complete_line "b $location" | |
657 | set start [string first $range_ss $complete_line] | |
658 | set end [expr ($start + [string length $range_ss])] | |
659 | test_complete_prefix_range $complete_line $start $end | |
660 | if {!$skip_check_bp} { | |
661 | check_bp_locations_match_list "b $location" [list "$prototype"] | |
662 | } | |
663 | } | |
664 | } | |
665 | } | |
666 | } | |
667 | } | |
668 | ||
669 | incomplete_scope_colon_helper \ | |
670 | "struct_incomplete_scope_colon_test::incomplete_scope_colon_test()" \ | |
671 | "t::i" | |
672 | ||
673 | incomplete_scope_colon_helper \ | |
674 | "ns_incomplete_scope_colon_test::incomplete_scope_colon_test()" \ | |
675 | "t::i" | |
676 | ||
677 | # Test completing around both "::"s. | |
678 | foreach range_ss {"t::s" "t::i"} skip_check_bp {0 1} { | |
679 | incomplete_scope_colon_helper \ | |
680 | "ns2_incomplete_scope_colon_test::struct_in_ns2_incomplete_scope_colon_test::incomplete_scope_colon_test()" \ | |
681 | $range_ss $skip_check_bp | |
682 | } | |
683 | } | |
684 | ||
a20714ff PA |
685 | # Test completing functions/methods in anonymous namespaces. |
686 | ||
687 | proc_with_prefix anon-ns {} { | |
688 | foreach cmd_prefix {"b" "b -function"} { | |
689 | foreach qc $completion::maybe_quoted_list { | |
690 | test_gdb_complete_unique \ | |
691 | "$cmd_prefix ${qc}anon_ns_function" \ | |
692 | "$cmd_prefix ${qc}anon_ns_function()${qc}" | |
693 | check_bp_locations_match_list "$cmd_prefix ${qc}anon_ns_function()${qc}" { | |
694 | "(anonymous namespace)::anon_ns_function()" | |
695 | "(anonymous namespace)::anon_ns_struct::anon_ns_function()" | |
696 | "the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_function()" | |
697 | "the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_struct::anon_ns_function()" | |
698 | } | |
699 | } | |
700 | ||
701 | # A "(" finds all anonymous namespace functions/methods in all | |
702 | # scopes. | |
703 | test_gdb_complete_multiple "$cmd_prefix " "(" "anonymous namespace)::" { | |
704 | "(anonymous namespace)::anon_ns_function()" | |
705 | "(anonymous namespace)::anon_ns_struct::anon_ns_function()" | |
706 | "(anonymous namespace)::overload2_function(overload2_arg3)" | |
707 | "(anonymous namespace)::overload3_function(int)" | |
708 | "(anonymous namespace)::overload3_function(long)" | |
709 | "(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg4)" | |
710 | "(anonymous namespace)::struct_overload3_test::overload3_function(int)" | |
711 | "(anonymous namespace)::struct_overload3_test::overload3_function(long)" | |
712 | "ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)" | |
713 | "ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)" | |
714 | "ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)" | |
715 | "ns_overload2_test::(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg8)" | |
716 | "ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(int)" | |
717 | "ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(long)" | |
718 | "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(int)" | |
719 | "ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(long)" | |
720 | "ns_overload3_test::(anonymous namespace)::overload3_function(int)" | |
721 | "ns_overload3_test::(anonymous namespace)::overload3_function(long)" | |
722 | "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(int)" | |
723 | "ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(long)" | |
724 | "the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_function()" | |
725 | "the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_struct::anon_ns_function()" | |
726 | } | |
727 | ||
728 | set function "the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_function()" | |
729 | test_gdb_complete_unique "$cmd_prefix $function" "$cmd_prefix $function" | |
730 | check_bp_locations_match_list "$cmd_prefix $function" [list $function] | |
731 | ||
732 | # Test completing after the "(anonymous namespace)" part. | |
733 | test_gdb_complete_unique \ | |
734 | "$cmd_prefix the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_fu" \ | |
735 | "$cmd_prefix $function" | |
736 | ||
737 | # Test whitespace in the "(anonymous namespace)" component. | |
738 | ||
739 | test_gdb_complete_unique \ | |
740 | "$cmd_prefix the_anon_ns_wrapper_ns::( anonymous namespace )::anon_ns_fu" \ | |
741 | "$cmd_prefix the_anon_ns_wrapper_ns::( anonymous namespace )::anon_ns_function()" | |
742 | check_setting_bp_fails \ | |
743 | "$cmd_prefix the_anon_ns_wrapper_ns::( anonymous namespace )::anon_ns_fu" | |
744 | ||
745 | set function_ws \ | |
746 | "the_anon_ns_wrapper_ns::( anonymous namespace )::anon_ns_function ( )" | |
747 | test_gdb_complete_unique "$cmd_prefix $function_ws" "$cmd_prefix $function_ws" | |
748 | check_bp_locations_match_list "$cmd_prefix $function_ws" [list $function] | |
749 | } | |
750 | } | |
751 | ||
8955eb2d PA |
752 | # Basic test for completing "operator<". More extensive C++ operator |
753 | # tests in cpls-op.exp. | |
754 | ||
755 | proc_with_prefix operator< {} { | |
756 | # Complete all prefixes between "oper" and the whole prototype. | |
757 | set function "operator<(foo_enum, foo_enum)" | |
758 | foreach cmd_prefix {"b" "b -function"} { | |
759 | set line "$cmd_prefix $function" | |
760 | set start [index_after "oper" $line] | |
761 | test_complete_prefix_range $line $start | |
762 | } | |
763 | ||
764 | # There's a label in the function; try completing it. (Exhaustive | |
765 | # label completion tests further below.) | |
766 | foreach location [list \ | |
767 | "$function:label1" \ | |
768 | "-function $function -label label1"] { | |
769 | ||
770 | set cmd "b $location" | |
771 | set input_line [string range $cmd 0 [expr [string length $cmd] - 3]] | |
772 | ||
773 | test_gdb_complete_unique $input_line $cmd | |
774 | test_gdb_complete_unique $cmd $cmd | |
775 | check_bp_locations_match_list $cmd [list "$location"] | |
776 | } | |
777 | } | |
778 | ||
a20714ff PA |
779 | # Test completion of scopes with an ambiguous prefix. |
780 | ||
781 | proc_with_prefix ambiguous-prefix {} { | |
782 | foreach cmd_prefix {"b" "b -function"} { | |
783 | test_gdb_complete_multiple "$cmd_prefix " "ambiguous_pre" "fix_" { | |
784 | "ambiguous_prefix_global_func()" | |
785 | "the_ambiguous_prefix_ns::ambiguous_prefix_ns_func()" | |
786 | "the_ambiguous_prefix_struct::ambiguous_prefix_method()" | |
787 | } | |
788 | check_setting_bp_fails "$cmd_prefix ambiguous_prefix_" | |
789 | } | |
790 | } | |
791 | ||
8955eb2d PA |
792 | # Test completion of function labels. |
793 | ||
794 | proc_with_prefix function-labels {} { | |
795 | # Test with and without a source file component. | |
796 | foreach_location_functions \ | |
797 | { "" "cpls.cc" } \ | |
798 | { "function_with_labels(int)" } \ | |
799 | { | |
800 | # Linespec version. Test various spacing around the label | |
801 | # colon separator. | |
802 | foreach label_sep {":" " :" ": " " : "} { | |
803 | set linespec "${location}${label_sep}" | |
804 | test_gdb_complete_multiple "b $linespec" "l" "abel" { | |
805 | "label1" | |
806 | "label2" | |
807 | } | |
808 | check_setting_bp_fails "b ${linespec}label" | |
809 | ||
810 | set tsep [string trim ${source_sep}] | |
811 | check_bp_locations_match_list \ | |
812 | "b ${linespec}label1" [list "${source}${tsep}${function}:label1"] | |
813 | check_bp_locations_match_list \ | |
814 | "b ${linespec}label2" [list "${source}${tsep}${function}:label2"] | |
815 | } | |
816 | } \ | |
817 | { | |
818 | # Explicit locations version. | |
819 | append location " -label" | |
820 | test_gdb_complete_multiple "b $location " "l" "abel" { | |
821 | "label1" | |
822 | "label2" | |
823 | } | |
824 | check_setting_bp_fails "b $location label" | |
825 | ||
826 | if {$source != ""} { | |
827 | set bp_loc_src "-source ${source} " | |
828 | } else { | |
829 | set bp_loc_src "" | |
830 | } | |
831 | check_bp_locations_match_list \ | |
832 | "b ${location} label1" [list "${bp_loc_src}-function $function -label label1"] | |
833 | check_bp_locations_match_list \ | |
834 | "b ${location} label2" [list "${bp_loc_src}-function $function -label label2"] | |
835 | } | |
836 | } | |
837 | ||
838 | # Test that completion after a function name offers keyword | |
733d554a TBA |
839 | # (if/task/thread/-force-condition) matches in linespec mode, and also |
840 | # the explicit location options in explicit locations mode. | |
8955eb2d PA |
841 | |
842 | proc_with_prefix keywords-after-function {} { | |
843 | set explicit_list \ | |
733d554a TBA |
844 | [lsort [concat \ |
845 | $completion::explicit_opts_list \ | |
846 | $completion::keyword_list]] | |
8955eb2d PA |
847 | |
848 | # Test without a source file, with a known source file, and with | |
849 | # and unknown source file. | |
850 | # Test a known and an unknown function. | |
851 | foreach_location_functions \ | |
852 | { "" "cpls.cc" "unknown_file.cc" } \ | |
853 | { "function_with_labels(int)" "unknown_function(int)" } \ | |
854 | { | |
855 | # Linespec version. | |
856 | test_gdb_complete_multiple "b ${location} " "" "" \ | |
857 | $completion::keyword_list | |
858 | } \ | |
859 | { | |
860 | # Explicit locations version. | |
861 | test_gdb_complete_multiple "b ${location} " "" "" \ | |
862 | $explicit_list | |
863 | } | |
864 | } | |
865 | ||
866 | # Same, but after a label. | |
867 | ||
868 | proc_with_prefix keywords-after-label {} { | |
869 | set explicit_list \ | |
733d554a TBA |
870 | [lsort [concat \ |
871 | $completion::explicit_opts_list \ | |
872 | $completion::keyword_list]] | |
8955eb2d PA |
873 | |
874 | foreach_location_labels \ | |
875 | { "" "cpls.cc" } \ | |
876 | { "function_with_labels(int)" "unknown_function(int)" } \ | |
877 | { "label1" "non_existing_label" } \ | |
878 | { | |
879 | # Linespec version. | |
880 | test_gdb_complete_multiple "b ${location} " "" "" \ | |
881 | $completion::keyword_list | |
882 | } \ | |
883 | { | |
884 | # Explicit locations version. | |
885 | test_gdb_complete_multiple "b ${location} " "" "" \ | |
886 | $explicit_list | |
887 | } | |
888 | } | |
889 | ||
890 | # Similar, but after an unknown file, and in linespec mode only. | |
891 | ||
892 | proc_with_prefix keywords-after-unknown-file {} { | |
893 | # Test with and without quoting. | |
894 | foreach qc $completion::maybe_quoted_list { | |
895 | set line "b ${qc}unknown_file.cc${qc}: " | |
896 | test_gdb_complete_multiple $line "" "" $completion::keyword_list | |
897 | } | |
898 | } | |
899 | ||
900 | # Test that linespec / function completion does not match data | |
901 | # symbols, only functions/methods. | |
902 | ||
903 | proc_with_prefix no-data-symbols {} { | |
904 | foreach cmd_prefix {"b" "b -function"} { | |
905 | test_gdb_complete_unique "$cmd_prefix code_" "$cmd_prefix code_function()" | |
906 | } | |
907 | } | |
908 | ||
909 | ||
910 | # After "if", we expect an expression, which has a different completer | |
911 | # that matches data symbols as well. Check that that works. | |
912 | ||
913 | proc_with_prefix if-expression {} { | |
914 | foreach cmd_prefix {"b" "b -function"} { | |
915 | test_gdb_complete_multiple "$cmd_prefix function() if " "code_" "" { | |
916 | "code_data" | |
917 | "code_function()" | |
918 | } | |
919 | ||
920 | test_gdb_complete_unique \ | |
921 | "$cmd_prefix function() if code_data + another_da" \ | |
922 | "$cmd_prefix function() if code_data + another_data" | |
923 | ||
924 | test_gdb_complete_unique \ | |
925 | "$cmd_prefix non_existing_function() if code_data + another_da" \ | |
926 | "$cmd_prefix non_existing_function() if code_data + another_data" | |
927 | ||
928 | # FIXME: For now, thread and task also use the expression | |
929 | # completer. | |
930 | test_gdb_complete_unique \ | |
931 | "$cmd_prefix function() thread code_data + another_da" \ | |
932 | "$cmd_prefix function() thread code_data + another_data" | |
933 | test_gdb_complete_unique \ | |
934 | "$cmd_prefix function() task code_data + another_da" \ | |
935 | "$cmd_prefix function() task code_data + another_data" | |
936 | } | |
937 | } | |
938 | ||
939 | # The testcase driver. Calls all test procedures. | |
940 | ||
941 | proc test_driver {} { | |
942 | all-param-prefixes | |
943 | overload | |
a20714ff PA |
944 | overload-2 |
945 | fqn | |
946 | fqn-2 | |
947 | overload-3 | |
948 | template-overload | |
949 | template-ret-type | |
950 | const-overload | |
951 | const-overload-quoted | |
8955eb2d PA |
952 | append-end-quote-char-when-unambiguous |
953 | in-source-file-unconstrained | |
954 | in-source-file-unambiguous | |
955 | in-source-file-ambiguous | |
956 | source-complete-appends-colon | |
957 | incomplete-scope-colon | |
a20714ff | 958 | anon-ns |
8955eb2d | 959 | operator< |
a20714ff | 960 | ambiguous-prefix |
8955eb2d PA |
961 | function-labels |
962 | keywords-after-function | |
963 | keywords-after-label | |
964 | keywords-after-unknown-file | |
965 | no-data-symbols | |
966 | if-expression | |
967 | } | |
968 | ||
969 | test_driver |