242 lines
8.1 KiB
Plaintext
242 lines
8.1 KiB
Plaintext
# Copyright 2017-2018 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/>.
|
|
|
|
# Tests for function local static variables, both C and C++.
|
|
|
|
# This file is part of the gdb testsuite.
|
|
|
|
standard_testfile .c
|
|
|
|
# A few expected errors.
|
|
set syntax_re "A syntax error in expression, near.*"
|
|
set cannot_resolve_re "Cannot resolve method S::method to any overloaded instance"
|
|
|
|
# Build an "Cannot resolve method ..." expected error string for
|
|
# method METH.
|
|
#
|
|
proc cannot_resolve {meth} {
|
|
return "Cannot resolve method $meth to any overloaded instance"
|
|
}
|
|
|
|
# A list of scopes that have the static variables that we want to
|
|
# print. Each entry has, in order, the scope/function name, and the
|
|
# prefix used by the static variables. The prefix exists both to make
|
|
# it easier to debug the test if something goes wrong, and, to make
|
|
# sure that printing the static local of one method overload doesn't
|
|
# find the variables of the wrong overload.
|
|
#
|
|
# While at it, we also try printing each scope without the static
|
|
# local, to check that the parse copes with cv overloads without
|
|
# quoting. That's what the third and forth columns are for. Note
|
|
# that printing "func()" is different from "func(void)". The former
|
|
# is an inferior function call, while the latter is a reference to the
|
|
# function.
|
|
|
|
#SCOPE #PREFIX #PRINT-SCOPE-QUOTED
|
|
#PRINT-SCOPE-UNQUOTED (opt)
|
|
set cxx_scopes_list {
|
|
{"S::method()" "S_M" {= \\{void \\(S \\* const\\)\\} $hex <S::method\\(\\)>}
|
|
{[cannot_resolve "S::method"]}}
|
|
|
|
{"S::method() const" "S_M_C" {= \\{void \\(const S \\* const\\)\\} $hex <S::method\\(\\) const>}
|
|
$syntax_re}
|
|
|
|
{"S::method() volatile" "S_M_V" {= \\{void \\(volatile S \\* const\\)\\} $hex <S::method\\(\\) volatile>}
|
|
$syntax_re}
|
|
|
|
{"S::method() const volatile" "S_M_CV" {= \\{void \\(const volatile S \\* const\\)\\} $hex <S::method\\(\\) const volatile>}
|
|
$syntax_re}
|
|
|
|
{"S::method() volatile const" "S_M_CV" {= \\{void \\(const volatile S \\* const\\)\\} $hex <S::method\\(\\) const volatile>}
|
|
$syntax_re}
|
|
|
|
{"S::method(void)" "S_M" {= \\{void \\(S \\* const\\)\\} $hex <S::method\\(\\)>}}
|
|
{"S::method(void) const" "S_M_C" {= \\{void \\(const S \\* const\\)\\} $hex <S::method\\(\\) const>}}
|
|
{"S::method(void) volatile" "S_M_V" {= \\{void \\(volatile S \\* const\\)\\} $hex <S::method\\(\\) volatile>}}
|
|
{"S::method(void) const volatile" "S_M_CV" {= \\{void \\(const volatile S \\* const\\)\\} $hex <S::method\\(\\) const volatile>}}
|
|
{"S::method(void) volatile const" "S_M_CV" {= \\{void \\(const volatile S \\* const\\)\\} $hex <S::method\\(\\) const volatile>}}
|
|
|
|
{"S::static_method()" "S_SM" {= \\{void \\(void\\)\\} $hex <S::static_method\\(\\)>}
|
|
"void"}
|
|
|
|
{"S::static_method(void)" "S_SM" {= \\{void \\(void\\)\\} $hex <S::static_method\\(\\)>}}
|
|
|
|
{"S::inline_method()" "S_IM" {= \\{void \\(S \\* const\\)\\} $hex <S::inline_method\\(\\)>}
|
|
{[cannot_resolve "S::inline_method"]}}
|
|
|
|
{"S::inline_method(void)" "S_IM" {= \\{void \\(S \\* const\\)\\} $hex <S::inline_method\\(\\)>}}
|
|
|
|
{"S::static_inline_method()" "S_SIM" {= \\{void \\(void\\)\\} $hex <S::static_inline_method\\(\\)>}
|
|
"void"}
|
|
|
|
{"S::static_inline_method(void)" "S_SIM" {= \\{void \\(void\\)\\} $hex <S::static_inline_method\\(\\)>}}
|
|
|
|
{"S2<int>::method()" "S2_M" {= \\{void \\(S2<int> \\* const\\)\\} $hex <S2<int>::method\\(\\)>}
|
|
{[cannot_resolve "S2<int>::method"]}}
|
|
|
|
{"S2<int>::static_method()" "S2_SM" {= \\{void \\(void\\)\\} $hex <S2<int>::static_method\\(\\)>}
|
|
"void"}
|
|
|
|
{"S2<int>::inline_method()" "S2_IM" {= \\{void \\(S2<int> \\* const\\)\\} $hex <S2<int>::inline_method\\(\\)>}
|
|
{[cannot_resolve "S2<int>::inline_method"]}}
|
|
|
|
{"S2<int>::static_inline_method()" "S2_SIM" {= \\{void \\(void\\)\\} $hex <S2<int>::static_inline_method\\(\\)>}
|
|
"void"}
|
|
|
|
{"free_func" "FF" {= \\{void \\(void\\)\\} $hex <free_func\\(\\)>}}
|
|
|
|
{"free_func()" "FF" {= \\{void \\(void\\)\\} $hex <free_func\\(\\)>}
|
|
"void"}
|
|
|
|
{"free_func(void)" "FF" {= \\{void \\(void\\)\\} $hex <free_func\\(\\)>}}
|
|
|
|
{"free_inline_func()" "FIF" {= \\{void \\(void\\)\\} $hex <free_inline_func\\(\\)>}
|
|
"void"}
|
|
|
|
{"free_inline_func(void)" "FIF" {= \\{void \\(void\\)\\} $hex <free_inline_func\\(\\)>}}
|
|
}
|
|
|
|
set c_scopes_list {
|
|
{"free_func" "FF" {= \\{void \\(void\\)\\} $hex <free_func>}}
|
|
{"free_inline_func" "FIF" {= \\{void \\(void\\)\\} $hex <free_inline_func>}}
|
|
}
|
|
|
|
# A list of all the static varibles defined in each scope. The first
|
|
# column is the name of the variable, without the prefix, and the
|
|
# second column is a regex matching what printing the variable should
|
|
# output.
|
|
|
|
#VAR #PRINT
|
|
set vars_list {
|
|
{"s_var_int" " = 4"}
|
|
{"s_var_float" " = 3.14.*"}
|
|
{"s_var_aggregate" " = \\{i1 = 1, i2 = 2, i3 = 3\\}"}
|
|
}
|
|
|
|
proc do_test {lang} {
|
|
global c_scopes_list
|
|
global cxx_scopes_list
|
|
global vars_list
|
|
global srcfile testfile
|
|
|
|
set options {debug}
|
|
|
|
if {$lang == "c++"} {
|
|
if { [skip_cplus_tests] } {
|
|
return
|
|
}
|
|
lappend options $lang
|
|
set src ${srcfile}c
|
|
} else {
|
|
set src ${srcfile}
|
|
}
|
|
|
|
if {[prepare_for_testing "failed to prepare" $testfile-$lang \
|
|
[list $src] $options]} {
|
|
return -1
|
|
}
|
|
|
|
if ![runto_main] then {
|
|
fail "couldn't run to breakpoint"
|
|
return
|
|
}
|
|
|
|
gdb_test "show language" " currently [string_to_regexp $lang]\"\\."
|
|
|
|
if {$lang == "c"} {
|
|
set scopes_list $c_scopes_list
|
|
} else {
|
|
set scopes_list $cxx_scopes_list
|
|
}
|
|
|
|
# Print each scope/function using these syntaxes:
|
|
#
|
|
# "(gdb) p 'S::method() const'" # quoted
|
|
# "(gdb) p S::method() const" # unquoted
|
|
#
|
|
foreach scope_line $scopes_list {
|
|
set scope [lindex $scope_line 0]
|
|
|
|
set print_quoted_re [lindex $scope_line 2]
|
|
set print_quoted_re [uplevel 1 "subst -nobackslashes -nocommands \"$print_quoted_re\""]
|
|
|
|
set print_unquoted_re [lindex $scope_line 3]
|
|
set print_unquoted_re [uplevel 1 "subst -nobackslashes -nocommands \"$print_unquoted_re\""]
|
|
|
|
gdb_test "print '${scope}'" $print_quoted_re
|
|
|
|
if {$print_unquoted_re != ""} {
|
|
gdb_test "print ${scope}" $print_unquoted_re
|
|
} else {
|
|
gdb_test "print ${scope}" $print_quoted_re
|
|
}
|
|
}
|
|
|
|
# Print each variable using these syntaxes:
|
|
#
|
|
# 'func()'::var
|
|
# func()::var
|
|
# 'func()::var'
|
|
#
|
|
# In C++, the latter case makes sure that symbol lookup finds the
|
|
# debug symbol instead of the minimal symbol with that exact same
|
|
# name.
|
|
|
|
foreach scope_line $scopes_list {
|
|
set scope [lindex $scope_line 0]
|
|
set var_prefix [lindex $scope_line 1]
|
|
foreach var_line $vars_list {
|
|
set var [lindex $var_line 0]
|
|
set print_re [lindex $var_line 1]
|
|
|
|
gdb_test "print '${scope}'::${var_prefix}_${var}" $print_re
|
|
gdb_test "print ${scope}::${var_prefix}_${var}" $print_re
|
|
|
|
set sym "${scope}::${var_prefix}_${var}"
|
|
if {$lang == "c++"} {
|
|
gdb_test "print '${sym}'" $print_re
|
|
} else {
|
|
gdb_test "print '${sym}'" "No symbol \"$sym\" in current context\\."
|
|
}
|
|
}
|
|
}
|
|
|
|
# Now run to each function, and print its variables using the
|
|
# localy-visible name.
|
|
foreach scope_line $scopes_list {
|
|
set scope [lindex $scope_line 0]
|
|
set var_prefix [lindex $scope_line 1]
|
|
|
|
with_test_prefix "$scope" {
|
|
delete_breakpoints
|
|
gdb_breakpoint "$scope"
|
|
gdb_continue_to_breakpoint "$scope"
|
|
|
|
foreach var_line $vars_list {
|
|
set var [lindex $var_line 0]
|
|
set print_re [lindex $var_line 1]
|
|
|
|
gdb_test "print ${var_prefix}_${var}" $print_re
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach lang {"c" "c++"} {
|
|
with_test_prefix $lang {
|
|
do_test $lang
|
|
}
|
|
}
|