mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-27 04:52:05 +08:00
9704b8b4bc
It is not necessary to call get_compiler_info before calling test_compiler_info, and, after recent commits that removed setting up the gcc_compiled, true, and false globals from get_compiler_info, there is now no longer any need for any test script to call get_compiler_info directly. As a result every call to get_compiler_info outside of lib/gdb.exp is redundant, and this commit removes them all. There should be no change in what is tested after this commit.
678 lines
30 KiB
Plaintext
678 lines
30 KiB
Plaintext
# Copyright 1992-2022 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 was written by Fred Fish. (fnf@cygnus.com)
|
|
|
|
set ws "\[\r\n\t \]+"
|
|
|
|
if { [skip_cplus_tests] } { continue }
|
|
|
|
standard_testfile .cc
|
|
|
|
set flags [list debug c++]
|
|
if { [test_compiler_info gcc-*] && [gcc_major_version] >= 10 } {
|
|
# Work around PR gcc/101452.
|
|
lappend flags additional_flags=-DGCC_BUG
|
|
}
|
|
|
|
if {[prepare_for_testing "failed to prepare" $testfile $srcfile $flags]} {
|
|
return -1
|
|
}
|
|
|
|
#
|
|
# Test printing of the types of templates.
|
|
#
|
|
|
|
proc test_ptype_of_templates {} {
|
|
global gdb_prompt
|
|
global ws
|
|
|
|
gdb_test_multiple "ptype/r T5<int>" "ptype T5<int>" {
|
|
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5<int> & operator=\\(T5<int> const ?&\\);${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\((void|)\\);${ws}static void \\* operator new\\(unsigned( int| long)?\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
|
|
xfail "ptype T5<int> -- new without size_t"
|
|
}
|
|
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\((void|)\\);${ws}static void \\* operator new\\(unsigned( int| long)?\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}T5<int> & operator=\\(T5<int> const ?&\\);${ws}\}\r\n$gdb_prompt $" {
|
|
xfail "ptype T5<int> -- new without size_t"
|
|
}
|
|
-re "type = class T5<int> \\{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}${ws}T5 \\(int\\);${ws}T5 \\(const class T5<int> &\\);${ws}void ~T5 \\(()\\);${ws}static void \\* new \\(unsigned int\\);${ws}static void delete \\(void ?\\*\\);${ws}int value \\((void|)\\);${ws}\\}${ws}$gdb_prompt $" {
|
|
xfail "ptype T5<int> -- new with unsigned int"
|
|
}
|
|
-re "type = class T5<int> \\{.*public:.*static int X;.*int x;.*int val;.*T5 \\(int\\);.*T5 \\(const class T5<int> &\\);.*void ~T5 \\(\\);.*static void \\* new \\(unsigned long\\);.*static void delete \\(void ?\\*\\);.*int value \\((void|)\\);.*\\}\r\n$gdb_prompt $" {
|
|
xfail "ptype T5<int> -- new with unsigned long"
|
|
}
|
|
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;((${ws}T5<int> & operator=\\(T5<int> const ?&\\);)|(${ws}T5\\(int\\);)|(${ws}T5\\((T5<int> const|const T5<int>) ?&\\);)|(${ws}~T5\\((void|)\\);)|(${ws}static void \\* operator new\\(unsigned( int| long)?\\);)|(${ws}static void operator delete\\(void ?\\*\\);)|(${ws}int value\\((void|)\\);))*${ws}\}\r\n$gdb_prompt $" {
|
|
xfail "ptype T5<int> (obsolescent gcc or gdb)"
|
|
}
|
|
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}void T5\\(int\\);${ws}void T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\(\\);${ws}static void \\* operator new\\((size_t|unsigned( int| long|))\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
|
|
# This also triggers gdb/1113...
|
|
kfail "gdb/1111" "ptype T5<int>"
|
|
# Add here a PASS case when PR gdb/1111 gets fixed.
|
|
# These are really:
|
|
# http://sourceware.org/bugzilla/show_bug.cgi?id=8216
|
|
# http://sourceware.org/bugzilla/show_bug.cgi?id=8218
|
|
}
|
|
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\(int\\);${ws}static void \\* operator new\\((size_t|unsigned( int| long|))\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
|
|
# http://sourceware.org/bugzilla/show_bug.cgi?id=8218
|
|
# The destructor has an argument type.
|
|
kfail "gdb/8218" "ptype T5<int>"
|
|
}
|
|
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\(\\);${ws}static void \\* operator new\\((size_t|unsigned( int| long|))\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
|
|
pass "ptype T5<int>"
|
|
}
|
|
}
|
|
|
|
gdb_test_multiple "ptype/r t5i" "ptype t5i" {
|
|
-re "type = class T5<int> \\{${ws}public:${ws}static int X;${ws}int x;${ws}int val;\r\n${ws}T5\\(int\\);${ws}T5\\(T5<int> const ?&\\);${ws}~T5\\((void|)\\);${ws}static void \\* operator new\\(unsigned( int| long)?\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\\}\r\n$gdb_prompt $" {
|
|
xfail "ptype T5<int> -- with several fixes from 4.17 -- without size_t"
|
|
}
|
|
-re "type = class T5<int> \\{${ws}public:${ws}static int X;${ws}int x;${ws}int val;\r\n${ws}T5 \\(int\\);${ws}T5 \\(const class T5<int> &\\);${ws}void ~T5 \\(\\);${ws}static void \\* new \\(unsigned int\\);${ws}static void delete \\(void ?\\*\\);${ws}int value \\((void|)\\);${ws}\\}\r\n$gdb_prompt $" {
|
|
xfail "ptype t5i<int> -- new with unsigned int -- without size_t"
|
|
}
|
|
-re "type = class T5<int> \\{${ws}public:${ws}static int X;${ws}int x;${ws}int val;\r\n${ws}T5 \\(int\\);${ws}T5 \\(const class T5<int> &\\);${ws}void ~T5 \\(\\);${ws}static void \\* new \\(unsigned long\\);${ws}static void delete \\(void ?\\*\\);${ws}int value \\((void|)\\);${ws}\\}\r\n$gdb_prompt $" {
|
|
xfail "ptype t5i<int> -- new with unsigned long -- without size_t"
|
|
}
|
|
-re "type = class T5<int> \{.*public:.*static int X;.*int x;.*int val;.*.*T5 \\(int\\);.*.*void ~T5 \\(\\).*.*.*int value \\((void|)\\);.*\}.*$gdb_prompt $" {
|
|
xfail "ptype t5i -- without size_t"
|
|
}
|
|
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5<int> & operator=\\(T5<int> const ?&\\);${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\((void|)\\);${ws}static void \\* operator new\\(unsigned( int| long)?\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
|
|
xfail "ptype t5i -- without size_t"
|
|
}
|
|
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\((void|)\\);${ws}static void \\* operator new\\(unsigned( int| long)?\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}T5<int> & operator=\\(T5<int> const ?&\\);${ws}\}\r\n$gdb_prompt $" {
|
|
xfail "ptype t5i -- without size_t"
|
|
}
|
|
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;((${ws}T5<int> & operator=\\(T5<int> const ?&\\);)|(${ws}T5\\(int\\);)|(${ws}T5\\(T5<int> const ?&\\);)|(${ws}~T5\\((void|)\\);)|(${ws}static void \\* operator new\\(unsigned( int| long)?\\);)|(${ws}static void operator delete\\(void ?\\*\\);)|(${ws}int value\\((void|)\\);))*${ws}\}\r\n$gdb_prompt $" {
|
|
xfail "ptype t5i (obsolescent gcc or gdb) -- without size_t"
|
|
}
|
|
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}void T5\\(int\\);${ws}void T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\(\\);${ws}static void \\* operator new\\((size_t|unsigned( int| long|))\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
|
|
# This also triggers gdb/1113...
|
|
kfail "gdb/1111" "ptype t5i"
|
|
# Add here a PASS case when PR gdb/1111 gets fixed.
|
|
# These are really:
|
|
# http://sourceware.org/bugzilla/show_bug.cgi?id=8216
|
|
# http://sourceware.org/bugzilla/show_bug.cgi?id=8218
|
|
}
|
|
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\(int\\);${ws}static void \\* operator new\\((size_t|unsigned( int| long|))\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
|
|
# http://sourceware.org/bugzilla/show_bug.cgi?id=8218
|
|
# The destructor has an argument type.
|
|
kfail "gdb/8218" "ptype t5i"
|
|
}
|
|
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\(\\);${ws}static void \\* operator new\\((size_t|unsigned( int| long|))\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
|
|
pass "ptype t5i"
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Test breakpoint setting on template methods.
|
|
#
|
|
|
|
proc test_template_breakpoints {} {
|
|
global gdb_prompt
|
|
global testfile
|
|
global srcdir
|
|
|
|
gdb_test_multiple "break T5<int>::T5" "constructor breakpoint" {
|
|
-re "0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2.*templates.cc:T5<int>::T5\\((T5<int> const|const T5<int>) ?&\\)\[\r\n\]*.3.*templates.cc:T5<int>::T5\\(int\\)\[\r\n\]*> $" {
|
|
gdb_test "0" \
|
|
"canceled" \
|
|
"constructor breakpoint"
|
|
}
|
|
-re "0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2. T5 at .*\[\r\n\]*.3. T5 at .*\[\r\n\]*> $" {
|
|
setup_kfail "gdb/1062" "*-*-*"
|
|
gdb_test "0" \
|
|
"nonsense intended to insure that this test fails" \
|
|
"constructor breakpoint"
|
|
}
|
|
-re ".*\n> $" {
|
|
gdb_test "0" \
|
|
"nonsense intended to insure that this test fails" \
|
|
"constructor breakpoint (bad menu choices)"
|
|
}
|
|
}
|
|
|
|
gdb_test_multiple "break T5<int>::~T5" "destructor_breakpoint" {
|
|
-re "Breakpoint.*at.* file .*${testfile}.cc, line.*$gdb_prompt $"
|
|
{
|
|
pass "destructor breakpoint"
|
|
}
|
|
-re "the class `T5<int>' does not have destructor defined\r\nHint: try 'T5<int>::~T5<TAB> or 'T5<int>::~T5<ESC-\\?>\r\n\\(Note leading single quote.\\)\r\n$gdb_prompt $"
|
|
{
|
|
kfail "gdb/1112" "destructor breakpoint"
|
|
}
|
|
}
|
|
|
|
gdb_test "break T5<int>::value" \
|
|
"Breakpoint.*at.* file .*${testfile}.cc, line.*" \
|
|
"value method breakpoint"
|
|
|
|
set bp_location [gdb_get_line_number \
|
|
"set breakpoint on a line with no real code"]
|
|
|
|
gdb_test_multiple "break ${testfile}.cc:${bp_location}" \
|
|
"breakpoint on a line with no real code" {
|
|
-re "0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2.*templates.cc:GetMax<int>\\(int, int\\)\[\r\n\]*.3.*templates.cc:GetMax<long>\\(long, long\\)\[\r\n\]*> $" {
|
|
gdb_test "0" \
|
|
"canceled" \
|
|
"breakpoint on a line with no real code"
|
|
}
|
|
-re "0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2.*\[\r\n\]*.3.*\[\r\n\]*> $" {
|
|
gdb_test "0" \
|
|
"nonsense intended to insure that this test fails" \
|
|
"breakpoint on a line with no real code"
|
|
}
|
|
-re ".*\n> $" {
|
|
gdb_test "0" \
|
|
"nonsense intended to insure that this test fails" \
|
|
"breakpoint on a line with no real code"
|
|
}
|
|
}
|
|
|
|
delete_breakpoints
|
|
}
|
|
|
|
#
|
|
# Test calling of template methods.
|
|
#
|
|
|
|
proc test_template_calls {} {
|
|
global gdb_prompt
|
|
|
|
if [target_info exists gdb,cannot_call_functions] {
|
|
unsupported "this target can not call functions"
|
|
return
|
|
}
|
|
|
|
setup_xfail hppa*-*-*
|
|
gdb_test_multiple "print t5i.value()" "print t5i.value()" {
|
|
-re ".* = 2\[\r\n\]*$gdb_prompt $" {
|
|
pass "print t5i.value()"
|
|
}
|
|
-re "Cannot invoke functions on this machine.*$gdb_prompt $" {
|
|
fail "print t5i.value()"
|
|
}
|
|
-re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
|
|
setup_xfail hppa*-*-* CLLbs16899
|
|
xfail "print t5i.value"
|
|
}
|
|
}
|
|
}
|
|
|
|
proc test_template_typedef {} {
|
|
global gdb_prompt
|
|
|
|
gdb_test "print intBazOne::baz" ".*baz\\(int, int\\)>" \
|
|
"print method of template typedef"
|
|
|
|
set test "print destructor of template typedef"
|
|
gdb_test_multiple "print intBazOne::~Baz" $test {
|
|
-re "~Baz(\\(\\))?>\r\n$gdb_prompt $" {
|
|
pass $test
|
|
}
|
|
-re "There is no field named ~Baz\r\n$gdb_prompt $" {
|
|
set test2 "verify GCC PR debug/51668"
|
|
gdb_test_multiple "whatis intBazOne" $test2 {
|
|
-re "type = Baz<int, \\(char\\)'\\\\001'>\r\n$gdb_prompt $" {
|
|
setup_xfail gcc/51668 "*-*-*"
|
|
xfail $test
|
|
pass $test2
|
|
}
|
|
-re "\r\n$gdb_prompt $" {
|
|
# Some unexpected response.
|
|
fail $test
|
|
fail $test2
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
proc test_template_args {} {
|
|
|
|
set empty_re "Empty *<void *\\(FunctionArg *<int>\\)>"
|
|
gdb_test "ptype/r empty" \
|
|
"type = (struct|class) $empty_re {.*<no data fields>.*}" \
|
|
"ptype empty"
|
|
|
|
gdb_test "ptype/r arg" \
|
|
"type = (struct|class) FunctionArg<int> {.*int method\\($empty_re \\&\\);.*}" \
|
|
"ptype arg"
|
|
}
|
|
|
|
proc do_tests {} {
|
|
# Change multiple-symbols to "ask" in order to get the multiple-choice
|
|
# menu when breaking on overloaded methods.
|
|
gdb_test_no_output "set multiple-symbols ask"
|
|
|
|
runto_main
|
|
|
|
test_ptype_of_templates
|
|
test_template_breakpoints
|
|
test_template_typedef
|
|
test_template_args
|
|
|
|
if [ runto_main] {
|
|
test_template_calls
|
|
}
|
|
}
|
|
|
|
do_tests
|
|
|
|
|
|
# More tests for different kinds of template parameters,
|
|
# templates with partial specializations, nested templates, etc.
|
|
|
|
gdb_breakpoint [gdb_get_line_number "Final breakpoint"]
|
|
gdb_continue_to_breakpoint "Final breakpoint"
|
|
|
|
gdb_test "print fint" \
|
|
"\\$\[0-9\]* = \\{x = 0, t = 0\\}"
|
|
|
|
# Prevent symbol on address 0x0 being printed.
|
|
gdb_test_no_output "set print symbol off"
|
|
gdb_test "print fvpchar" \
|
|
"\\$\[0-9\]* = \\{x = 0, t = 0x0\\}"
|
|
|
|
# Template Foo<T>
|
|
|
|
# Neither stabs nor DWARF-2 contains type information about templates
|
|
# (as opposed to instantiations of templates), so in those
|
|
# circumstances we expect GDB to not find a symbol. HP has a debug
|
|
# format that contains more info, though, so it's also correct to
|
|
# print out template info. (This affects several subsequent tests as
|
|
# well.)
|
|
|
|
# NOTE: carlton/2003-02-26: However, because of a bug in the way GDB
|
|
# handles nested types, we don't get this right in the DWARF-2 case.
|
|
|
|
gdb_test_multiple "ptype/r Foo" "ptype Foo" {
|
|
-re "type = template <(class |)T> (class |)Foo \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Foo<volatile char \\*>\r\n\[ \t\]*(class |)Foo<char>\r\n\[ \t\]*(class |)Foo<int>\r\n$gdb_prompt $" {
|
|
pass "ptype Foo"
|
|
}
|
|
-re "type = template <(class |)T> (class |)Foo \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\n$gdb_prompt $" {
|
|
xfail "ptype Foo"
|
|
}
|
|
-re "type = class Foo<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int foo\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
# GCC 3.1, DWARF-2 output.
|
|
kfail "gdb/57" "ptype Foo"
|
|
}
|
|
-re "No symbol \"Foo\" in current context.\r\n$gdb_prompt $" {
|
|
# GCC 2.95.3, stabs+ output.
|
|
pass "ptype Foo"
|
|
}
|
|
}
|
|
|
|
# -re "type = class Foo<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int foo(int, int);\r\n\\}\r\n$gdb_prompt $"
|
|
|
|
# ptype Foo<int>
|
|
|
|
gdb_test_multiple "ptype/r fint" "ptype fint" {
|
|
-re "type = (class |)Foo<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int foo\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype fint"
|
|
}
|
|
-re "type = (class |)Foo<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int foo\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype fint"
|
|
}
|
|
}
|
|
|
|
# ptype Foo<char>
|
|
|
|
gdb_test_multiple "ptype/r fchar" "ptype fchar" {
|
|
-re "type = (class |)Foo<char> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*.*char foo\\(int, char\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype fchar"
|
|
}
|
|
-re "type = (class |)Foo<char> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*char foo\\(int, char\\);.*\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype fchar"
|
|
}
|
|
}
|
|
|
|
# ptype Foo<volatile char *>
|
|
|
|
gdb_test_multiple "ptype/r fvpchar" "ptype fvpchar" {
|
|
-re "type = (class |)Foo<volatile char ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*char.*\\*t;\r\n\r\n\[ \t\]*.*char \\* foo\\(int,.*char.*\\*\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype fvpchar"
|
|
}
|
|
-re "type = (class |)Foo<volatile char ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*char.*\\*t;\r\n\r\n\[ \t\]*.*char \\* foo\\(int,.*char.*\\*\\);.*\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype fvpchar"
|
|
}
|
|
-re "type = (class |)Foo<char volatile ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*char.*\\*t;\r\n\r\n\[ \t\]*.*char \\* foo\\(int,.*char.*\\*\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
kfail "gdb/1512" "ptype fvpchar"
|
|
}
|
|
}
|
|
|
|
# print a function from Foo<volatile char *>
|
|
|
|
# This test is sensitive to whitespace matching, so we'll do it twice,
|
|
# varying the spacing, because of PR gdb/33.
|
|
|
|
gdb_test_multiple "print Foo<volatile char *>::foo" "print Foo<volatile char *>::foo" {
|
|
-re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<(volatile char|char volatile) ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" {
|
|
pass "print Foo<volatile char *>::foo"
|
|
}
|
|
-re "No symbol \"Foo<volatile char \\*>\" in current context.\r\n$gdb_prompt $" {
|
|
# This used to be a kfail gdb/33 and then kfail gdb/931.
|
|
fail "print Foo<volatile char *>::foo"
|
|
}
|
|
}
|
|
|
|
gdb_test_multiple "print Foo<volatile char*>::foo" "print Foo<volatile char*>::foo" {
|
|
-re "\\$\[0-9\]* = \\{.*char \\*\\((class |)Foo<(volatile char|char volatile) ?\\*> \\*(| const), int, .*char \\*\\)\\} $hex <Foo<.*char.*\\*>::foo\\(int, .*char.*\\*\\)>\r\n$gdb_prompt $" {
|
|
pass "print Foo<volatile char*>::foo"
|
|
}
|
|
-re "No symbol \"Foo<volatile char\\*>\" in current context.\r\n$gdb_prompt $" {
|
|
# This used to be a kfail gdb/33 and then kfail gdb/931.
|
|
fail "print Foo<volatile char*>::foo"
|
|
}
|
|
}
|
|
|
|
# Template Bar<T, int>
|
|
|
|
# same as Foo for g++
|
|
gdb_test_multiple "ptype/r Bar" "ptype Bar" {
|
|
-re "type = template <(class |)T, (class |)sz> (class |)Bar \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Bar<int,(\\(int\\)|)1>\r\n\[ \t\]*(class |)Bar<int,(\\(int\\)|)33>\r\n$gdb_prompt $" {
|
|
pass "ptype Bar"
|
|
}
|
|
-re "type = <(class |)T, (class |)sz> (class |)Bar \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\n$gdb_prompt $" {
|
|
xfail "ptype Bar"
|
|
}
|
|
-re "ptype Bar\r\ntype = class Bar<int, ?33> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int bar\\(int, int\\);\r\n}\r\n$gdb_prompt $" {
|
|
# GCC 3.1, DWARF-2 output.
|
|
kfail "gdb/57" "ptype Bar"
|
|
}
|
|
-re "No symbol \"Bar\" in current context.\r\n$gdb_prompt $" {
|
|
# GCC 2.95.3, stabs+ output.
|
|
pass "ptype Bar"
|
|
}
|
|
}
|
|
|
|
|
|
# ptype Bar<int,33>
|
|
|
|
gdb_test_multiple "ptype/r bint" "ptype bint" {
|
|
-re "type = (class |)Bar<int, ?(\\(int\\)|)33> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int bar\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype bint"
|
|
}
|
|
-re "type = (class |)Bar<int,(\\(int\\)|)33> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int bar\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype bint"
|
|
}
|
|
}
|
|
|
|
# ptype Bar<int, (4>3)>
|
|
|
|
gdb_test_multiple "ptype/r bint2" "ptype bint2" {
|
|
-re "type = (class |)Bar<int, ?(\\(int\\)|)1> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int bar\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype bint2"
|
|
}
|
|
-re "type = (class |)Bar<int,(\\(int\\)|)1> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int bar\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype bint2"
|
|
}
|
|
}
|
|
|
|
# Template Baz<T, char>
|
|
|
|
# Same as Foo, for g++
|
|
gdb_test_multiple "ptype/r Baz" "ptype Baz" {
|
|
-re "type = template <(class |)T, ?(class |)sz> (class |)Baz \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Baz<char,(\\(char\\)|)97>\r\n\[ \t\]*(class |)Baz<int,(\\(char\\)|)115>\r\n$gdb_prompt $" {
|
|
pass "ptype Baz"
|
|
}
|
|
-re "type = <(class |)T, ?(class |)sz> (class |)Baz \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\n$gdb_prompt $" {
|
|
xfail "ptype Baz"
|
|
}
|
|
-re "type = class Baz<int, ?'s'> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int baz\\(int, int\\);\r\n}\r\n$gdb_prompt $" {
|
|
# GCC 3.1, DWARF-2 output.
|
|
kfail "gdb/57" "ptype Baz"
|
|
}
|
|
-re "type = class Baz<int, ?(\\(char\\))?115> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int baz\\(int, int\\);\r\n}\r\n$gdb_prompt $" {
|
|
# GCC 3.x, DWARF-2 output, running into gdb/57 and gdb/1512.
|
|
kfail "gdb/57" "ptype Baz"
|
|
}
|
|
-re "No symbol \"Baz\" in current context.\r\n$gdb_prompt $" {
|
|
# GCC 2.95.3, stabs+ output.
|
|
pass "ptype Baz"
|
|
}
|
|
}
|
|
|
|
|
|
# ptype Baz<int, 's'>
|
|
|
|
gdb_test_multiple "ptype/r bazint" "ptype bazint" {
|
|
-re "type = (class |)Baz<int, ?(\\(char\\)|)(115|\\'s\\')> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int baz\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype bazint"
|
|
}
|
|
-re "type = (class |)Baz<int,(\\(char\\)|)(115|\\'s\\')> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int baz\\(int, int\\).*;\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype bazint"
|
|
}
|
|
}
|
|
|
|
# ptype Baz<char, 'a'>
|
|
|
|
gdb_test_multiple "ptype/r bazint2" "ptype bazint2" {
|
|
-re "type = (class |)Baz<char, ?(\\(char\\)|)(97|\\'a\\')> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*.*char baz\\(int, char\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype bazint2"
|
|
}
|
|
-re "type = (class |)Baz<char,(\\(char\\)|)(97|\\'a\\')> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*char baz\\(int, char\\);.*\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype bazint2"
|
|
}
|
|
}
|
|
|
|
# Template Qux<T, int (*f)(int) >
|
|
# Same as Foo for g++
|
|
gdb_test_multiple "ptype/r Qux" "ptype Qux" {
|
|
-re "type = template <(class |)T, ?(class |)sz> (class |)Qux \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Qux<int,&string>\r\n\[ \t\]*(class |)Qux<char,&string>\r\n$gdb_prompt $" {
|
|
pass "ptype Qux"
|
|
}
|
|
-re ".*type = template <(class |)T.*, ?(class |)sz> (class |)Qux \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}.*$gdb_prompt $" {
|
|
pass "ptype Qux"
|
|
}
|
|
-re "type = class Qux<char, ?&string> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*char qux\\(int, char\\);\r\n}\r\n$gdb_prompt $" {
|
|
# GCC 3.1, DWARF-2 output.
|
|
kfail "gdb/57" "ptype Qux"
|
|
}
|
|
-re "type = class Qux<char, ?&\\(string\\)> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*char qux\\(int, char\\);\r\n}\r\n$gdb_prompt $" {
|
|
# GCC 3.x, DWARF-2 output; gdb/57 + gdb/1512.
|
|
kfail "gdb/57" "ptype Qux"
|
|
}
|
|
-re "No symbol \"Qux\" in current context.\r\n$gdb_prompt $" {
|
|
# GCC 2.95.3, stabs+ output.
|
|
pass "ptype Qux"
|
|
}
|
|
}
|
|
|
|
# pt Qux<int,&string>
|
|
|
|
gdb_test_multiple "ptype/r quxint" "ptype quxint" {
|
|
-re "type = class Qux<int, ?& ?string> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int qux\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype quxint"
|
|
}
|
|
-re "type = class Qux<int, string> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int qux\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype quxint"
|
|
}
|
|
-re "type = class Qux<int, ?& ?string> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype quxint"
|
|
}
|
|
-re "type = class Qux<int, ?\\(char ?\\*\\)\\(& ?\\(?string\\)?\\)> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype quxint"
|
|
}
|
|
-re "type = class Qux<int, ?& ?\\(string\\)> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int qux\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" {
|
|
kfail "gdb/1512" "ptype quxint"
|
|
}
|
|
}
|
|
|
|
|
|
# Template Spec<T1, T2>
|
|
|
|
# Same as Foo for g++
|
|
gdb_test_multiple "ptype/r Spec" "ptype Spec" {
|
|
-re "type = template <(class |)T1, (class |)T2> (class |)Spec \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Spec<int,int \\*>\r\n\[ \t\]*(class |)Spec<int,char>\r\n$gdb_prompt $" {
|
|
pass "ptype Spec"
|
|
}
|
|
-re "type = <(class |)T1, (class |)T2> (class |)Spec \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\\}\r\n$gdb_prompt $" {
|
|
xfail "ptype Spec"
|
|
}
|
|
-re "type = class Spec<int, ?char> {\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\r\n\[ \t\]*int spec\\(char\\);\r\n}\r\n$gdb_prompt $" {
|
|
# GCC 3.1, DWARF-2 output.
|
|
kfail "gdb/57" "ptype Spec"
|
|
}
|
|
-re "No symbol \"Spec\" in current context.\r\n$gdb_prompt $" {
|
|
# GCC 2.95.3, stabs+ output.
|
|
pass "ptype Spec"
|
|
}
|
|
}
|
|
|
|
# pt Spec<char,0>
|
|
|
|
gdb_test_multiple "ptype/r siip" "ptype siip" {
|
|
-re "type = class Spec<int, ?int ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\r\n\[ \t\]*.*int spec\\(int ?\\*\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype siip"
|
|
}
|
|
-re "type = class Spec<int,int ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\r\n\[ \t\]*int spec\\(int ?\\*\\);.*\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype siip"
|
|
}
|
|
}
|
|
|
|
# Check cv qualifiers and substitute parameters.
|
|
|
|
if {[test_compiler_info {clang-*}]} {
|
|
setup_kfail "llvm/52262 " "*-*-*"
|
|
}
|
|
gdb_test "ptype cfoo" [multi_line \
|
|
"type = (class |)Cfoo<double> \\\[with DataT = double\\\] \\{" \
|
|
"\[ \t\]*public:" \
|
|
"\[ \t\]*DataT me0;" \
|
|
"\[ \t\]*const DataT me1;" \
|
|
"\[ \t\]*const myfloat me2;" \
|
|
"\[ \t\]*const int me3;" \
|
|
"" \
|
|
"\[ \t\]*private:" \
|
|
"\[ \t\]*typedef float myfloat;" \
|
|
"\\}" \
|
|
] "print type of cfoo"
|
|
|
|
# Check cv qualifiers and do not substitute.
|
|
|
|
if {[test_compiler_info {clang-*}]} {
|
|
setup_kfail "llvm/52262 " "*-*-*"
|
|
}
|
|
gdb_test "ptype/r cfoo" [multi_line \
|
|
"type = (class |)Cfoo<double> \\{" \
|
|
"\[ \t\]*public:" \
|
|
"\[ \t\]*double me0;" \
|
|
"\[ \t\]*const double me1;" \
|
|
"\[ \t\]*const Cfoo<double>::myfloat me2;" \
|
|
"\[ \t\]*const int me3;" \
|
|
"" \
|
|
"\[ \t\]*private:" \
|
|
"\[ \t\]*typedef float myfloat;" \
|
|
"\\}" \
|
|
] "print raw type of cfoo"
|
|
|
|
# pt Garply<int>
|
|
|
|
gdb_test_multiple "ptype/r Garply<int>" "ptype Garply<int>" {
|
|
-re "type = class Garply<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int garply\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype Garply<int>"
|
|
}
|
|
-re "type = class Garply<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*int garply\\(int, int\\);.*\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype Garply<int>"
|
|
}
|
|
}
|
|
|
|
# ptype of nested template name
|
|
|
|
gdb_test_multiple "ptype/r Garply<Garply<char> >" "ptype Garply<Garply<char> >" {
|
|
-re "type = (class |)Garply<Garply<char> > \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*(class |)Garply<char> t;\r\n\r\n\[ \t\]*.*(class |)Garply<char> garply\\(int, (class |)Garply<char>\\);\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype Garply<Garply<char> >"
|
|
}
|
|
-re "type = (class |)Garply<Garply<char> > \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*(class |)Garply<char> t;\r\n\r\n\[ \t\]*(class |)Garply<char> garply\\(int, (class |)Garply<char>\\);.*\r\n\\}\r\n$gdb_prompt $" {
|
|
pass "ptype Garply<Garply<char> >"
|
|
}
|
|
}
|
|
|
|
# print out a function from a nested template name
|
|
|
|
gdb_test "print Garply<Garply<char> >::garply" \
|
|
"\\$\[0-9\]* = \\{(class |)Garply<char> \\((class |)Garply<Garply<char> > \\*(| const), int, (class |)Garply<char>\\)\\} $hex <Garply<Garply<char>\[ \t\]*>::garply\\(int, (class |)Garply<char>\\)>"
|
|
|
|
# djb - 06-03-2000
|
|
# Now should work fine
|
|
gdb_test "break Garply<Garply<char> >::garply" \
|
|
"Breakpoint \[0-9\]* at $hex: file .*templates.cc, line.*"
|
|
|
|
#
|
|
# Template wild-matching tests
|
|
#
|
|
|
|
# Turn off "ask" when multiple symbols are seen.
|
|
gdb_test_no_output "set multiple-symbols all"
|
|
|
|
# Test setting breakpoints in a method of all class template instantiations,
|
|
# including overloads.
|
|
gdb_test "break Foo::foo" "Breakpoint.*at.* \\(3 locations\\)"
|
|
foreach t [list "int" "char" "volatile char *"] {
|
|
gdb_breakpoint "Foo<$t>::foo (int, $t)"
|
|
gdb_breakpoint "Foo::foo (int, $t)"
|
|
}
|
|
|
|
gdb_test "break Bar::bar" "Breakpoint.*at.* \\(2 locations\\)"
|
|
gdb_test "break Bar::bar (int, int)" "Breakpoint.*at.* \\(2 locations\\)"
|
|
foreach val [list 1 33] {
|
|
gdb_breakpoint "Bar<int, $val>::bar (int, int)"
|
|
}
|
|
|
|
# Test setting breakpoints in a member function template of a class template,
|
|
# including overloads.
|
|
gdb_test "break Foozle::fogey" "Breakpoint.*at.* \\(9 locations\\)" \
|
|
"break at template method fogey"
|
|
foreach t [list "int" "char" "Empty<int>"] {
|
|
gdb_test "break Foozle::fogey ($t)" "Breakpoint.*at.* \\(3 locations\\)"
|
|
gdb_test "break Foozle::fogey<$t>" "Breakpoint.*at.* \\(3 locations\\)"
|
|
foreach u [list "int" "char" "Empty<int>"] {
|
|
gdb_breakpoint "Foozle<$t>::fogey<$u>" message
|
|
gdb_breakpoint "Foozle<$t>::fogey<$u> ($u)" message
|
|
}
|
|
}
|
|
|
|
# Test templated operators < and <<. Restrict results to only the test
|
|
# source file.
|
|
# operator<:
|
|
# 1. operator< (const T2&, const T2&)
|
|
# 2. operator< (const T2&, char)
|
|
# 3. operator< <Empty<int>>
|
|
# 4. operator< <Foozle<in>>
|
|
#
|
|
# operator<<:
|
|
# 1. operator<< <Empty<int>>
|
|
# 2. operator<< <Foozle<int>>
|
|
gdb_test "break -source $srcfile -func operator<" \
|
|
"Breakpoint.*at.* \\(4 locations\\)"
|
|
gdb_test "break -source $srcfile -func operator<<" \
|
|
"Breakpoint.*at.* \\(2 locations\\)"
|
|
foreach t [list "Empty" "Foozle"] {
|
|
set tt "$t<int>"
|
|
gdb_breakpoint "operator< <$tt>" message
|
|
gdb_breakpoint "operator<< <$tt>" message
|
|
|
|
# Try a specific instance, both with and without whitespace
|
|
# after the template-template parameter.
|
|
gdb_breakpoint "operator< <$tt> ($tt&, $tt&)" message
|
|
gdb_breakpoint "operator< <$tt > ($tt&, $tt&)" message
|
|
gdb_breakpoint "operator<< <$tt> ($tt&, $tt&)" message
|
|
gdb_breakpoint "operator<< <$tt > ($tt&, $tt&)" message
|
|
}
|
|
|
|
# Test that "-qualified" finds no matching locations.
|
|
gdb_test_no_output "set breakpoint pending off"
|
|
gdb_test "break -qualified Foozle::fogey" \
|
|
"Function \"Foozle::fogey\" not defined."
|