2003-12-31 Michael Chastain <mec.gnu@mindspring.com>
authorMichael Chastain <mec@google.com>
Thu, 1 Jan 2004 02:30:59 +0000 (02:30 +0000)
committerMichael Chastain <mec@google.com>
Thu, 1 Jan 2004 02:30:59 +0000 (02:30 +0000)
* gdb.cp/virtfunc.exp: Rewrite.  Clean up patterns to match
current versions of gcc, including gcc abi 2.  Use "breakpoint"
and "continue" instead of restarting the target program.  Use
gdb_test_multiple and gdb_test for all tests.

gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/virtfunc.exp

index 38d0164..b28aef1 100644 (file)
@@ -1,3 +1,10 @@
+2003-12-31  Michael Chastain  <mec.gnu@mindspring.com>
+
+       * gdb.cp/virtfunc.exp: Rewrite.  Clean up patterns to match
+       current versions of gcc, including gcc abi 2.  Use "breakpoint"
+       and "continue" instead of restarting the target program.  Use
+       gdb_test_multiple and gdb_test for all tests.
+
 2004-01-01  Mark Kettenis  <kettenis@gnu.org>
 
        * gdb.asm/asm-source.exp: Update copyright year.  Link statically
index ff36c27..0f90adf 100644 (file)
 # bug-gdb@prep.ai.mit.edu
 
 # This file was written by Fred Fish. (fnf@cygnus.com)
+# And rewritten by Michael Chastain <mec.gnu@mindspring.com>.
 
 set ws "\[\r\n\t \]+"
 set nl "\[\r\n\]+"
 
 if $tracelevel then {
-       strace $tracelevel
+    strace $tracelevel
 }
 
 if { [skip_cplus_tests] } { continue }
@@ -33,855 +34,414 @@ set testfile "virtfunc"
 set srcfile ${testfile}.cc
 set binfile ${objdir}/${subdir}/${testfile}
 
-if [get_compiler_info ${binfile} "c++"] {
-    return -1
-}
-
-source ${binfile}.ci
-
 if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {c++ debug}] != "" } {
      gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
 }
 
-proc gdb_virtfunc_init {} {
-    global srcdir subdir binfile
-    global gdb_prompt
-
-    gdb_reinitialize_dir $srcdir/$subdir
-    gdb_load $binfile
-
-    send_gdb "set language c++\n"
-    gdb_expect -re "$gdb_prompt $"
-    send_gdb "set width 0\n"
-    gdb_expect -re "$gdb_prompt $"
-}
-
-proc gdb_virtfunc_restart {} {
-    gdb_exit;
-    gdb_start;
-    gdb_virtfunc_init;
-    runto 'test_calls';
-}
-
+# Test ptype of class objects.
+#
+# Different C++ compilers produce different output.  I build up regular
+# expressions piece by piece to accommodate all the compilers that I
+# have seen: gcc 2.95.3, gcc 3.3.2 (ABI 1), gcc 3.4 prerelease (ABI 2);
+# and all the debug formats I have seen: dwarf-2 and stabs+.
+#
+# A complicated class declaration looks like this:
+#
+#   class A : public virtual V {       // re_class
+#     private:
+#       V * _vb$V;                     // re_vbptr
+#       int a;                         // re_fields
+#
+#     public:
+#       A & operator=(A const &);      // re_synth_gcc_2
+#       A(int, A const &);             // ...
+#       A(int);                                // ...
+#       virtual int f(void);           // re_methods
+#   }
+#
+# RE_CLASS matches the class declaration.  C++ allows multiple ways of
+# expressing this.
+#
+#   struct ... { private: ... };
+#   class ... { private: ... };
+#   class ... { ... };
+#
+# RE_VBPTR matches the virtual base declarations.  gcc 2.95.3 emits
+# these, but gcc 3.X.Y does not.  The name depends on the debug format.
 #
-#  Test printing of the types of various classes.
+# RE_FIELDS matches the data fields of the class.
+# RE_METHODS matches the methods explicitly declared for the class.
 #
