old-cross-binutils/gdb/testsuite/gdb.cp/member-ptr.exp
Keith Seitz cec808ecec * gdb.cp/cp-relocate.exp: Remove single-quoting of C++ methods.
* gdb.cp/cplusfuncs.cc (dm_type_short): New function.
        (dm_type_long): New function.
        (dm_type_unsigned_short): New function.
        (dm_type_unsigned_long): New function.
        (myint): New typedef.
        * gdb.cp/cplusfuncs.exp (probe_demangler): Add tests for short,
        long, unsigned shor and long, operator char*, and typedef.
        (test_lookup_operator_functions): Add operator char* test.
        (test_paddr_operator_functions): Likewise.
        (test_paddr_overloaded_functions): Use probe values for
        short, long, and unsigned short and long.
        (test_paddr_hairy_functions): If the demangler probe detected
        gdb type printers, "expect" them. Otherwise "expect" the v2 or v3
        demangler.
        * gdb.cp/expand-sals.exp: Backtrace may contain class names.
        * gdb.cp/member-ptr.exp: Refine expected result for "print pmf"
        and "print null_pmf".
        Add test "ptype a.*pmf".
        * gdb.cp/overload.exp: Allow optional "int" to appear with
        "short" and "long".
        * gdb.cp/ovldbreak.exp: Use append to construct super-duper
        long expect value for men_overload1arg.
        Allow "int" to appear with "short" and "long".
        When testing "info break", add argument for main (void).
        Also allow "int" to appear with "short" and "long".
        Ditto with "unsigned" and "long long".
	* gdb.java/jmain.exp: Do not enclose methods names in single
	quotes.
	* gdb.java/jmisc.exp: Likewise.
	* gdb.java/jprint.exp: Likewise.
	* gdb.python/py-symbol.exp: Update expected "linkage_name" value.

	From Jan Kratochvil  <jan.kratochvil@redhat.com>:
	* gdb.cp/exception.exp (backtrace after first throw)
	(backtrace after second throw): Allow a namespace before __cxa_throw.
	(backtrace after first catch, backtrace after second catch): Allow
	a namespace before __cxa_begin_catch.

	* gdb.cp/cpexprs.exp: New file.
	* gdb.cp/cpexprs.cc: New file.

	From Daniel Jacobowitz  <dan@codesourcery.com>
	* gdb.cp/cpexprs.exp (escape): Delete.  Change all callers
	to use string_to_regexp.
	(ctor, dtor): New functions.  Use them to match constructor
	and destructor function types.
	(Top level): Use runto_main.
2010-03-09 18:08:05 +00:00

664 lines
19 KiB
Text

