966 lines
36 KiB
Plaintext
966 lines
36 KiB
Plaintext
# Copyright 2017-2020 Free Software Foundation, Inc.
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# This file is part of the gdb testsuite.
|
|
|
|
load_lib completion-support.exp
|
|
|
|
standard_testfile cpls.cc cpls2.cc cpls-hyphen.cc
|
|
|
|
if {[prepare_for_testing "failed to prepare" $testfile \
|
|
[list $srcfile $srcfile2 $srcfile3] {debug}]} {
|
|
return -1
|
|
}
|
|
|
|
# Tests below are about tab-completion, which doesn't work if readline
|
|
# library isn't used. Check it first.
|
|
|
|
if { ![readline_is_used] } {
|
|
untested "no tab completion support without readline"
|
|
return -1
|
|
}
|
|
|
|
# Disable the completion limit for the whole testcase.
|
|
gdb_test_no_output "set max-completions unlimited"
|
|
|
|
# Start of tests.
|
|
|
|
# Test completion of all parameter prefixes, crossing "(" and ")",
|
|
# with and without whitespace.
|
|
|
|
proc_with_prefix all-param-prefixes {} {
|
|
|
|
# Test both linespecs and explicit locations.
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
set line "$cmd_prefix param_prefixes_test_long(long)"
|
|
set start [index_after "test_long" $line]
|
|
test_complete_prefix_range $line $start
|
|
|
|
# Same, but with extra spaces. Note that the original spaces in
|
|
# the input line are preserved after completion.
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix param_prefixes_test_long(long " \
|
|
"$cmd_prefix param_prefixes_test_long(long )"
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix param_prefixes_test_long( long " \
|
|
"$cmd_prefix param_prefixes_test_long( long )"
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix param_prefixes_test_long ( long " \
|
|
"$cmd_prefix param_prefixes_test_long ( long )"
|
|
|
|
# Complete all parameter prefixes between "(i" and "(int*, int&)".
|
|
# Note that this exercises completing when the point is at the
|
|
# space in "param_prefixes_test_intp_intr(int*, ".
|
|
set line "$cmd_prefix param_prefixes_test_intp_intr(int*, int&)"
|
|
set start [index_after "intp_intr" $line]
|
|
test_complete_prefix_range $line $start
|
|
|
|
# Similar, but with extra spaces.
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix param_prefixes_test_intp_intr ( int* " \
|
|
"$cmd_prefix param_prefixes_test_intp_intr ( int* , int&)"
|
|
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix param_prefixes_test_intp_intr ( int *" \
|
|
"$cmd_prefix param_prefixes_test_intp_intr ( int *, int&)"
|
|
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix param_prefixes_test_intp_intr ( int *, int " \
|
|
"$cmd_prefix param_prefixes_test_intp_intr ( int *, int &)"
|
|
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix param_prefixes_test_intp_intr ( int *, int & " \
|
|
"$cmd_prefix param_prefixes_test_intp_intr ( int *, int & )"
|
|
}
|
|
}
|
|
|
|
# Test completion of an overloaded function.
|
|
|
|
proc_with_prefix overload {} {
|
|
set completion_list {
|
|
"overload_ambiguous_test(int, int)"
|
|
"overload_ambiguous_test(int, long)"
|
|
"overload_ambiguous_test(long)"
|
|
}
|
|
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_multiple \
|
|
"$cmd_prefix " "overload_ambiguous_" "test(" \
|
|
$completion_list
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix overload_ambiguous_test" \
|
|
$completion_list
|
|
|
|
# Test disambiguating by typing enough to pick the "int" as
|
|
# first parameter type. This then tests handling ambiguity in
|
|
# the second parameter, which checks that tab completion when
|
|
# the point is at the whitespace behaves naturally, by showing
|
|
# the remaining matching overloads to the user.
|
|
test_gdb_complete_multiple \
|
|
"$cmd_prefix " "overload_ambiguous_test(i" "nt, " {
|
|
"overload_ambiguous_test(int, int)"
|
|
"overload_ambiguous_test(int, long)"
|
|
}
|
|
|
|
# Add a few more characters to make the completion
|
|
# unambiguous.
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix overload_ambiguous_test(int, i" \
|
|
"$cmd_prefix overload_ambiguous_test(int, int)"
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix overload_ambiguous_test(int, int)" {
|
|
"overload_ambiguous_test(int, int)"
|
|
}
|
|
}
|
|
}
|
|
|
|
# Test completion of a function that is defined in different scopes
|
|
# with different parameters.
|
|
|
|
proc_with_prefix overload-2 {} {
|
|
with_test_prefix "all" {
|
|
set completion_list {
|
|
"(anonymous namespace)::overload2_function(overload2_arg3)"
|
|
"(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg4)"
|
|
"ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
|
|
"ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)"
|
|
"ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"
|
|
"ns_overload2_test::(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg8)"
|
|
"ns_overload2_test::overload2_function(overload2_arg5)"
|
|
"ns_overload2_test::struct_overload2_test::overload2_function(overload2_arg6)"
|
|
"overload2_function(overload2_arg1)"
|
|
"struct_overload2_test::overload2_function(overload2_arg2)"
|
|
}
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_multiple \
|
|
"$cmd_prefix " "overload2_func" "tion(overload2_arg" $completion_list
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix overload2_function" $completion_list
|
|
}
|
|
}
|
|
|
|
# Same, but restrict to functions/methods in some scope.
|
|
with_test_prefix "restrict scope" {
|
|
set completion_list {
|
|
"ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
|
|
"ns_overload2_test::overload2_function(overload2_arg5)"
|
|
}
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_multiple \
|
|
"$cmd_prefix " "ns_overload2_test::overload2_func" "tion(overload2_arg" $completion_list
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix ns_overload2_test::overload2_function" $completion_list
|
|
}
|
|
}
|
|
|
|
# Restrict to anonymous namespace scopes.
|
|
with_test_prefix "restrict scope 2" {
|
|
set completion_list {
|
|
"(anonymous namespace)::overload2_function(overload2_arg3)"
|
|
"ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"
|
|
}
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_multiple \
|
|
"$cmd_prefix " "(anonymous namespace)::overload2_func" "tion(overload2_arg" $completion_list
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix (anonymous namespace)::overload2_function" $completion_list
|
|
}
|
|
}
|
|
|
|
# Add enough scopes, and we get a unique completion.
|
|
with_test_prefix "unique completion" {
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix ns_overload2_test::(anonymous namespace)::overload2_func" \
|
|
"$cmd_prefix ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"
|
|
check_setting_bp_fails "$cmd_prefix ns_overload2_test::(anonymous namespace)::overload2_func"
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix ns_overload2_test::(anonymous namespace)::overload2_function" \
|
|
{"ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Test linespecs / locations using fully-qualified names.
|
|
|
|
proc_with_prefix fqn {} {
|
|
|
|
# "-qualified" works with both explicit locations and linespecs.
|
|
# Also test that combining a source file with a function name
|
|
# still results in a full match, with both linespecs and explicit
|
|
# locations.
|
|
foreach cmd_prefix {
|
|
"b -qualified "
|
|
"b -qualified -function "
|
|
"b -qualified cpls.cc:"
|
|
"b -qualified -source cpls.cc -function "
|
|
"b -source cpls.cc -qualified -function "
|
|
} {
|
|
test_gdb_complete_unique \
|
|
"${cmd_prefix}overload2_func" \
|
|
"${cmd_prefix}overload2_function(overload2_arg1)"
|
|
|
|
# Drill down until we find a unique completion.
|
|
test_gdb_complete_multiple "${cmd_prefix}" "ns_overload2_test::" "" {
|
|
"ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
|
|
"ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)"
|
|
"ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"
|
|
"ns_overload2_test::(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg8)"
|
|
"ns_overload2_test::overload2_function(overload2_arg5)"
|
|
"ns_overload2_test::struct_overload2_test::overload2_function(overload2_arg6)"
|
|
}
|
|
|
|
test_gdb_complete_multiple "${cmd_prefix}" "ns_overload2_test::(anonymous namespace)::" "" {
|
|
"ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
|
|
"ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)"
|
|
"ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"
|
|
"ns_overload2_test::(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg8)"
|
|
}
|
|
|
|
test_gdb_complete_multiple "${cmd_prefix}" "ns_overload2_test::(anonymous namespace)::ns_overload2_test::" "" {
|
|
"ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
|
|
"ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)"
|
|
}
|
|
|
|
test_gdb_complete_unique \
|
|
"${cmd_prefix}ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_func" \
|
|
"${cmd_prefix}ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
|
|
|
|
}
|
|
}
|
|
|
|
# Check that a fully-qualified lookup name doesn't match symbols in
|
|
# nested scopes.
|
|
|
|
proc_with_prefix fqn-2 {} {
|
|
set linespec "struct_overload2_test::overload2_function(overload2_arg6)"
|
|
set cmd_prefix "b -qualified"
|
|
check_setting_bp_fails "$cmd_prefix $linespec"
|
|
test_gdb_complete_none "$cmd_prefix $linespec"
|
|
|
|
# Check that using the same name, but not fully-qualifying it,
|
|
# would find something, just to make sure the test above is
|
|
# testing what we intend to test.
|
|
set cmd_prefix "b -function"
|
|
test_gdb_complete_unique "$cmd_prefix $linespec" "$cmd_prefix $linespec"
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix $linespec" \
|
|
{"ns_overload2_test::struct_overload2_test::overload2_function(overload2_arg6)"}
|
|
}
|
|
|
|
# Test completion of functions in different scopes that have the same
|
|
# name and parameters. Restricting the scopes should find fewer and
|
|
# fewer matches.
|
|
|
|
proc_with_prefix overload-3 {} {
|
|
with_test_prefix "all overloads" {
|
|
set completion_list {
|
|
"(anonymous namespace)::overload3_function(int)"
|
|
"(anonymous namespace)::overload3_function(long)"
|
|
"(anonymous namespace)::struct_overload3_test::overload3_function(int)"
|
|
"(anonymous namespace)::struct_overload3_test::overload3_function(long)"
|
|
"ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(long)"
|
|
"ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(long)"
|
|
"ns_overload3_test::(anonymous namespace)::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::overload3_function(long)"
|
|
"ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(long)"
|
|
"ns_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::overload3_function(long)"
|
|
"ns_overload3_test::struct_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::struct_overload3_test::overload3_function(long)"
|
|
"overload3_function(int)"
|
|
"overload3_function(long)"
|
|
"struct_overload3_test::overload3_function(int)"
|
|
"struct_overload3_test::overload3_function(long)"
|
|
}
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_multiple "$cmd_prefix " "overload3_func" "tion(" $completion_list
|
|
check_bp_locations_match_list "$cmd_prefix overload3_function" $completion_list
|
|
}
|
|
}
|
|
|
|
with_test_prefix "restrict overload" {
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix overload3_function(int)" \
|
|
"$cmd_prefix overload3_function(int)"
|
|
check_bp_locations_match_list "$cmd_prefix overload3_function(int)" {
|
|
"(anonymous namespace)::overload3_function(int)"
|
|
"(anonymous namespace)::struct_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::struct_overload3_test::overload3_function(int)"
|
|
"overload3_function(int)"
|
|
"struct_overload3_test::overload3_function(int)"
|
|
}
|
|
}
|
|
}
|
|
|
|
with_test_prefix "restrict scope" {
|
|
set completion_list {
|
|
"(anonymous namespace)::struct_overload3_test::overload3_function(int)"
|
|
"(anonymous namespace)::struct_overload3_test::overload3_function(long)"
|
|
"ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(long)"
|
|
"ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(long)"
|
|
"ns_overload3_test::struct_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::struct_overload3_test::overload3_function(long)"
|
|
"struct_overload3_test::overload3_function(int)"
|
|
"struct_overload3_test::overload3_function(long)"
|
|
}
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_multiple \
|
|
"$cmd_prefix " "struct_overload3_test::overload3_func" "tion(" \
|
|
$completion_list
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix struct_overload3_test::overload3_function" \
|
|
$completion_list
|
|
}
|
|
}
|
|
}
|
|
|
|
# Test completing an overloaded template method.
|
|
|
|
proc_with_prefix template-overload {} {
|
|
set completion_list {
|
|
"template_struct<int>::template_overload_fn(int)"
|
|
"template_struct<long>::template_overload_fn(long)"
|
|
}
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_multiple "$cmd_prefix " "template_overload_fn" "(" $completion_list
|
|
check_bp_locations_match_list "$cmd_prefix template_overload_fn" $completion_list
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix template_struct<int>::template_overload_fn" \
|
|
"template_struct<int>::template_overload_fn(int)"
|
|
}
|
|
}
|
|
|
|
# Test completing template methods with non-void return type.
|
|
|
|
proc_with_prefix template-ret-type {} {
|
|
set method_name "template2_fn<int, int>"
|
|
set param_list "(template2_ret_type<int>, int, int)"
|
|
set struct_type "template2_struct<template2_ret_type<int> >"
|
|
set ret_type "template2_ret_type<int>"
|
|
|
|
# Templates are listed both with and without return type, making
|
|
# "template2_<tab>" ambiguous.
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
set completion_list \
|
|
[list \
|
|
"${ret_type} ${struct_type}::${method_name}${param_list}" \
|
|
"${struct_type}::${method_name}${param_list}"]
|
|
test_gdb_complete_multiple "$cmd_prefix " "template2_" "" $completion_list
|
|
|
|
# Add one character more after "2_", and the linespec becomes
|
|
# unambiguous. Test completing the whole prefix range after that,
|
|
# thus testing completing either with or without return type.
|
|
foreach {s t} [list \
|
|
"template2_r" \
|
|
"${ret_type} ${struct_type}::${method_name}${param_list}" \
|
|
"template2_s" \
|
|
"${struct_type}::${method_name}${param_list}"] {
|
|
set linespec $t
|
|
set complete_line "$cmd_prefix $linespec"
|
|
set start [index_after $s $complete_line]
|
|
test_complete_prefix_range $complete_line $start
|
|
}
|
|
|
|
# Setting a breakpoint without the template params doesn't work.
|
|
check_setting_bp_fails "$cmd_prefix template2_fn"
|
|
# However, setting a breakpoint with template params and without
|
|
# the method params does work, just like with non-template
|
|
# functions. It also works with or without return type.
|
|
foreach linespec [list \
|
|
"${method_name}" \
|
|
"${method_name}${param_list}" \
|
|
"${struct_type}::${method_name}" \
|
|
"${struct_type}::${method_name}${param_list}" \
|
|
"${ret_type} ${struct_type}::${method_name}" \
|
|
"${ret_type} ${struct_type}::${method_name}${param_list}"] {
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix $linespec" \
|
|
[list "${struct_type}::${method_name}${param_list}"]
|
|
}
|
|
}
|
|
}
|
|
|
|
# Test completion of a const-overloaded funtion (const-overload).
|
|
# Note that "const" appears after the function/method parameters.
|
|
|
|
proc_with_prefix const-overload {} {
|
|
set completion_list {
|
|
"struct_with_const_overload::const_overload_fn()"
|
|
"struct_with_const_overload::const_overload_fn() const"
|
|
}
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_multiple \
|
|
"$cmd_prefix " "const_overload_fn" "()" \
|
|
$completion_list
|
|
test_gdb_complete_multiple \
|
|
"$cmd_prefix " "const_overload_fn ( " ")" \
|
|
$completion_list
|
|
test_gdb_complete_multiple \
|
|
"$cmd_prefix " "const_overload_fn()" "" \
|
|
$completion_list
|
|
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix const_overload_fn" \
|
|
{"struct_with_const_overload::const_overload_fn()"
|
|
"struct_with_const_overload::const_overload_fn() const"}
|
|
|
|
check_setting_bp_fails "$cmd_prefix const_overload_fn("
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix const_overload_fn()" \
|
|
{"struct_with_const_overload::const_overload_fn()"}
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix const_overload_fn() const" \
|
|
{"struct_with_const_overload::const_overload_fn() const"}
|
|
}
|
|
}
|
|
|
|
# Same but quote-enclose the function name. This makes the overload
|
|
# no longer be ambiguous.
|
|
|
|
proc_with_prefix const-overload-quoted {} {
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
set linespec "'const_overload_fn()'"
|
|
test_gdb_complete_unique "$cmd_prefix $linespec" "$cmd_prefix $linespec"
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix $linespec" {
|
|
"struct_with_const_overload::const_overload_fn()"
|
|
}
|
|
|
|
set linespec "'const_overload_fn() const'"
|
|
test_gdb_complete_unique "$cmd_prefix $linespec" "$cmd_prefix $linespec"
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix $linespec" {
|
|
"struct_with_const_overload::const_overload_fn() const"
|
|
}
|
|
}
|
|
}
|
|
|
|
# Test that when the function is unambiguous, linespec completion
|
|
# appends the end quote char automatically, both ' and ".
|
|
|
|
proc_with_prefix append-end-quote-char-when-unambiguous {} {
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
foreach qc $completion::all_quotes_list {
|
|
set linespec "${qc}not_overloaded_fn()${qc}"
|
|
foreach cmd [list "$cmd_prefix ${qc}not_overloaded_fn()" \
|
|
"$cmd_prefix ${qc}not_overloaded_fn" \
|
|
"$cmd_prefix ${qc}not_overloaded_"] {
|
|
test_gdb_complete_unique $cmd "$cmd_prefix $linespec"
|
|
}
|
|
check_bp_locations_match_list \
|
|
"$cmd_prefix $linespec" {"not_overloaded_fn()"}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Test completing symbols of source files.
|
|
|
|
proc_with_prefix in-source-file-unconstrained {} {
|
|
# First test that unconstrained matching picks up functions from
|
|
# multiple files.
|
|
test_gdb_complete_multiple "b " "file_constrained_test" "_cpls" {
|
|
"file_constrained_test_cpls2_function(int)"
|
|
"file_constrained_test_cpls_function(int)"
|
|
}
|
|
check_setting_bp_fails "b file_constrained_test_cpls"
|
|
}
|
|
|
|
# Test an unambiguous completion that would be ambiguous if it weren't
|
|
# for the source file component, due to
|
|
# "file_constrained_test_cpls_function" in cpls.cc. Test with
|
|
# different components quoted, and with whitespace before the function
|
|
# name.
|
|
|
|
proc_with_prefix in-source-file-unambiguous {} {
|
|
foreach sqc $completion::maybe_quoted_list {
|
|
foreach fqc $completion::maybe_quoted_list {
|
|
# Linespec.
|
|
foreach sep {":" ": "} {
|
|
set linespec \
|
|
"${sqc}cpls2.cc${sqc}${sep}${fqc}file_constrained_test_cpls2_function(int)${fqc}"
|
|
set complete_line "b $linespec"
|
|
set start [index_after "constrained_test" $complete_line]
|
|
set input_line [string range $complete_line 0 $start]
|
|
test_gdb_complete_unique $input_line ${complete_line}
|
|
check_bp_locations_match_list "b $linespec" {
|
|
"file_constrained_test_cpls2_function(int)"
|
|
}
|
|
}
|
|
|
|
# Explicit location.
|
|
set source_opt "-source ${sqc}cpls2.cc${sqc}"
|
|
set function_opt "-function ${fqc}file_constrained_test_cpls2_function(int)${fqc}"
|
|
set complete_line "b $source_opt $function_opt"
|
|
set start [index_after "cpls2_functio" $complete_line]
|
|
set input_line [string range $complete_line 0 $start]
|
|
test_gdb_complete_unique $input_line ${complete_line}
|
|
check_bp_locations_match_list "$complete_line" {
|
|
"file_constrained_test_cpls2_function(int)"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Test an ambiguous completion constrained by a source file. Test
|
|
# with different components quoted, and with whitespace before the
|
|
# function name.
|
|
|
|
proc_with_prefix in-source-file-ambiguous {} {
|
|
foreach sqc $completion::maybe_quoted_list {
|
|
foreach fqc $completion::maybe_quoted_list {
|
|
# Linespec.
|
|
foreach sep {":" ": "} {
|
|
set cmd_prefix "b ${sqc}cpls2.cc${sqc}${sep}"
|
|
test_gdb_complete_multiple "${cmd_prefix}" ${fqc} "" {
|
|
"another_file_constrained_test_cpls2_function(int)"
|
|
"file_constrained_test_cpls2_function(int)"
|
|
} ${fqc} ${fqc}
|
|
}
|
|
|
|
# Explicit location.
|
|
test_gdb_complete_multiple \
|
|
"b -source ${sqc}cpls2.cc${sqc} -function " ${fqc} "" {
|
|
"another_file_constrained_test_cpls2_function(int)"
|
|
"file_constrained_test_cpls2_function(int)"
|
|
} ${fqc} ${fqc}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Check that completing a file name in a linespec auto-appends a colon
|
|
# instead of a whitespace character.
|
|
|
|
proc_with_prefix source-complete-appends-colon {} {
|
|
# Test with quotes to make sure the end quote char is put at the
|
|
# right place.
|
|
foreach qc $completion::maybe_quoted_list {
|
|
test_gdb_complete_unique \
|
|
"b ${qc}cpls2." \
|
|
"b ${qc}cpls2.cc${qc}" ":"
|
|
test_gdb_complete_unique \
|
|
"b ${qc}cpls2.c" \
|
|
"b ${qc}cpls2.cc${qc}" ":"
|
|
test_gdb_complete_unique \
|
|
"b ${qc}cpls2.cc" \
|
|
"b ${qc}cpls2.cc${qc}" ":"
|
|
|
|
# Same, but with a filename with an hyphen (which is normally
|
|
# a language word break char).
|
|
test_gdb_complete_unique \
|
|
"b ${qc}cpls-" \
|
|
"b ${qc}cpls-hyphen.cc${qc}" ":"
|
|
test_gdb_complete_unique \
|
|
"b ${qc}cpls-hyphen" \
|
|
"b ${qc}cpls-hyphen.cc${qc}" ":"
|
|
}
|
|
|
|
# Test the same, but with the name of a nonexisting file.
|
|
|
|
# Cursor at the end of the string.
|
|
test_gdb_complete_none "b nonexistingfilename.cc"
|
|
# Cursor past the end of the string.
|
|
test_gdb_complete_multiple "b nonexistingfilename.cc " "" "" \
|
|
$completion::keyword_list
|
|
foreach qc $completion::all_quotes_list {
|
|
# Unterminated quote.
|
|
test_gdb_complete_none "b ${qc}nonexistingfilename.cc"
|
|
test_gdb_complete_none "b ${qc}nonexistingfilename.cc "
|
|
# Terminated quote, cursor at the quote.
|
|
test_gdb_complete_unique \
|
|
"b ${qc}nonexistingfilename.cc${qc}" \
|
|
"b ${qc}nonexistingfilename.cc${qc}"
|
|
# Terminated quote, cursor past the quote.
|
|
test_gdb_complete_multiple \
|
|
"b ${qc}nonexistingfilename.cc${qc} " "" "" \
|
|
$completion::keyword_list
|
|
}
|
|
}
|
|
|
|
####################################################################
|
|
|
|
# Test that a colon at the end of the linespec is understood as an
|
|
# incomplete scope operator (incomplete-scope-colon), instead of a
|
|
# source/function separator.
|
|
|
|
proc_with_prefix incomplete-scope-colon {} {
|
|
|
|
# Helper for the loop below to simplify it. Tests completion of
|
|
# the range defined by the RANGE_SS found in the constructed line.
|
|
#
|
|
# E.g., with:
|
|
#
|
|
# source="source.cc"
|
|
# fqc="'"
|
|
# prototype="ns::function()"
|
|
# range_ss="s::f"
|
|
#
|
|
# we'd try completing with the cursor set in each of the
|
|
# underlined range's positions of:
|
|
#
|
|
# b source.cc:'ns::function()'"
|
|
# ^^^^
|
|
#
|
|
# Also test that setting a breakpoint at the constructed line
|
|
# finds the same breakpoint location as completion does.
|
|
#
|
|
proc incomplete_scope_colon_helper {prototype range_ss {skip_check_bp 0}} {
|
|
foreach source {"" "cpls.cc"} {
|
|
# Test with and without source quoting.
|
|
foreach sqc $completion::maybe_quoted_list {
|
|
if {$source == "" && $sqc != ""} {
|
|
# Invalid combination.
|
|
continue
|
|
}
|
|
|
|
# Test with and without function quoting.
|
|
foreach fqc $completion::maybe_quoted_list {
|
|
if {$source == ""} {
|
|
set linespec_source ""
|
|
set explicit_source ""
|
|
} else {
|
|
set linespec_source "${sqc}${source}${sqc}:"
|
|
set explicit_source "-source ${sqc}${source}${sqc}"
|
|
}
|
|
|
|
# Even though this use case is trickier with
|
|
# linespecs due to the ":" as separator, test both
|
|
# linespecs and explicit locations for
|
|
# completeness.
|
|
foreach location [list \
|
|
"${linespec_source}${fqc}$prototype${fqc}" \
|
|
"${explicit_source} -function ${fqc}$prototype${fqc}"] {
|
|
set complete_line "b $location"
|
|
set start [string first $range_ss $complete_line]
|
|
set end [expr ($start + [string length $range_ss])]
|
|
test_complete_prefix_range $complete_line $start $end
|
|
if {!$skip_check_bp} {
|
|
check_bp_locations_match_list "b $location" [list "$prototype"]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
incomplete_scope_colon_helper \
|
|
"struct_incomplete_scope_colon_test::incomplete_scope_colon_test()" \
|
|
"t::i"
|
|
|
|
incomplete_scope_colon_helper \
|
|
"ns_incomplete_scope_colon_test::incomplete_scope_colon_test()" \
|
|
"t::i"
|
|
|
|
# Test completing around both "::"s.
|
|
foreach range_ss {"t::s" "t::i"} skip_check_bp {0 1} {
|
|
incomplete_scope_colon_helper \
|
|
"ns2_incomplete_scope_colon_test::struct_in_ns2_incomplete_scope_colon_test::incomplete_scope_colon_test()" \
|
|
$range_ss $skip_check_bp
|
|
}
|
|
}
|
|
|
|
# Test completing functions/methods in anonymous namespaces.
|
|
|
|
proc_with_prefix anon-ns {} {
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
foreach qc $completion::maybe_quoted_list {
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix ${qc}anon_ns_function" \
|
|
"$cmd_prefix ${qc}anon_ns_function()${qc}"
|
|
check_bp_locations_match_list "$cmd_prefix ${qc}anon_ns_function()${qc}" {
|
|
"(anonymous namespace)::anon_ns_function()"
|
|
"(anonymous namespace)::anon_ns_struct::anon_ns_function()"
|
|
"the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_function()"
|
|
"the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_struct::anon_ns_function()"
|
|
}
|
|
}
|
|
|
|
# A "(" finds all anonymous namespace functions/methods in all
|
|
# scopes.
|
|
test_gdb_complete_multiple "$cmd_prefix " "(" "anonymous namespace)::" {
|
|
"(anonymous namespace)::anon_ns_function()"
|
|
"(anonymous namespace)::anon_ns_struct::anon_ns_function()"
|
|
"(anonymous namespace)::overload2_function(overload2_arg3)"
|
|
"(anonymous namespace)::overload3_function(int)"
|
|
"(anonymous namespace)::overload3_function(long)"
|
|
"(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg4)"
|
|
"(anonymous namespace)::struct_overload3_test::overload3_function(int)"
|
|
"(anonymous namespace)::struct_overload3_test::overload3_function(long)"
|
|
"ns_overload2_test::(anonymous namespace)::ns_overload2_test::overload2_function(overload2_arg9)"
|
|
"ns_overload2_test::(anonymous namespace)::ns_overload2_test::struct_overload2_test::overload2_function(overload2_arga)"
|
|
"ns_overload2_test::(anonymous namespace)::overload2_function(overload2_arg7)"
|
|
"ns_overload2_test::(anonymous namespace)::struct_overload2_test::overload2_function(overload2_arg8)"
|
|
"ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::ns_overload3_test::overload3_function(long)"
|
|
"ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::ns_overload3_test::struct_overload3_test::overload3_function(long)"
|
|
"ns_overload3_test::(anonymous namespace)::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::overload3_function(long)"
|
|
"ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(int)"
|
|
"ns_overload3_test::(anonymous namespace)::struct_overload3_test::overload3_function(long)"
|
|
"the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_function()"
|
|
"the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_struct::anon_ns_function()"
|
|
}
|
|
|
|
set function "the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_function()"
|
|
test_gdb_complete_unique "$cmd_prefix $function" "$cmd_prefix $function"
|
|
check_bp_locations_match_list "$cmd_prefix $function" [list $function]
|
|
|
|
# Test completing after the "(anonymous namespace)" part.
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix the_anon_ns_wrapper_ns::(anonymous namespace)::anon_ns_fu" \
|
|
"$cmd_prefix $function"
|
|
|
|
# Test whitespace in the "(anonymous namespace)" component.
|
|
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix the_anon_ns_wrapper_ns::( anonymous namespace )::anon_ns_fu" \
|
|
"$cmd_prefix the_anon_ns_wrapper_ns::( anonymous namespace )::anon_ns_function()"
|
|
check_setting_bp_fails \
|
|
"$cmd_prefix the_anon_ns_wrapper_ns::( anonymous namespace )::anon_ns_fu"
|
|
|
|
set function_ws \
|
|
"the_anon_ns_wrapper_ns::( anonymous namespace )::anon_ns_function ( )"
|
|
test_gdb_complete_unique "$cmd_prefix $function_ws" "$cmd_prefix $function_ws"
|
|
check_bp_locations_match_list "$cmd_prefix $function_ws" [list $function]
|
|
}
|
|
}
|
|
|
|
# Basic test for completing "operator<". More extensive C++ operator
|
|
# tests in cpls-op.exp.
|
|
|
|
proc_with_prefix operator< {} {
|
|
# Complete all prefixes between "oper" and the whole prototype.
|
|
set function "operator<(foo_enum, foo_enum)"
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
set line "$cmd_prefix $function"
|
|
set start [index_after "oper" $line]
|
|
test_complete_prefix_range $line $start
|
|
}
|
|
|
|
# There's a label in the function; try completing it. (Exhaustive
|
|
# label completion tests further below.)
|
|
foreach location [list \
|
|
"$function:label1" \
|
|
"-function $function -label label1"] {
|
|
|
|
set cmd "b $location"
|
|
set input_line [string range $cmd 0 [expr [string length $cmd] - 3]]
|
|
|
|
test_gdb_complete_unique $input_line $cmd
|
|
test_gdb_complete_unique $cmd $cmd
|
|
check_bp_locations_match_list $cmd [list "$location"]
|
|
}
|
|
}
|
|
|
|
# Test completion of scopes with an ambiguous prefix.
|
|
|
|
proc_with_prefix ambiguous-prefix {} {
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_multiple "$cmd_prefix " "ambiguous_pre" "fix_" {
|
|
"ambiguous_prefix_global_func()"
|
|
"the_ambiguous_prefix_ns::ambiguous_prefix_ns_func()"
|
|
"the_ambiguous_prefix_struct::ambiguous_prefix_method()"
|
|
}
|
|
check_setting_bp_fails "$cmd_prefix ambiguous_prefix_"
|
|
}
|
|
}
|
|
|
|
# Test completion of function labels.
|
|
|
|
proc_with_prefix function-labels {} {
|
|
# Test with and without a source file component.
|
|
foreach_location_functions \
|
|
{ "" "cpls.cc" } \
|
|
{ "function_with_labels(int)" } \
|
|
{
|
|
# Linespec version. Test various spacing around the label
|
|
# colon separator.
|
|
foreach label_sep {":" " :" ": " " : "} {
|
|
set linespec "${location}${label_sep}"
|
|
test_gdb_complete_multiple "b $linespec" "l" "abel" {
|
|
"label1"
|
|
"label2"
|
|
}
|
|
check_setting_bp_fails "b ${linespec}label"
|
|
|
|
set tsep [string trim ${source_sep}]
|
|
check_bp_locations_match_list \
|
|
"b ${linespec}label1" [list "${source}${tsep}${function}:label1"]
|
|
check_bp_locations_match_list \
|
|
"b ${linespec}label2" [list "${source}${tsep}${function}:label2"]
|
|
}
|
|
} \
|
|
{
|
|
# Explicit locations version.
|
|
append location " -label"
|
|
test_gdb_complete_multiple "b $location " "l" "abel" {
|
|
"label1"
|
|
"label2"
|
|
}
|
|
check_setting_bp_fails "b $location label"
|
|
|
|
if {$source != ""} {
|
|
set bp_loc_src "-source ${source} "
|
|
} else {
|
|
set bp_loc_src ""
|
|
}
|
|
check_bp_locations_match_list \
|
|
"b ${location} label1" [list "${bp_loc_src}-function $function -label label1"]
|
|
check_bp_locations_match_list \
|
|
"b ${location} label2" [list "${bp_loc_src}-function $function -label label2"]
|
|
}
|
|
}
|
|
|
|
# Test that completion after a function name offers keyword
|
|
# (if/task/thread) matches in linespec mode, and also the explicit
|
|
# location options in explicit locations mode.
|
|
|
|
proc_with_prefix keywords-after-function {} {
|
|
set explicit_list \
|
|
[concat $completion::explicit_opts_list $completion::keyword_list]
|
|
|
|
# Test without a source file, with a known source file, and with
|
|
# and unknown source file.
|
|
# Test a known and an unknown function.
|
|
foreach_location_functions \
|
|
{ "" "cpls.cc" "unknown_file.cc" } \
|
|
{ "function_with_labels(int)" "unknown_function(int)" } \
|
|
{
|
|
# Linespec version.
|
|
test_gdb_complete_multiple "b ${location} " "" "" \
|
|
$completion::keyword_list
|
|
} \
|
|
{
|
|
# Explicit locations version.
|
|
test_gdb_complete_multiple "b ${location} " "" "" \
|
|
$explicit_list
|
|
}
|
|
}
|
|
|
|
# Same, but after a label.
|
|
|
|
proc_with_prefix keywords-after-label {} {
|
|
set explicit_list \
|
|
[concat $completion::explicit_opts_list $completion::keyword_list]
|
|
|
|
foreach_location_labels \
|
|
{ "" "cpls.cc" } \
|
|
{ "function_with_labels(int)" "unknown_function(int)" } \
|
|
{ "label1" "non_existing_label" } \
|
|
{
|
|
# Linespec version.
|
|
test_gdb_complete_multiple "b ${location} " "" "" \
|
|
$completion::keyword_list
|
|
} \
|
|
{
|
|
# Explicit locations version.
|
|
test_gdb_complete_multiple "b ${location} " "" "" \
|
|
$explicit_list
|
|
}
|
|
}
|
|
|
|
# Similar, but after an unknown file, and in linespec mode only.
|
|
|
|
proc_with_prefix keywords-after-unknown-file {} {
|
|
# Test with and without quoting.
|
|
foreach qc $completion::maybe_quoted_list {
|
|
set line "b ${qc}unknown_file.cc${qc}: "
|
|
test_gdb_complete_multiple $line "" "" $completion::keyword_list
|
|
}
|
|
}
|
|
|
|
# Test that linespec / function completion does not match data
|
|
# symbols, only functions/methods.
|
|
|
|
proc_with_prefix no-data-symbols {} {
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_unique "$cmd_prefix code_" "$cmd_prefix code_function()"
|
|
}
|
|
}
|
|
|
|
|
|
# After "if", we expect an expression, which has a different completer
|
|
# that matches data symbols as well. Check that that works.
|
|
|
|
proc_with_prefix if-expression {} {
|
|
foreach cmd_prefix {"b" "b -function"} {
|
|
test_gdb_complete_multiple "$cmd_prefix function() if " "code_" "" {
|
|
"code_data"
|
|
"code_function()"
|
|
}
|
|
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix function() if code_data + another_da" \
|
|
"$cmd_prefix function() if code_data + another_data"
|
|
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix non_existing_function() if code_data + another_da" \
|
|
"$cmd_prefix non_existing_function() if code_data + another_data"
|
|
|
|
# FIXME: For now, thread and task also use the expression
|
|
# completer.
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix function() thread code_data + another_da" \
|
|
"$cmd_prefix function() thread code_data + another_data"
|
|
test_gdb_complete_unique \
|
|
"$cmd_prefix function() task code_data + another_da" \
|
|
"$cmd_prefix function() task code_data + another_data"
|
|
}
|
|
}
|
|
|
|
# The testcase driver. Calls all test procedures.
|
|
|
|
proc test_driver {} {
|
|
all-param-prefixes
|
|
overload
|
|
overload-2
|
|
fqn
|
|
fqn-2
|
|
overload-3
|
|
template-overload
|
|
template-ret-type
|
|
const-overload
|
|
const-overload-quoted
|
|
append-end-quote-char-when-unambiguous
|
|
in-source-file-unconstrained
|
|
in-source-file-unambiguous
|
|
in-source-file-ambiguous
|
|
source-complete-appends-colon
|
|
incomplete-scope-colon
|
|
anon-ns
|
|
operator<
|
|
ambiguous-prefix
|
|
function-labels
|
|
keywords-after-function
|
|
keywords-after-label
|
|
keywords-after-unknown-file
|
|
no-data-symbols
|
|
if-expression
|
|
}
|
|
|
|
test_driver
|