+# RE_SYNTH_GCC_2 and RE_SYNTH_GCC_3 match the optional synthetic methods
+# of the class.  gcc -gstabs+ emits these methods, and gcc -gdwarf-2
+# does not.
+#
+# RE_ALL_METHODS combines RE_METHODS and the optional synthetic methods.
+# Up to gcc 3.3.X, gcc defaults to gcc ABI 1, with synthetic methods at
+# the beginning.  Starting with gcc 3.4.X, gcc defaults to gcc ABI 2,
+# with synthetic methods at the end.
+#
+# So the possible choices for RE_ALL_METHODS are:
+#
+#   RE_METHODS                 // any gcc with dwarf-2
+#   RE_SYNTH_GCC_2|RE_METHODS  // gcc 2.95.3, stabs+
+#   RE_SYNTH_GCC_3|RE_METHODS  // gcc 3.3.2, stabs+
+#   RE_METHODS|RE_SYNTH_GCC_3  // gcc 3.4.0, stabs+
+#
+# When I get HP-UX aCC, I hope that I can just add RE_SYNTH_ACC_FOO
+# and enlarge RE_ALL_METHODS.
+#
+# Yet another twist: with gcc v2, ctor and dtor methods have a hidden
+# argument in front, the "in-charge" flag.  With gcc v3, there is no
+# hidden argument; instead, there are multiple object functions for
+# each ctor and dtor.
+#
+# I use gdb_test_multiple with only one arm.  I could use gdb_test,
+# but gdb_test_multiple makes it easier to add KFAIL arms as needed.
+#
+# -- chastain 2003-12-31
 
 proc test_ptype_of_classes {} {
     global gdb_prompt
     global ws
     global nl
 
-    # This used to be a fail if it printed "struct" not "class".  But
-    # since this struct doesn't use any special C++ features, it is
-    # considered right for GDB to print it as "struct".
-    send_gdb "ptype VA\n"
-    gdb_expect {
-       -re "type = (struct|class) VA \{(${ws}public:|)${ws}int va;${ws}VA & operator=\\(VA const ?&\\);${ws}VA\\((VA const|const VA) ?&\\);${ws}VA\\((void|)\\);${ws}\}.*$gdb_prompt $" {
+    # class VA
+
+    set re_class       "((struct|class) VA \{${ws}public:|struct VA \{)"
+    set re_fields      "int va;"
+    set re_synth_gcc_23        "VA & operator=\\(VA const ?&\\);${ws}VA\\(VA const ?&\\);${ws}VA\\((void|)\\);"
+    set re_all_methods "(|$re_synth_gcc_23)"
+
+    gdb_test_multiple "ptype VA" "ptype VA" {
+       -re "type = $re_class${ws}$re_fields${ws}(public:${ws}|)$re_all_methods$nl\}$nl$gdb_prompt $" {
            pass "ptype VA"
        }
-       -re "type = (struct|class) VA \{(${ws}public:|)${ws}int va;((${ws}VA & operator=\\(VA const ?&\\);)|(${ws}VA\\(VA const ?&\\);)|(${ws}VA\\((void|)\\);))*${ws}\}.*$gdb_prompt $" {
-           pass "ptype VA (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype VA"
-       }
-       timeout {
-           fail "ptype VA (timeout)"
-       }
     }
 
-    send_gdb "ptype VB\n"
-    gdb_expect {
-       -re "type = class VB \{${ws}public:${ws}int vb;${ws}VB & operator=\\(VB const ?&\\);${ws}VB\\((VB const|const VB) ?&\\);${ws}VB\\((void|)\\);${ws}int fvb\\((void|)\\);${ws}virtual int vvb\\((void|)\\);${ws}\}.*$gdb_prompt $" {
+    # class VB
+
+    set re_class       "((struct|class) VB \{${ws}public:|struct VB \{)"
+    set re_fields      "int vb;"
+    set re_methods     "int fvb\\((void|)\\);${ws}virtual int vvb\\((void|)\\);"
+    set re_synth_gcc_23        "VB & operator=\\(VB const ?&\\);${ws}VB\\(VB const ?&\\);${ws}VB\\((void|)\\);"
+    set re_all_methods "($re_methods|$re_methods${ws}$re_synth_gcc_23|$re_synth_gcc_23${ws}$re_methods)"
+
+    gdb_test_multiple "ptype VB" "ptype VB" {
+       -re "type = $re_class${ws}$re_fields${ws}(public:${ws}|)$re_all_methods$nl\}$nl$gdb_prompt $" {
            pass "ptype VB"
        }
-       -re "type = class VB \{${ws}public:${ws}int vb;${ws}int fvb \\((void|)\\);${ws}virtual int vvb \\((void|)\\);${ws}\}.*$gdb_prompt $" {
-           pass "ptype VB (aCC)"
-       }
-       -re "type = class VB \{${ws}public:${ws}int vb;((${ws}VB & operator=\\(VB const ?&\\);)|(${ws}VB\\(VB const ?&\\);)|(${ws}VB\\((void|)\\);)|(${ws}int fvb\\((void|)\\);)|(${ws}virtual int vvb\\((void|)\\);))*${ws}\}.*$gdb_prompt $" {
-           pass "ptype VB (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype VB"
-       }
-       timeout {
-           fail "ptype VB (timeout)"
-       }
     }
 
-    send_gdb "ptype V\n"
-    gdb_expect {
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}V & operator=\\(V const ?&\\);${ws}V\\((V const|const V) ?&\\);${ws}V\\((void|)\\);${ws}int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype V"
-       }
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}int f \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype V (aCC)"
-       }
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;((${ws}V & operator=\\(V const ?&\\);)|(${ws}V\\(V const ?&\\);)|(${ws}V\\((void|)\\);)|(${ws}int f\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype V (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype V"
-       }
-       timeout {
-           fail "ptype V (timeout)"
+    # An instance of VB
+
+    gdb_test_multiple "ptype vb" "ptype vb" {
+       -re "type = $re_class${ws}$re_fields${ws}(public:${ws}|)$re_all_methods$nl\}$nl$gdb_prompt $" {
+           pass "ptype vb"
        }
     }
 
-    # The format of a g++ virtual base pointer.
-    set vbptr "(_vb\[$.\]|__vb_)\[0-9\]?"
+    # An instance of VB *
 
-    send_gdb "ptype A\n"
-    gdb_expect {
-       -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\(int, A const ?&\\);${ws}A\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype A"
-       }
-       -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\((A const|const A) ?&\\);${ws}A\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype A"
-       }
-        -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-            pass "ptype A (aCC)"
-        }
-       -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:((${ws}A & operator=\\(A const ?&\\);)|(${ws}A\\(int, A const ?&\\);)|(${ws}A\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype A (obsolescent gcc or gdb)"
-       }
-       -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}FOO;${ws}int a;${ws}public:${ws}virtual int f.void.;${ws}\}$nl$gdb_prompt $" {
-           # This happens because the type is defined only after it is
-           # too late.
-           fail "ptype A (known failure with gcc cygnus-2.4.5-930417)"
-           # Many of the rest of these tests have the same problem.
-           return 0
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype A"
-       }
-       timeout {
-           fail "ptype A (timeout)"
+    gdb_test_multiple "ptype pVB" "ptype pVB" {
+       -re "type = $re_class${ws}$re_fields${ws}(public:${ws}|)$re_all_methods$nl\} \\*$nl$gdb_prompt $" {
+           pass "ptype pVB"
        }
     }
 
-    send_gdb "ptype B\n"
-    gdb_expect {
-       -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}B & operator=\\(B const ?&\\);${ws}B\\(int, B const ?&\\);${ws}B\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype B"
-       }
-       -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}B & operator=\\(B const ?&\\);${ws}B\\((B const|const B) ?&\\);${ws}B\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype B"
-       }
-       -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}virtual int f \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype B (aCC)"
-       }
-       -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:((${ws}B & operator=\\(B const ?&\\);)|(${ws}B\\(int, B const ?&\\);)|(${ws}B\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype B (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype B"
-       }
-       timeout {
-           fail "ptype B (timeout)"
-       }
-    }
+    # class V
 
-    send_gdb "ptype C\n"
-    gdb_expect {
-       -re "type = class C : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int c;${ws}C & operator=\\(C const ?&\\);${ws}C\\(int, C const ?&\\);${ws}C\\(int\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype C"
-       }
-       -re "type = class C : public virtual V \{${ws}public:${ws}int c;${ws}C & operator=\\(C const ?&\\);${ws}C\\((C const|const C) ?&\\);${ws}C\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype C"
-       }
-        -re "type = class C : public virtual V \{${ws}public:${ws}int c;${ws}\}$nl$gdb_prompt $" {
-            pass "ptype C (aCC)"
-        }
-       -re "type = class C : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int c;((${ws}C & operator=\\(C const ?&\\);)|(${ws}C\\(int, C const ?&\\);)|(${ws}C\\(int\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype C (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype C"
-       }
-       timeout {
-           fail "ptype C (timeout)"
-       }
-    }
+    set re_class       "class V : public VA, public VB \{${ws}public:"
+    set re_fields      "int w;"
+    set re_methods     "int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);"
+    set re_synth_gcc_23        "V & operator=\\(V const ?&\\);${ws}V\\(V const ?&\\);${ws}V\\((void|)\\);"
+    set re_all_methods "($re_methods|$re_methods${ws}$re_synth_gcc_23|$re_synth_gcc_23${ws}$re_methods)"
 