# Copyright 1998, 1999, 2003, 2004, 2006, 2007, 2008, 2009, 2010
# Free Software Foundation, Inc.
# This file is part of the gdb testsuite
# 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 pointer-to-member support
# Written by Satish Pai <pai@apollo.hp.com> 1997-08-19
# Rewritten by Michael Chastain <mec.gnu@mindspring.com> 2004-01-11
set vhn "\\$\[0-9\]+"
if $tracelevel then {
strace $tracelevel
}
if { [skip_cplus_tests] } { continue }
set prms_id 0
set bug_id 0
set testfile "member-ptr"
set srcfile ${testfile}.cc
set binfile ${objdir}/${subdir}/${testfile}
if [get_compiler_info ${binfile} "c++"] {
return -1
}
if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
untested member-ptr.exp
return -1
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
if ![runto_main] then {
perror "couldn't run to breakpoint"
continue
}
gdb_breakpoint [gdb_get_line_number "Breakpoint 1 here"]
gdb_continue_to_breakpoint "continue to pmi = NULL"
# ======================
# pointer to member data
# ======================
# ptype on pointer to data member
set name "ptype pmi (A::j)"
gdb_test_multiple "ptype pmi" $name {
-re "type = int A::\\*\r\n$gdb_prompt $" {
pass $name
}
}
# print pointer to data member
set name "print pmi (A::j) "
gdb_test_multiple "print pmi" $name {
-re "$vhn = &A::j\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = \\(int ?\\( ?A::\\*\\)\\) &A::j\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = \\(int ?\\( ?A::\\*\\)\\) ?&A::j ?\\+ ?1 bytes\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
kfail "gdb/NNNN" $name
}
-re "$vhn = &A::j ?\\+ ?1 bytes\r\n$gdb_prompt $" {
# gcc 2.95.3 -gstabs+
kfail "gdb/NNNN" $name
}
-re "$vhn = not implemented: member type in c_val_print\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-11 05:33:21 -gdwarf-2
# gcc HEAD 2004-01-11 05:33:21 -gstabs+
kfail "gdb/NNNN" $name
}
-re "$vhn = \\(int ?\\( A::\\*\\)\\) 536870920\r\n$gdb_prompt $" {
# the value is 0x20000008 hex. 0x20000000 is an internal flag.
# Use '|' to add in more values as needed.
# hpacc A.03.45
kfail "gdb/NNNN" $name
}
}
# print dereferenced pointer to data member
set name "print a.*pmi (A::j)"
gdb_test_multiple "print a.*pmi" $name {
-re "$vhn = 121\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = 855638016\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
# gcc 2.95.3 -gstabs+
kfail "gdb/NNNN" $name
}
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# print dereferenced pointer to data member
# this time, dereferenced through a pointer
set name "print a_p->*pmi (A::j)"
gdb_test_multiple "print a_p->*pmi" $name {
-re "$vhn = 121\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = 855638016\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
# gcc 2.95.3 -gstabs+
kfail "gdb/NNNN" $name
}
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# set the pointer to a different data member
set name "set var pmi = &A::jj"
gdb_test_multiple "set var pmi = &A::jj" $name {
-re "Invalid cast.\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
-re "set var pmi = &A::jj\r\n$gdb_prompt $" {
# I have to match the echo'ed input explicitly here.
# If I leave it out, the pattern becomes too general
# and matches anything that ends in "$gdb_prompt $".
pass $name
}
}
# print the pointer again
set name "print pmi (A::jj)"
gdb_test_multiple "print pmi" $name {
-re "$vhn = &A::jj\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = \\(int ?\\( ?A::\\*\\)\\) &A::jj\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = not implemented: member type in c_val_print\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-11 05:33:21 -gdwarf-2
# gcc HEAD 2004-01-11 05:33:21 -gstabs+
kfail "gdb/NNNN" $name
}
-re "$vhn = \\(int ?\\( A::\\*\\)\\) 536870924\r\n$gdb_prompt $" {
# the value is 0x20000008 hex. 0x20000000 is an internal flag.
# Use '|' to add in more values as needed.
# hpacc A.03.45
kfail "gdb/NNNN" $name
}
}
# print dereferenced pointer to data member again
set name "print a.*pmi (A::jj)"
gdb_test_multiple "print a.*pmi" $name {
-re "$vhn = 1331\r\n$gdb_prompt $" {
pass $name
}
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# set the pointer to data member back to A::j
set name "set var pmi = &A::j"
gdb_test_multiple "set var pmi = &A::j" $name {
-re "Invalid cast.\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
-re "set var pmi = &A::j\r\n$gdb_prompt $" {
# I have to match the echo'ed input explicitly here.
# If I leave it out, the pattern becomes too general
# and matches anything that ends in "$gdb_prompt $".
pass $name
}
}
# print dereferenced pointer to data member yet again (extra check, why not)
set name "print a.*pmi (A::j) (again)"
gdb_test_multiple "print a.*pmi" $name {
-re "$vhn = 121\r\n$gdb_prompt $" {
pass $name
}
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# Set the data member pointed to.
set name "print a.*pmi = 33"
gdb_test_multiple "print a.*pmi = 33" $name {
-re "$vhn = 33\r\n$gdb_prompt $" {
pass $name
}
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# Now check that the data really was changed
set name "print a.*pmi (A::j) (33)"
gdb_test_multiple "print a.*pmi" $name {
-re "$vhn = 33\r\n$gdb_prompt $" {
pass $name
}
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# Double-check by printing a.
set name "print a (j = 33)"
gdb_test_multiple "print a" $name {
-re "$vhn = \{c = 120 'x', j = 33, jj = 1331, (static|static int) s = 10, (_vptr.A|_vptr\\$) = ($hex|$hex <A virtual table>)\}\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = \{c = 120 'x', j = 33, jj = 1331, (static|static int) s = 10, Virtual table at $hex\}\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = \{(_vptr.A|_vptr\\$) = $hex, c = 120 'x', j = 33, jj = 1331, (static|static int) s = 10\}\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = \{(_vptr.A|_vptr\\$) = $hex, c = 120 'x', j = 121, jj = 1331, (static|static int) s = 10\}\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# Set the data member pointed to, using ->*
set name "print a_p->*pmi = 44"
gdb_test_multiple "print a_p->*pmi = 44" $name {
-re "$vhn = 44\r\n$gdb_prompt $" {
pass $name
}
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# Check that the data really was changed
set name "print a_p->*pmi (44)"
gdb_test_multiple "print a_p->*pmi" $name {
-re "$vhn = 44\r\n$gdb_prompt $" {
pass $name
}
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# Double-check by printing a.
set name "print a (j = 44)"
gdb_test_multiple "print a" $name {
-re "$vhn = \{c = 120 'x', j = 44, jj = 1331, (static|static int) s = 10, (_vptr.A|_vptr\\$) = ($hex|$hex <A virtual table>)\}\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = \{c = 120 'x', j = 44, jj = 1331, (static|static int) s = 10, Virtual table at $hex\}\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = \{(_vptr.A|_vptr\\$) = $hex, c = 120 'x', j = 44, jj = 1331, (static|static int) s = 10\}\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = \{(_vptr.A|_vptr\\$) = $hex, c = 120 'x', j = 121, jj = 1331, (static|static int) s = 10\}\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# ptype the dereferenced pointer to member.
set name "ptype a.*pmi"
gdb_test_multiple "ptype a.*pmi" $name {
-re "type = int\r\n$gdb_prompt" {
pass $name
}
-re "not implemented: member types in unpack_long\r\n$gdb_prompt $" {
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# dereference the pointer to data member without any object
# this is not allowed: a pmi must be bound to an object to dereference
set name "print *pmi"
gdb_test_multiple "print *pmi" $name {
-re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
pass $name
}
-re "Cannot access memory at address 0x4\r\n$gdb_prompt $" {
# gcc 2.95.3 -gstabs+
kfail "gdb/NNNN" $name
}
-re "Cannot access memory at address 0x8\r\n$gdb_prompt $" {
# gcc 3.3.2 -gdwarf-2
# gcc 3.3.2 -gstabs+
kfail "gdb/NNNN" $name
}
}
# dereference the pointer to data member without any object
# this is not allowed: a pmi must be bound to an object to dereference
set name "ptype *pmi"
gdb_test_multiple "ptype *pmi" $name {
-re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
pass $name
}
-re "type = int A::\r\n$gdb_prompt $" {
# gcc 2.95.3 -gstabs+
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# Check cast of pointer to member to integer.
# This is similar to "offset-of".
# such as "A a; print (size_t) &A.j - (size_t) &A".
set name "print (int) pmi"
gdb_test_multiple "print (int) pmi" $name {
-re "$vhn = (4|8|12)\r\n$gdb_prompt" {
pass $name
}
}
# Check "(int) pmi" explicitly for equality.
set name "print ((int) pmi) == ((char *) &a.j - (char *) &a)"
gdb_test_multiple "print ((int) pmi) == ((char *) &a.j - (char *) & a)" $name {
-re "$vhn = true\r\n$gdb_prompt" {
pass $name
}
}
# ==========================
# pointer to member function
# ==========================
# ptype a pointer to a method
set name "ptype pmf"
gdb_test_multiple "ptype pmf" $name {
-re "type = int \\( ?A::\\*\\)\\(A \\*, int\\)\r\n$gdb_prompt $" {
pass $name
}
-re "type = int \\( ?A::\\*\\)\\(void\\)\r\n$gdb_prompt $" {
# hpacc A.03.45
kfail "gdb/NNNN" $name
}
-re "type = struct \{.*\}\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
# gcc 2.95.3 -gstabs+
# gcc 3.2.2 -gdwarf-2
# gcc 3.2.2 -gstabs+
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# print a pointer to a method
set name "print pmf"
gdb_test_multiple "print pmf" $name {
-re "$vhn = \\(int \\(A::\\*\\)\\(A \\*, int\\)\\) $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = .*not supported with HP aCC.*\r\n$gdb_prompt $" {
# hpacc A.03.45
kfail "gdb/NNNN" $name
}
-re "$vhn = \{.*\}\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
# gcc 2.95.3 -gstabs+
# gcc 3.2.2 -gdwarf-2
# gcc 3.2.2 -gstabs+
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# ptype a pointer to a pointer to a method
set name "ptype pmf_p"
gdb_test_multiple "ptype pmf_p" $name {
-re "type = int \\( ?A::\\*\\*\\)\\(A \\*, int\\)\r\n$gdb_prompt $" {
pass $name
}
-re "type = int \\( ?A::\\*\\*\\)\\(void\\)\r\n$gdb_prompt $" {
# hpacc A.03.45
kfail "gdb/NNNN" $name
}
-re "type = struct \{.*\} \\*\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
# gcc 2.95.3 -gstabs+
# gcc 3.2.2 -gdwarf-2
# gcc 3.2.2 -gstabs+
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# print a pointer to a pointer to a method
set name "print pmf_p"
gdb_test_multiple "print pmf_p" $name {
-re "$vhn = \\(int \\( ?A::\\*\\*\\)\\)\\(int\\)\\) $hex\r\n$gdb_prompt $" {
pass $name
}
-re "$vhn = \\(PMF \\*\\) $hex\r\n$gdb_prompt $" {
pass "gdb/NNNN"
}
-re "$vhn = \\(int \\( ?A::\\*\\*\\)\\(void\\)\\) $hex\r\n$gdb_prompt $" {
# hpacc A.03.45
kfail "gdb/NNNN" $name
}
-re "$vhn = \\(struct \{.*\} \\*\\) $hex\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
kfail "gdb/NNNN" $name
}
}
# print dereferenced pointer to method
set name "print a.*pmf"
gdb_test_multiple "print a.*pmf" $name {
-re "$vhn = {int \\(A \\*, int\\)} $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
pass $name
}
-re "Pointers to methods not supported with HP aCC\r\n$gdb_prompt $" {
# hpacc A.03.45
kfail "gdb/NNNN" $name
}
-re "Value can't be converted to integer.\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
# gcc 2.95.3 -gstabs+
# gcc 3.2.2 -gdwarf-2
# gcc 3.2.2 -gstabs+
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# print dereferenced pointer to method, using ->*
set name "print a_p->*pmf"
gdb_test_multiple "print a_p->*pmf" $name {
-re "$vhn = {int \\(A \\*, int\\)} $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
pass $name
}
-re "Pointers to methods not supported with HP aCC\r\n$gdb_prompt $" {
# hpacc A.03.45
kfail "gdb/NNNN" $name
}
-re "Value can't be converted to integer.\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
# gcc 2.95.3 -gstabs+
# gcc 3.2.2 -gdwarf-2
# gcc 3.2.2 -gstabs+
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# set the pointer to data member
set name "set var pmf = &A::foo"
gdb_test_multiple "set var pmf = &A::foo" $name {
-re "set var pmf = &A::foo\r\n$gdb_prompt $" {
# I have to match the echo'ed input explicitly here.
# If I leave it out, the pattern becomes too general
# and matches anything that ends in "$gdb_prompt $".
pass $name
}
-re "Invalid cast.\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
# gcc 2.95.3 -gstabs+
# gcc 3.2.2 -gdwarf-2
# gcc 3.2.2 -gstabs+
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
-re "Assignment to pointers to methods not implemented with HP aCC\r\n$gdb_prompt $" {
kfail "gdb/NNNN" $name
}
}
# dereference the pointer to data member without any object
# this is not allowed: a pmf must be bound to an object to dereference
set name "print *pmf"
gdb_test_multiple "print *pmf" $name {
-re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
pass $name
}
-re "Structure has no component named operator\\*.\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
# gcc 2.95.3 -gstabs+
# gcc 3.3.2 -gdwarf-2
# gcc 3.3.2 -gstabs+
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# dereference the pointer to data member without any object
# this is not allowed: a pmf must be bound to an object to dereference
set name "ptype *pmf"
gdb_test_multiple "ptype *pmf" $name {
-re "Attempt to dereference pointer to member without an object\r\n$gdb_prompt $" {
pass $name
}
-re "Structure has no component named operator\\*.\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
# gcc 2.95.3 -gstabs+
# gcc 3.3.2 -gdwarf-2
# gcc 3.3.2 -gstabs+
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
# Call a function through a pmf.
set name "print (a.*pmf)(3)"
gdb_test_multiple "print (a.*pmf)(3)" $name {
-re "$vhn = 50\r\n$gdb_prompt $" {
pass $name
}
-re "Not implemented: function invocation through pointer to method with HP aCC\r\n$gdb_prompt $" {
# hpacc A.03.45
kfail "gdb/NNNN" $name
}
-re "Value can't be converted to integer.\r\n$gdb_prompt $" {
# gcc 2.95.3 -gdwarf-2
# gcc 2.95.3 -gstabs+
# gcc 3.3.2 -gdwarf-2
# gcc 3.3.2 -gstabs+
# gcc HEAD 2004-01-10 -gdwarf-2
# gcc HEAD 2004-01-10 -gstabs+
kfail "gdb/NNNN" $name
}
}
gdb_test "ptype a.*pmf" "type = int \\(A \\*, int\\)"
# Print out a pointer to data member which requires looking into
# a base class.
gdb_test "print diamond_pmi" "$vhn = &Base::x"
gdb_test "print diamond.*diamond_pmi" "$vhn = 77"
# Examine some more complicated pmfs, which require adjusting "this"
# and looking through virtual tables.
# These two have a different object adjustment, but call the same method.
gdb_test "print diamond.*left_pmf" \
"$vhn = {int \\(Diamond \\*\\)} $hex <Base::get_x\\((void|)\\)>"
gdb_test "print diamond.*right_pmf" \
"$vhn = {int \\(Diamond \\*\\)} $hex <Base::get_x\\((void|)\\)>"
gdb_test "print (diamond.*left_pmf) ()" "$vhn = 77"
gdb_test "print (diamond.*right_pmf) ()" "$vhn = 88"
# These two point to different methods, although they have the same
# virtual table offsets.
gdb_test "print diamond.*left_vpmf" \
"$vhn = {int \\(Diamond \\*\\)} $hex <Left::vget\\((void|)\\)>"
gdb_test "print diamond.*right_vpmf" \
"$vhn = {int \\(Diamond \\*\\)} $hex <Right::vget\\((void|)\\)>"
gdb_test "print (diamond.*left_vpmf) ()" "$vhn = 177"
gdb_test "print (diamond.*left_base_vpmf) ()" "$vhn = 2077"
gdb_test "print (diamond.*right_vpmf) ()" "$vhn = 288"
# We should be able to figure out left_vpmf even without an object,
# because it comes from a non-virtual base. The same for right_vpmf.
gdb_test "print left_vpmf" "$vhn = &virtual Left::vget\\(\\)"
gdb_test "print right_vpmf" "$vhn = &virtual Right::vget\\(\\)"
# But we should gracefully fail to figure out base_vpmf, because
# its runtime type is more derived than its static type. This
# is a valid but unspecified cast (it is value preserving, i.e.
# can be casted back to the correct type and used).
gdb_test "print base_vpmf" \
"$vhn = &virtual table offset \[0-9\]*, this adjustment -\[0-9\]*"
# Make sure we parse this correctly; it's invalid.
gdb_test "print diamond.*left_vpmf ()" \
"Invalid data type for function to be called\\."
# NULL pointer to member tests.
gdb_test "print null_pmi" "$vhn = NULL"
gdb_test "print null_pmi = &A::j" "$vhn = &A::j"
gdb_test "print null_pmi = 0" "$vhn = NULL"
gdb_test "print null_pmf" "$vhn = NULL"
gdb_test "print null_pmf = &A::foo" "$vhn = \\(int \\(A::\\*\\)\\(A \\*, int\\)\\) $hex <A::foo ?\\(int\\)>"
gdb_test "print null_pmf = 0" "$vhn = NULL"