-    send_gdb "ptype AD\n"
-    gdb_expect {
-       -re "type = class AD \{${ws}public:${ws}AD & operator=\\(AD const ?&\\);${ws}AD\\((AD const|const AD) ?&\\);${ws}AD\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype AD"
-       }
-       -re "type = class AD \{${ws}public:${ws}virtual int vg \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype AD (aCC)"
-       }
-       -re "type = class AD \{${ws}public:((${ws}AD & operator=\\(AD const ?&\\);)|(${ws}AD\\(AD const ?&\\);)|(${ws}AD\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype AD (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype AD"
-       }
-       timeout {
-           fail "ptype AD (timeout)"
+    gdb_test_multiple "ptype V" "ptype V" {
+       -re "type = $re_class${ws}$re_fields${ws}(public:${ws}|)$re_all_methods$nl\}$nl$gdb_prompt $" {
+           pass "ptype V"
        }
     }
 
-    send_gdb "ptype D\n"
-    gdb_expect {
-       -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype D"
-       }
-       -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype D"
-       }
-        -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-            pass "ptype D (aCC)"
-        }
-       -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(int, D const ?&\\);)|(${ws}D\\(int\\);)|(${ws}static void s\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vd\\((void|)\\);)|(${ws}int fd\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype D (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype D"
-       }
-       timeout {
-           fail "ptype D (timeout)"
-       }
-    }
+    # An instance of V
 
-    send_gdb "ptype E\n"
-    gdb_expect {
-       -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}E & operator=\\(E const ?&\\);${ws}E\\(int, E const ?&\\);${ws}E\\(int\\);${ws}virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype E"
-       }
-       -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}E & operator=\\(E const ?&\\);${ws}E\\((E const|const E) ?&\\);${ws}E\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype E"
-       }
-       -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}virtual int f \\((void|)\\);${ws}virtual int vg \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype E (aCC)"
-       }
-       -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;((${ws}E & operator=\\(E const ?&\\);)|(${ws}E\\(int, E const ?&\\);)|(${ws}E\\(int\\);)|(${ws}virtual int f\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype E (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype E"
-       }
-       timeout {
-           fail "ptype E (timeout)"
+    gdb_test_multiple "ptype v" "ptype v" {
+       -re "type = $re_class${ws}$re_fields${ws}(public:${ws}|)$re_all_methods$nl\}$nl$gdb_prompt $" {
+           pass "ptype v"
        }
     }
 
-    send_gdb "ptype dd\n"
-    gdb_expect {
-       -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype dd"
-       }
-       -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype dd"
-       }
-        -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-            pass "ptype dd (aCC)"
-        }
-       -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(int, D const ?&\\);)|(${ws}D\\(int\\);)|(${ws}static void s\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vd\\((void|)\\);)|(${ws}int fd\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype dd (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype dd"
-       }
-       timeout {
-           fail "ptype dd (timeout)"
-       }
-    }
+    # An instance of V *
 
-    send_gdb "ptype ppd\n"
-    gdb_expect {
-       -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype ppd"
-       }
-       -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype ppd"
-       }
-        -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-            pass "ptype ppd (aCC)"
-        }
-       -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(int, D const ?&\\);)|(${ws}D\\(int\\);)|(${ws}static void s\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vd\\((void|)\\);)|(${ws}int fd\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype ppd (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype ppd"
-       }
-       timeout {
-           fail "ptype ppd (timeout)"
+    gdb_test_multiple "ptype pVa" "ptype pVa" {
+       -re "type = $re_class${ws}$re_fields${ws}(public:${ws}|)$re_all_methods$nl\} \\*$nl$gdb_prompt $" {
+           pass "ptype pVa"
        }
     }
 
-    send_gdb "ptype pAd\n"
-    gdb_expect {
-       -re "type = class AD \{${ws}public:${ws}AD & operator=\\(AD const ?&\\);${ws}AD\\((AD const|const AD) ?&\\);${ws}AD\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pAd"
-       }
-       -re "type = class AD \{${ws}public:${ws}virtual int vg \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pAd (aCC)"
-       }
-       -re "type = class AD \{${ws}public:((${ws}AD & operator=\\(AD const ?&\\);)|(${ws}AD\\(AD const ?&\\);)|(${ws}AD\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pAd (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pAd"
-       }
-       timeout {
-           fail "ptype pAd (timeout)"
-       }
-    }
+    # An instance of V *
 
-    send_gdb "ptype a\n"
-    gdb_expect {
-       -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\(int, A const ?&\\);${ws}A\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype a"
-       }
-       -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\((A const|const A) ?&\\);${ws}A\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype a"
-       }
-        -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-            pass "ptype a (aCC)"
-        }
-       -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:((${ws}A & operator=\\(A const ?&\\);)|(${ws}A\\(int, A const ?&\\);)|(${ws}A\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype a (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype a"
-       }
-       timeout {
-           fail "ptype a (timeout)"
+    gdb_test_multiple "ptype pVv" "ptype pVv" {
+       -re "type = $re_class${ws}$re_fields${ws}(public:${ws}|)$re_all_methods$nl\} \\*$nl$gdb_prompt $" {
+           pass "ptype pVv"
        }
     }
 
-    send_gdb "ptype b\n"
-    gdb_expect {
-       -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}B & operator=\\(B const ?&\\);${ws}B\\(int, B const ?&\\);${ws}B\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype b"
-       }
-       -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}B & operator=\\(B const ?&\\);${ws}B\\((B const|const B) ?&\\);${ws}B\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype b"
-       }
-       -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}virtual int f \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype b (aCC)"
-       }
-       -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:((${ws}B & operator=\\(B const ?&\\);)|(${ws}B\\(int, B const ?&\\);)|(${ws}B\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype b (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype b"
-       }
-       timeout {
-           fail "ptype b (timeout)"
-       }
-    }
+    # An instance of V *
 
-    send_gdb "ptype c\n"
-    gdb_expect {
-       -re "type = class C : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int c;${ws}C & operator=\\(C const ?&\\);${ws}C\\(int, C const ?&\\);${ws}C\\(int\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype c"
-       }
-       -re "type = class C : public virtual V \{${ws}public:${ws}int c;${ws}C & operator=\\(C const ?&\\);${ws}C\\((C const|const C) ?&\\);${ws}C\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype c"
-       }
-        -re "type = class C : public virtual V \{${ws}public:${ws}int c;${ws}\}$nl$gdb_prompt $" {
-            pass "ptype c (aCC)"
-        }
-       -re "type = class C : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int c;((${ws}C & operator=\\(C const ?&\\);)|(${ws}C\\(int, C const ?&\\);)|(${ws}C\\(int\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype c (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype c"
-       }
-       timeout {
-           fail "ptype c (timeout)"
+    gdb_test_multiple "ptype pVe" "ptype pVe" {
+       -re "type = $re_class${ws}$re_fields${ws}(public:${ws}|)$re_all_methods$nl\} \\*$nl$gdb_prompt $" {
+           pass "ptype pVe"
        }
     }
 
-    send_gdb "ptype d\n"
-    gdb_expect {
-       -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype d"
-       }
-       -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype d"
-       }
-        -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-            pass "ptype d (aCC)"
-        }
-       -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(int, D const ?&\\);)|(${ws}D\\(int\\);)|(${ws}static void s\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vd\\((void|)\\);)|(${ws}int fd\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype d (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype d"
-       }
-       timeout {
-           fail "ptype d (timeout)"
-       }
-    }
+    # An instance of V *
 
-    send_gdb "ptype e\n"
-    gdb_expect {
-       -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}E & operator=\\(E const ?&\\);${ws}E\\(int, E const ?&\\);${ws}E\\(int\\);${ws}virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype e"
-       }
-       -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}E & operator=\\(E const ?&\\);${ws}E\\((E const|const E) ?&\\);${ws}E\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype e"
-       }
-       -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}virtual int f \\((void|)\\);${ws}virtual int vg \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype e (aCC)"
-       }
-       -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;((${ws}E & operator=\\(E const ?&\\);)|(${ws}E\\(int, E const ?&\\);)|(${ws}E\\(int\\);)|(${ws}virtual int f\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype e (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype e"
-       }
-       timeout {
-           fail "ptype e (timeout)"
+    gdb_test_multiple "ptype pVd" "ptype pVd" {
+       -re "type = $re_class${ws}$re_fields${ws}(public:${ws}|)$re_all_methods$nl\} \\*$nl$gdb_prompt $" {
+           pass "ptype pVd"
        }
     }
 
-    send_gdb "ptype v\n"
-    gdb_expect {
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}V & operator=\\(V const ?&\\);${ws}V\\((V const|const V) ?&\\);${ws}V\\((void|)\\);${ws}int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype v"
-       }
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}int f \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype v (aCC)"
-       }
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;((${ws}V & operator=\\(V const ?&\\);)|(${ws}V\\(V const ?&\\);)|(${ws}V\\((void|)\\);)|(${ws}int f\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype v (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype v"
-       }
-       timeout {
-           fail "ptype v (timeout)"
+    # class A
+
+    set re_class       "class A : public virtual V \{(${ws}private:|)"
+    set re_vbptr       "V \\*(_vb.1V|_vb.V);"
+    set re_fields      "int a;"
+    set re_methods     "virtual int f\\((void|)\\);"
+    # gcc 2 adds an "in-charge" arg to the ctor.
+    set re_synth_gcc_2 "A & operator=\\(A const ?&\\);${ws}A\\(int, A const ?&\\);${ws}A\\(int\\);"
+    set re_synth_gcc_3 "A & operator=\\(A const ?&\\);${ws}A\\(A const ?&\\);${ws}A\\(\\);"
+    set re_all_methods "($re_methods|$re_synth_gcc_2${ws}$re_methods|$re_synth_gcc_3${ws}$re_methods|$re_methods${ws}$re_synth_gcc_3)"
+
+    gdb_test_multiple "ptype A" "ptype A" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)${re_fields}${ws}public:${ws}${re_all_methods}$nl\}$nl$gdb_prompt $" {
+           pass "ptype A"
        }
     }
 
-    send_gdb "ptype vb\n"
-    gdb_expect {
-       -re "type = class VB \{${ws}public:${ws}int vb;${ws}VB & operator=\\(VB const ?&\\);${ws}VB\\((VB const|const VB) ?&\\);${ws}VB\\((void|)\\);${ws}int fvb\\((void|)\\);${ws}virtual int vvb\\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype vb"
-       }
-       -re "type = class VB \{${ws}public:${ws}int vb;${ws}int fvb \\((void|)\\);${ws}virtual int vvb \\((void|)\\);${ws}\}$nl$gdb_prompt $" {
-           pass "ptype vb (aCC)"
-       }
-       -re "type = class VB \{${ws}public:${ws}int vb;((${ws}VB & operator=\\(VB const ?&\\);)|(${ws}VB\\(VB const ?&\\);)|(${ws}VB\\((void|)\\);)|(${ws}int fvb\\((void|)\\);)|(${ws}virtual int vvb\\((void|)\\);))*${ws}\}$nl$gdb_prompt $" {
-           pass "ptype vb (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype vb"
-       }
-       timeout {
-           fail "ptype vb (timeout)"
+    # An instance of A
+
+    gdb_test_multiple "ptype a" "ptype a" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)${re_fields}${ws}public:${ws}${re_all_methods}$nl\}$nl$gdb_prompt $" {
+           pass "ptype a"
        }
     }
 
-    send_gdb "ptype pAa\n"
-    gdb_expect {
-       -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\(int, A const ?&\\);${ws}A\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pAa"
-       }
-       -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\((A const|const A) ?&\\);${ws}A\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+    # An instance of A *
+
+    gdb_test_multiple "ptype pAa" "ptype pAa" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)${re_fields}${ws}public:${ws}${re_all_methods}$nl\} \\*$nl$gdb_prompt $" {
            pass "ptype pAa"
        }
-        -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-            pass "ptype pAa (aCC)"
-        }
-       -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:((${ws}A & operator=\\(A const ?&\\);)|(${ws}A\\(int, A const ?&\\);)|(${ws}A\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pAa (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pAa"
-       }
-       timeout {
-           fail "ptype pAa (timeout)"
-       }
     }
 
-    send_gdb "ptype pAe\n"
-    gdb_expect {
-       -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\(int, A const ?&\\);${ws}A\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pAe"
-       }
-       -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}A & operator=\\(A const ?&\\);${ws}A\\((A const|const A) ?&\\);${ws}A\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
+    # An instance of A *
+
+    gdb_test_multiple "ptype pAe" "ptype pAe" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)${re_fields}${ws}public:${ws}${re_all_methods}$nl\} \\*$nl$gdb_prompt $" {
            pass "ptype pAe"
        }
-        -re "type = class A : public virtual V \{${ws}private:${ws}int a;${ws}public:${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-            pass "ptype pAe (aCC)"
-       }
-       -re "type = class A : public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}int a;${ws}public:((${ws}A & operator=\\(A const ?&\\);)|(${ws}A\\(int, A const ?&\\);)|(${ws}A\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pAe (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pAe"
-       }
-       timeout {
-           fail "ptype pAe (timeout)"
-       }
     }
 
-    send_gdb "ptype pBe\n"
-    gdb_expect {
-       -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}B & operator=\\(B const ?&\\);${ws}B\\(int, B const ?&\\);${ws}B\\(int\\);${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pBe"
-       }
-       -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}B & operator=\\(B const ?&\\);${ws}B\\((B const|const B) ?&\\);${ws}B\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pBe"
-       }
-       -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:${ws}virtual int f \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pBe (aCC)"
-       }
-       -re "type = class B : public A \{${ws}private:${ws}int b;${ws}public:((${ws}B & operator=\\(B const ?&\\);)|(${ws}B\\(int, B const ?&\\);)|(${ws}B\\(int\\);)|(${ws}virtual int f\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pBe (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pBe"
-       }
-       timeout {
-           fail "ptype pBe (timeout)"
-       }
-    }
+    # class B
 
-    send_gdb "ptype pDd\n"
-    gdb_expect {
-       -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pDd"
-       }
-       -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pDd"
-       }
-        -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-            pass "ptype pDd (aCC)"
-        }
-       -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(int, D const ?&\\);)|(${ws}D\\(int\\);)|(${ws}static void s\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vd\\((void|)\\);)|(${ws}int fd\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pDd (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pDd"
-       }
-       timeout {
-           fail "ptype pDd (timeout)"
-       }
-    }
+    set re_class       "class B : public A \{(${ws}private:|)"
+    set re_vbptr       "V \\*(_vb.1V|_vb.V);"
+    set re_fields      "int b;"
+    set re_methods     "virtual int f\\((void|)\\);"
+    set re_synth_gcc_2 "B & operator=\\(B const ?&\\);${ws}B\\(int, B const ?&\\);${ws}B\\(int\\);"
+    set re_synth_gcc_3 "B & operator=\\(B const ?&\\);${ws}B\\(B const ?&\\);${ws}B\\(\\);"
+    set re_all_methods "($re_methods|$re_synth_gcc_2${ws}$re_methods|$re_synth_gcc_3${ws}$re_methods|$re_methods${ws}$re_synth_gcc_3)"
 
-    send_gdb "ptype pDe\n"
-    gdb_expect {
-       -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pDe"
-       }
-       -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}D & operator=\\(D const ?&\\);${ws}D\\((D const|const D) ?&\\);${ws}D\\((void|)\\);${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pDe"
-       }
-        -re "type = class D : public AD, public virtual V \{${ws}public:${ws}int d;${ws}static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-            pass "ptype pDe (aCC)"
-        }
-       -re "type = class D : public AD, public virtual V \{${ws}private:${ws}V \\*${vbptr}V;${ws}public:${ws}int d;((${ws}D & operator=\\(D const ?&\\);)|(${ws}D\\(int, D const ?&\\);)|(${ws}D\\(int\\);)|(${ws}static void s\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vd\\((void|)\\);)|(${ws}int fd\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pDe (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pDe"
-       }
-       timeout {
-           fail "ptype pDe (timeout)"
+    gdb_test_multiple "ptype B" "ptype B" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)${re_fields}${ws}public:${ws}${re_all_methods}$nl\}$nl$gdb_prompt $" {
+           pass "ptype B"
        }
     }
 
-    send_gdb "ptype pVa\n"
-    gdb_expect {
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}V & operator=\\(V const ?&\\);${ws}V\\((V const|const V) ?&\\);${ws}V\\((void|)\\);${ws}int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVa"
-       }
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}int f \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVa (aCC)"
-       }
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;((${ws}V & operator=\\(V const ?&\\);)|(${ws}V\\(V const ?&\\);)|(${ws}V\\((void|)\\);)|(${ws}int f\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVa (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pVa"
-       }
-       timeout {
-           fail "ptype pVa (timeout)"
+    # An instance of B
+
+    gdb_test_multiple "ptype b" "ptype b" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)${re_fields}${ws}public:${ws}${re_all_methods}$nl\}$nl$gdb_prompt $" {
+           pass "ptype b"
        }
     }
 
-    send_gdb "ptype pVv\n"
-    gdb_expect {
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}V & operator=\\(V const ?&\\);${ws}V\\((V const|const V) ?&\\);${ws}V\\((void|)\\);${ws}int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVv"
-       }
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}int f \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVv (aCC)"
-       }
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;((${ws}V & operator=\\(V const ?&\\);)|(${ws}V\\(V const ?&\\);)|(${ws}V\\((void|)\\);)|(${ws}int f\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVv (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pVv"
-       }
-       timeout {
-           fail "ptype pVv (timeout)"
+    # An instance of B *
+
+    gdb_test_multiple "ptype pBe" "ptype pBe" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)${re_fields}${ws}public:${ws}${re_all_methods}$nl\} \\*$nl$gdb_prompt $" {
+           pass "ptype pBe"
        }
     }
 
-    send_gdb "ptype pVe\n"
-    gdb_expect {
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}V & operator=\\(V const ?&\\);${ws}V\\((V const|const V) ?&\\);${ws}V\\((void|)\\);${ws}int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVe"
-       }
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}int f \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVe (aCC)"
-       }
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;((${ws}V & operator=\\(V const ?&\\);)|(${ws}V\\(V const ?&\\);)|(${ws}V\\((void|)\\);)|(${ws}int f\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVe (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pVe"
-       }
-       timeout {
-           fail "ptype pVe (timeout)"
+    # class C
+
+    set re_class       "class C : public virtual V \{(${ws}private:|)"
+    set re_vbptr       "V \\*(_vb.1V|_vb.V);"
+    set re_fields      "int c;"
+    set re_synth_gcc_2 "C & operator=\\(C const ?&\\);${ws}C\\(int, C const ?&\\);${ws}C\\(int\\);"
+    set re_synth_gcc_3 "C & operator=\\(C const ?&\\);${ws}C\\(C const ?&\\);${ws}C\\(\\);"
+    set re_all_methods "(|$re_synth_gcc_2|$re_synth_gcc_3)"
+
+    gdb_test_multiple "ptype C" "ptype C" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)public:${ws}${re_fields}${ws}(public:${ws}|)${re_all_methods}$nl\}$nl$gdb_prompt $" {
+           pass "ptype C"
        }
     }
 
-    send_gdb "ptype pVd\n"
-    gdb_expect {
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}V & operator=\\(V const ?&\\);${ws}V\\((V const|const V) ?&\\);${ws}V\\((void|)\\);${ws}int f\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVd"
-       }
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;${ws}int f \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVd (aCC)"
-       }
-       -re "type = class V : public VA, public VB \{${ws}public:${ws}int w;((${ws}V & operator=\\(V const ?&\\);)|(${ws}V\\(V const ?&\\);)|(${ws}V\\((void|)\\);)|(${ws}int f\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVd (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pVd"
-       }
-       timeout {
-           fail "ptype pVd (timeout)"
+    # An instance of C
+
+    gdb_test_multiple "ptype c" "ptype c" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)public:${ws}${re_fields}${ws}(public:${ws}|)${re_all_methods}$nl\}$nl$gdb_prompt $" {
+           pass "ptype c"
        }
     }
 
-    send_gdb "ptype pADe\n"
-    gdb_expect {
-       -re "type = class AD \{${ws}public:${ws}AD & operator=\\(AD const ?&\\);${ws}AD\\((AD const|const AD) ?&\\);${ws}AD\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pADe"
-       }
-       -re "type = class AD \{${ws}public:${ws}virtual int vg \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pADe (aCC)"
-       }
-       -re "type = class AD \{${ws}public:((${ws}AD & operator=\\(AD const ?&\\);)|(${ws}AD\\(AD const ?&\\);)|(${ws}AD\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pADe (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pADe"
-       }
-       timeout {
-           fail "ptype pADe (timeout)"
+    # class AD
+
+    set re_class       "((struct|class) AD \{${ws}public:|struct AD \{)"
+    set re_methods     "virtual int vg\\((void|)\\);"
+    set re_synth_gcc_23        "AD & operator=\\(AD const ?&\\);${ws}AD\\(AD const ?&\\);${ws}AD\\((void|)\\);"
+    set re_all_methods "($re_methods|$re_methods${ws}$re_synth_gcc_23|$re_synth_gcc_23${ws}$re_methods)"
+
+    gdb_test_multiple "ptype AD" "ptype AD" {
+       -re "type = $re_class${ws}$re_all_methods$nl\}$nl$gdb_prompt $" {
+           pass "ptype AD"
        }
     }
 
-    send_gdb "ptype pEe\n"
-    gdb_expect {
-       -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}E & operator=\\(E const ?&\\);${ws}E\\(int, E const ?&\\);${ws}E\\(int\\);${ws}virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pEe"
-       }
-       -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}E & operator=\\(E const ?&\\);${ws}E\\((E const|const E) ?&\\);${ws}E\\((void|)\\);${ws}virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pEe"
-       }
-       -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;${ws}virtual int f \\((void|)\\);${ws}virtual int vg \\((void|)\\);${ws}virtual int vv \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pEe (aCC)"
-       }
-       -re "type = class E : public B, public virtual V, public D, public C \{${ws}public:${ws}int e;((${ws}E & operator=\\(E const ?&\\);)|(${ws}E\\(int, E const ?&\\);)|(${ws}E\\(int\\);)|(${ws}virtual int f\\((void|)\\);)|(${ws}virtual int vg\\((void|)\\);)|(${ws}virtual int vv\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pEe (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pEe"
-       }
-       timeout {
-           fail "ptype pEe (timeout)"
+    # An instance of AD *
+    # TODO: this should be named pADd, not pAd.
+
+    gdb_test_multiple "ptype pAd" "ptype pAd" {
+       -re "type = $re_class${ws}$re_all_methods$nl\} \\*$nl$gdb_prompt $" {
+           pass "ptype pAd"
        }
     }
 
-    send_gdb "ptype pVB\n"
-    gdb_expect {
-       -re "type = class VB \{${ws}public:${ws}int vb;${ws}VB & operator=\\(VB const ?&\\);${ws}VB\\((VB const|const VB) ?&\\);${ws}VB\\((void|)\\);${ws}int fvb\\((void|)\\);${ws}virtual int vvb\\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVB"
-       }
-       -re "type = class VB \{${ws}public:${ws}int vb;${ws}int fvb \\((void|)\\);${ws}virtual int vvb \\((void|)\\);${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVB (aCC)"
-       }
-       -re "type = class VB \{${ws}public:${ws}int vb;((${ws}VB & operator=\\(VB const ?&\\);)|(${ws}VB\\(VB const ?&\\);)|(${ws}VB\\((void|)\\);)|(${ws}int fvb\\((void|)\\);)|(${ws}virtual int vvb\\((void|)\\);))*${ws}\} \[*\]+$nl$gdb_prompt $" {
-           pass "ptype pVB (obsolescent gcc or gdb)"
-       }
-       -re ".*$gdb_prompt $" {
-           fail "ptype pVB"
-       }
-       timeout {
-           fail "ptype pVB (timeout)"
+    # An instance of a AD *
+
+    gdb_test_multiple "ptype pADe" "ptype pADe" {
+       -re "type = $re_class${ws}$re_all_methods$nl\} \\*$nl$gdb_prompt $" {
+           pass "ptype pADe"
        }
     }
-}
 
-#
-#  Test calling of virtual functions.
-#
+    # class D
 
-proc test_virtual_calls {} {
-    global gdb_prompt
-    global GDB
-    global nl
+    set re_class       "class D : public AD, public virtual V \{(${ws}private:|)"
+    set re_vbptr       "V \\*(_vb.1V|_vb.V);"
+    set re_fields      "int d;"
+    set re_methods     "static void s\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vd\\((void|)\\);${ws}int fd\\((void|)\\);"
+    set re_synth_gcc_2 "D & operator=\\(D const ?&\\);${ws}D\\(int, D const ?&\\);${ws}D\\(int\\);"
+    set re_synth_gcc_3 "D & operator=\\(D const ?&\\);${ws}D\\(D const ?&\\);${ws}D\\(\\);"
+    set re_all_methods "($re_methods|$re_synth_gcc_2${ws}$re_methods|$re_synth_gcc_3${ws}$re_methods|$re_methods${ws}$re_synth_gcc_3)"
 
-    if [target_info exists gdb,cannot_call_functions] {
-       setup_xfail "*-*-*" 2416
-       fail "This target can not call functions"
-       return 0
-    }
-
-    send_gdb "print pAe->f()\n"
-    gdb_expect {
-       -re ".* = 20$nl$gdb_prompt $" { pass "print pAe->f()" }
-       -re "Cannot invoke functions on this machine.*$gdb_prompt $" {
-           fail "print pAe->f() (cannot invoke functions, skipping virtual calls)"
-           return 0
-       }
-       -re ".*Cannot access memory at address 0x8.*$gdb_prompt $" {
-           fail "print pAe->f() \
-(known failure with gcc cygnus-2.4.5-930417, skipping virtual calls)"
-           return 0
-       }
-        -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
-           setup_xfail hppa*-*-* CLLbs16899
-            fail "print pAe->f()"
+    gdb_test_multiple "ptype D" "ptype D" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)public:${ws}${re_fields}${ws}${re_all_methods}$nl\}$nl$gdb_prompt $" {
+           pass "ptype D"
        }
-       -re ".*$gdb_prompt $" { fail "print pAe->f()" }
-       timeout { fail "print pAe->f() (timeout)" }
-       eof { fail "print pAe->f() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
     }
 
-    send_gdb "print pAa->f()\n"
-    gdb_expect {
-       -re ".* = 1$nl$gdb_prompt $" { pass "print pAa->f()" }
-        -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
-           setup_xfail hppa*-*-*  CLLbs16899
-           fail "print pAa->f()"
-       }
-       -re ".*$gdb_prompt $" { fail "print pAa->f()" }
-       timeout { fail "print pAa->f() (timeout)" }
-       eof { fail "print pAa->f() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
-    }
+    # An instance of D
 
-    send_gdb "print pDe->vg()\n"
-    gdb_expect {
-       -re ".* = 202$nl$gdb_prompt $" { pass "print pDe->vg()" }
-        -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
-           setup_xfail hppa*-*-*  CLLbs16899
-           fail "print pDe->vg()"
+    gdb_test_multiple "ptype d" "ptype d" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)public:${ws}${re_fields}${ws}${re_all_methods}$nl\}$nl$gdb_prompt $" {
+           pass "ptype d"
        }
-       -re ".*$gdb_prompt $" { fail "print pDe->vg()" }
-       timeout { fail "print pDe->vg() (timeout)" }
-       eof { fail "print pDe->vg() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
     }
 
-    send_gdb "print pADe->vg()\n"
-    gdb_expect {
-       -re ".* = 202$nl$gdb_prompt $" { pass "print pADe->vg()" }
-        -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
-           setup_xfail hppa*-*-*  CLLbs16899
-           fail "print pADe->vg()"
+    # An instance of D
+
+    gdb_test_multiple "ptype dd" "ptype dd" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)public:${ws}${re_fields}${ws}${re_all_methods}$nl\}$nl$gdb_prompt $" {
+           pass "ptype dd"
        }
-       -re ".*$gdb_prompt $" { fail "print pADe->vg()" }
-       timeout { fail "print pADe->vg() (timeout)" }
-       eof { fail "print pADe->vg() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
     }
 
-    send_gdb "print pDd->vg()\n"
-    gdb_expect {
-       -re ".* = 101$nl$gdb_prompt $" { pass "print pDd->vg()" }
-        -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
-           setup_xfail hppa*-*-*  CLLbs16899
-           fail "print pDd->vg()"
+    # An instance of D *
+
+    gdb_test_multiple "ptype ppd" "ptype ppd" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)public:${ws}${re_fields}${ws}${re_all_methods}$nl\} \\*$nl$gdb_prompt $" {
+           pass "ptype ppd"
        }
-       -re ".*$gdb_prompt $" { fail "print pDd->vg()" }
-       timeout { fail "print pDd->vg() (timeout)" }
-       eof { fail "print pDd->vg() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
     }
 
-    send_gdb "print pEe->vvb()\n"
-    gdb_expect {
-       -re ".* = 411$nl$gdb_prompt $" { pass "print pEe->vvb()" }
-        -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
-           setup_xfail hppa*-*-*  CLLbs16899
-           fail "print pEe->vvb()"
+    # An instance of D *
+
+    gdb_test_multiple "ptype pDd" "ptype pDd" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)public:${ws}${re_fields}${ws}${re_all_methods}$nl\} \\*$nl$gdb_prompt $" {
+           pass "ptype pDd"
        }
-       -re ".*$gdb_prompt $" { fail "print pEe->vvb()" }
-       timeout { fail "print pEe->vvb() (timeout)" }
-       eof { fail "print pEe->vvb() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
     }
 
-    send_gdb "print pVB->vvb()\n"
-    gdb_expect {
-       -re ".* = 407$nl$gdb_prompt $" { pass "print pVB->vvb()" }
-        -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
-           setup_xfail hppa*-*-*  CLLbs16899
-           fail "print pVB->vvb()"
+    # An instance of D *
+
+    gdb_test_multiple "ptype pDe" "ptype pDe" {
+       -re "type = ${re_class}${ws}(${re_vbptr}${ws}|)public:${ws}${re_fields}${ws}${re_all_methods}$nl\} \\*$nl$gdb_prompt $" {
+           pass "ptype pDe"
        }
-       -re ".*$gdb_prompt $" { fail "print pVB->vvb()" }
-       timeout { fail "print pVB->vvb() (timeout)" }
-       eof { fail "print pVB->vvb() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
     }
 
-    send_gdb "print pBe->vvb()\n"
-    gdb_expect {
-       -re ".* = 411$nl$gdb_prompt $" { pass "print pBe->vvb()" }
-        -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
-           setup_xfail hppa*-*-*  CLLbs16899
-           fail "print pBe->vvb()"
+    # class E
+    # TODO: E does not show a vbptr for V.  That seems strange.
+
+    set re_class       "class E : public B, public virtual V, public D, public C \{(${ws}private:|)"
+    set re_fields      "int e;"
+    set re_methods     "virtual int f\\((void|)\\);${ws}virtual int vg\\((void|)\\);${ws}virtual int vv\\((void|)\\);"
+    set re_synth_gcc_2 "E & operator=\\(E const ?&\\);${ws}E\\(int, E const ?&\\);${ws}E\\(int\\);"
+    set re_synth_gcc_3 "E & operator=\\(E const ?&\\);${ws}E\\(E const ?&\\);${ws}E\\(\\);"
+    set re_all_methods "($re_methods|$re_synth_gcc_2${ws}$re_methods|$re_synth_gcc_3${ws}$re_methods|$re_methods${ws}$re_synth_gcc_3)"
+
+    gdb_test_multiple "ptype E" "ptype E" {
+       -re "type = ${re_class}${ws}public:${ws}${re_fields}${ws}${re_all_methods}$nl\}$nl$gdb_prompt $" {
+           pass "ptype E"
        }
-       -re ".*$gdb_prompt $" { fail "print pBe->vvb()" }
-       timeout { fail "print pBe->vvb() (timeout)" }
-       eof { fail "print pBe->vvb() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
     }
 
-    send_gdb "print pDe->vvb()\n"
-    gdb_expect {
-       -re ".* = 411$nl$gdb_prompt $" { pass "print pDe->vvb()" }
-        -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
-           setup_xfail hppa*-*-*  CLLbs16899
-           fail "print pDe->vvb()"
+    # An instance of E
+
+    gdb_test_multiple "ptype e" "ptype e" {
+       -re "type = ${re_class}${ws}public:${ws}${re_fields}${ws}${re_all_methods}$nl\}$nl$gdb_prompt $" {
+           pass "ptype e"
        }
-       -re ".*$gdb_prompt $" { fail "print pDe->vvb()" }
-       timeout { fail "print pDe->vvb() (timeout)" }
-       eof { fail "print pDe->vvb() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
     }
 
-    send_gdb "print pEe->vd()\n"
-    gdb_expect {
-       -re ".* = 282$nl$gdb_prompt $" { pass "print pEe->vd()" }
-        -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
-           setup_xfail hppa*-*-*  CLLbs16899
-           fail "print pEe->vd()"
+    # An instance of E *
+
+    gdb_test_multiple "ptype pEe" "ptype pEe" {
+       -re "type = ${re_class}${ws}public:${ws}${re_fields}${ws}${re_all_methods}$nl\} \\*$nl$gdb_prompt $" {
+           pass "ptype pEe"
        }
-       -re ".*$gdb_prompt $" { fail "print pEe->vd()" }
-       timeout { fail "print pEe->vd() (timeout)" }
-       eof { fail "print pEe->vd() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
     }
+}
 
-    send_gdb "print pEe->fvb()\n"
-    gdb_expect {
-       -re ".* = 311$nl$gdb_prompt $" { pass "print pEe->fvb()" }
-        -re "Cannot resolve .* to any overloaded instance.*$gdb_prompt $" {
-           setup_xfail hppa*-*-*  CLLbs16899
-           fail "print pEe->fvb()"
-       }
-       -re ".*$gdb_prompt $" { fail "print pEe->fvb()" }
-       timeout { fail "print pEe->fvb() (timeout)" }
-       eof { fail "print pEe->fvb() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+# Call virtual functions.
+
+proc test_virtual_calls {} {
+    global gdb_prompt
+    global nl
+
+    if [target_info exists gdb,cannot_call_functions] {
+       setup_xfail "*-*-*" 2416
+       fail "This target can not call functions"
+       return 0
     }
 
+    gdb_test "print pAe->f()"   "\\$\[0-9\]+ = 20"
+    gdb_test "print pAa->f()"   "\\$\[0-9\]+ = 1"
+    gdb_test "print pDe->vg()"  "\\$\[0-9\]+ = 202"
+    gdb_test "print pADe->vg()" "\\$\[0-9\]+ = 202"
+    gdb_test "print pDd->vg()"  "\\$\[0-9\]+ = 101"
+    gdb_test "print pEe->vvb()" "\\$\[0-9\]+ = 411"
+    gdb_test "print pVB->vvb()" "\\$\[0-9\]+ = 407"
+    gdb_test "print pBe->vvb()" "\\$\[0-9\]+ = 411"
+    gdb_test "print pDe->vvb()" "\\$\[0-9\]+ = 411"
+    gdb_test "print pEe->vd()"  "\\$\[0-9\]+ = 282"
+    gdb_test "print pEe->fvb()" "\\$\[0-9\]+ = 311"
+
     # fails on target=native, host=i686-pc-linux-gnu%rh-7.2,
     # gdb=HEAD%2002-02-16, gcc=2.95.3, goption=-gdwarf-2.
     #
@@ -914,34 +474,49 @@ proc test_virtual_calls {} {
     #
     # -- chastain 2002-02-20
 
-    send_gdb "print pEe->D::vg()\n"
-    gdb_expect {
-       -re ".* = 102$nl$gdb_prompt $" { pass "print pEe->D::vg()" }
-       -re "Attempt to take address of value not located in memory.\r\n$gdb_prompt $"
-       { kfail "gdb/1064" "print pEe->D::vg()" }
-       -re ".*$gdb_prompt $" { fail "print pEe->D::vg()" }
-       timeout { fail "print pEe->D::vg() (timeout)" }
-       eof { fail "print pEe->D::vg() ($GDB dumped core) (FIXME)" ; gdb_virtfunc_restart; return }
+    # more recent results:
+    # wrong value "202"
+    #   gcc 2.95.3 -gdwarf-2
+    #   gcc 2.95.3 -gstabs+
+    # attempt to take addres of value not located in memory
+    #   gcc 3.3.2 -gdwarf-2
+    #   gcc 3.3.2 -gstabs+
+    #
+    # -- chastain 2003-12-31
+
+    gdb_test_multiple "print pEe->D::vg()" "print pEe->D::vg()" {
+       -re "\\$\[0-9]+ = 102$nl$gdb_prompt $" {
+           pass "print pEe->D::vg()"
+       }
+       -re "Attempt to take address of value not located in memory.$nl$gdb_prompt $" {
+           kfail "gdb/1064" "print pEe->D::vg()"
+       }
     }
 }
 
 proc do_tests {} {
     global prms_id
     global bug_id
+    global srcdir subdir binfile
+    global gdb_prompt
 
     set prms_id 0
     set bug_id 0
 
-    gdb_start;
-    gdb_virtfunc_init;
+    gdb_exit
+    gdb_start
+    gdb_reinitialize_dir $srcdir/$subdir
+    gdb_load $binfile
 
-    runto_main
+    gdb_test "set language c++" "" ""
+    gdb_test "set width 0" "" ""
 
+    runto_main
     test_ptype_of_classes
 
-    if [ runto 'test_calls' ] then {
-       test_virtual_calls
-    }
+    gdb_breakpoint test_calls
+    gdb_test "continue" ".*Breakpoint .* test_calls.*" ""
+    test_virtual_calls
 }
 
 do_tests