This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] c++/13615


On 11/08/2012 01:59 PM, Tom Tromey wrote:
Keith> ptype N::Derived::value_type should print 'int' -- but from the
Keith> comment and placement of this code I wonder if it would print 'double'.

I neglected to mention it, but it would be nice either way to have an
explicit test for this.

I've added a test for this and updated the patch to correct that bug.


Keith

ChangeLog
2012-11-14  Keith Seitz  <keiths@redhat.com>

	c++/13615
	* cp-namespace.c (cp_lookup_symbol_in_namespace): Add SEARCH
	parameter and pass it to lookup_symbol_file.
	(cp_lookup_symbol_imports): Tell cp_lookup_symbol_in_namespace
	to search base classes.
	(cp_lookup_symbol_namespace): Likewise.
	(lookup_namespace_scope): Likewise.
	(lookup_symbol_file): Add SEARCH parameter.
	If SEARCH is non-zero and no symbol is found, lookup the class
	and call cp_lookup_nested_symbol.
	(find_symbol_in_baseclass): New function.
	(cp_lookup_nested_symbol): Do not let
	cp_lookup_symbol_in_namespace search through base classes.
	Do that later when there is no global symbol match.

testsuite/ChangeLog
2012-11-14  Keith Seitz  <keiths@redhat.com>

	c++/13615
	* gdb.cp/baseenum.cc: New file.
	* gdb.cp/baseenum.exp: New file.
	* gdb.cp/derivation.cc (A): Add copyright.
	Add a typedef.
	(B): Use A::value_type instead of int.  Change all references.
	(D): Use value_type instead of int.  Change all references.
	(E): Likewise.
	(F); Likewise.
	(Z): New class.
	(ZZ): New class.
 	(N, Base, Derived): New namespace and classes.
	(main): Add instances of Z and ZZ.
	Make sure all symbols from N are kept.
	* gdb.cp/derivation.exp: Update typedef changes in tests.
	Add tests for class typedefs both before and after starting
	the inferior.
	Add tests for searching for a typedef while stopped in a
	method.

diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 1a69402..f2f79ea 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -42,7 +42,8 @@ static struct symbol *lookup_namespace_scope (const char *name,
 static struct symbol *lookup_symbol_file (const char *name,
 					  const struct block *block,
 					  const domain_enum domain,
-					  int anonymous_namespace);
+					  int anonymous_namespace,
+					  int search);
 
 static struct type *cp_lookup_transparent_type_loop (const char *name,
 						     const char *scope,
@@ -264,17 +265,18 @@ cp_lookup_symbol_nonlocal (const char *name,
 }
 
 /* Look up NAME in the C++ namespace NAMESPACE.  Other arguments are
-   as in cp_lookup_symbol_nonlocal.  */
+   as in cp_lookup_symbol_nonlocal.  If SEARCH is non-zero, search
+   through base classes for a matching symbol.  */
 
 static struct symbol *
 cp_lookup_symbol_in_namespace (const char *namespace,
                                const char *name,
                                const struct block *block,
-                               const domain_enum domain)
+                               const domain_enum domain, int search)
 {
   if (namespace[0] == '\0')
     {
-      return lookup_symbol_file (name, block, domain, 0);
+      return lookup_symbol_file (name, block, domain, 0, search);
     }
   else
     {
@@ -285,7 +287,7 @@ cp_lookup_symbol_in_namespace (const char *namespace,
       strcat (concatenated_name, "::");
       strcat (concatenated_name, name);
       return lookup_symbol_file (concatenated_name, block, domain,
-				 cp_is_anonymous (namespace));
+				 cp_is_anonymous (namespace), search);
     }
 }
 
@@ -341,7 +343,7 @@ cp_lookup_symbol_imports (const char *scope,
   /* First, try to find the symbol in the given namespace.  */
   if (!declaration_only)
     sym = cp_lookup_symbol_in_namespace (scope, name,
-					 block, domain);
+					 block, domain, 1);
   
   if (sym != NULL)
     return sym;
@@ -385,7 +387,7 @@ cp_lookup_symbol_imports (const char *scope,
 			 ? current->alias : current->declaration) == 0)
 	    sym = cp_lookup_symbol_in_namespace (current->import_src,
 						 current->declaration,
-						 block, domain);
+						 block, domain, 1);
 
 	  /* If this is a DECLARATION_ONLY search or a symbol was found
 	     or this import statement was an import declaration, the
@@ -419,7 +421,7 @@ cp_lookup_symbol_imports (const char *scope,
 	    {
 	      sym = cp_lookup_symbol_in_namespace (scope,
 						   current->import_src,
-						   block, domain);
+						   block, domain, 1);
 	    }
 	  else if (current->alias == NULL)
 	    {
@@ -550,7 +552,7 @@ cp_lookup_symbol_namespace (const char *scope,
   
   /* First, try to find the symbol in the given namespace.  */
   sym = cp_lookup_symbol_in_namespace (scope, name,
-				       block, domain);
+				       block, domain, 1);
   if (sym != NULL)
     return sym;
 
@@ -621,19 +623,20 @@ lookup_namespace_scope (const char *name,
   strncpy (namespace, scope, scope_len);
   namespace[scope_len] = '\0';
   return cp_lookup_symbol_in_namespace (namespace, name,
-					block, domain);
+					block, domain, 1);
 }
 
 /* Look up NAME in BLOCK's static block and in global blocks.  If
    ANONYMOUS_NAMESPACE is nonzero, the symbol in question is located
-   within an anonymous namespace.  Other arguments are as in
+   within an anonymous namespace.  If SEARCH is non-zero, search through
+   base classes for a matching symbol.  Other arguments are as in
    cp_lookup_symbol_nonlocal.  */
 
 static struct symbol *
 lookup_symbol_file (const char *name,
 		    const struct block *block,
 		    const domain_enum domain,
-		    int anonymous_namespace)
+		    int anonymous_namespace, int search)
 {
   struct symbol *sym = NULL;
 
@@ -657,6 +660,126 @@ lookup_symbol_file (const char *name,
       sym = lookup_symbol_global (name, block, domain);
     }
 
+  if (sym != NULL)
+    return sym;
+
+  if (search)
+    {
+      char *klass, *nested;
+      unsigned int prefix_len;
+      struct cleanup *cleanup;
+      struct symbol *klass_sym;
+
+      /* A simple lookup failed.  Check if the symbol was defined in
+	 a base class.  */
+
+      cleanup = make_cleanup (null_cleanup, NULL);
+
+      /* Find the name of the class and the name of the method,
+	 variable, etc.  */
+      prefix_len = cp_entire_prefix_len (name);
+
+      /* If no prefix was found, search "this".  */
+      if (prefix_len == 0)
+	{
+	  struct type *type;
+	  struct symbol *this;
+
+	  this = lookup_language_this (language_def (language_cplus), block);
+	  if (this == NULL)
+	    {
+	      do_cleanups (cleanup);
+	      return NULL;
+	    }
+
+	  type = check_typedef (TYPE_TARGET_TYPE (SYMBOL_TYPE (this)));
+	  klass = xstrdup (TYPE_NAME (type));
+	  nested = xstrdup (name);
+	}
+      else
+	{
+	  /* The class name is everything up to and including PREFIX_LEN.  */
+	  klass = savestring (name, prefix_len);
+
+	  /* The rest of the name is everything else past the initial scope
+	     operator.  */
+	  nested = xstrdup (name + prefix_len + 2);
+	}
+
+      /* Add cleanups to free memory for these strings.  */
+      make_cleanup (xfree, klass);
+      make_cleanup (xfree, nested);
+
+      /* Lookup a class named KLASS.  If none is found, there is nothing
+	 more that can be done.  */
+      klass_sym = lookup_symbol_global (klass, block, domain);
+      if (klass_sym == NULL)
+	{
+	  do_cleanups (cleanup);
+	  return NULL;
+	}
+
+      /* Look for a symbol named NESTED in this class.  */
+      sym = cp_lookup_nested_symbol (SYMBOL_TYPE (klass_sym), nested, block);
+      do_cleanups (cleanup);
+    }
+
+  return sym;
+}
+
+/* Search through the base classes of PARENT_TYPE for a symbol named
+   NAME in block BLOCK.  */
+
+static struct symbol *
+find_symbol_in_baseclass (struct type *parent_type, const char *name,
+			   const struct block *block)
+{
+  int i;
+  struct symbol *sym;
+  struct cleanup *cleanup;
+  char *concatenated_name;
+
+  sym = NULL;
+  concatenated_name = NULL;
+  cleanup = make_cleanup (null_cleanup, NULL);
+  for (i = 0; i < TYPE_N_BASECLASSES (parent_type); ++i)
+    {
+      const char *base_name = TYPE_BASECLASS_NAME (parent_type, i);
+
+      /* Search this particular base class.  */
+      sym = cp_lookup_symbol_namespace (base_name, name, block, VAR_DOMAIN);
+      if (sym != NULL)
+	break;
+
+      discard_cleanups (cleanup);
+      concatenated_name = xrealloc (concatenated_name,
+				    (strlen (base_name) + 2
+				     + strlen (name) + 1));
+      cleanup = make_cleanup (xfree, concatenated_name);
+      sprintf (concatenated_name, "%s::%s", base_name, name);
+      sym = lookup_symbol_static (concatenated_name, block, VAR_DOMAIN);
+
+      /* If there is currently no BLOCK, e.g., the inferior hasn't yet
+	 been started, then try searching all STATIC_BLOCK symbols in
+	 all objfiles.  */
+      if (block == NULL)
+	{
+	  sym = lookup_static_symbol_aux (concatenated_name, VAR_DOMAIN);
+	  if (sym != NULL)
+	    break;
+	}
+
+      /* If this class has base classes, search them next.  */
+      if (TYPE_N_BASECLASSES (TYPE_BASECLASS (parent_type, i)) > 0)
+	{
+	  sym = find_symbol_in_baseclass (TYPE_BASECLASS (parent_type, i),
+					  name, block);
+	  if (sym != NULL)
+	    break;
+	}
+    }
+
+  do_cleanups (cleanup);
   return sym;
 }
 
@@ -692,7 +815,7 @@ cp_lookup_nested_symbol (struct type *parent_type,
 	const char *parent_name = type_name_no_tag_or_error (saved_parent_type);
 	struct symbol *sym
 	  = cp_lookup_symbol_in_namespace (parent_name, nested_name,
-					   block, VAR_DOMAIN);
+					   block, VAR_DOMAIN, 0);
 	char *concatenated_name;
 
 	if (sym != NULL)
@@ -701,7 +824,7 @@ cp_lookup_nested_symbol (struct type *parent_type,
 	/* Now search all static file-level symbols.  Not strictly
 	   correct, but more useful than an error.  We do not try to
 	   guess any imported namespace as even the fully specified
-	   namespace seach is is already not C++ compliant and more
+	   namespace search is already not C++ compliant and more
 	   assumptions could make it too magic.  */
 
 	size = strlen (parent_name) + 2 + strlen (nested_name) + 1;
@@ -712,7 +835,9 @@ cp_lookup_nested_symbol (struct type *parent_type,
 	if (sym != NULL)
 	  return sym;
 
-	return NULL;
+	/* If no matching symbols were found, try searching any
+	   base classes.  */
+	return find_symbol_in_baseclass (parent_type, nested_name, block);
       }
     default:
       internal_error (__FILE__, __LINE__,
diff --git a/gdb/testsuite/gdb.cp/baseenum.cc b/gdb/testsuite/gdb.cp/baseenum.cc
new file mode 100644
index 0000000..a9e713f
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/baseenum.cc
@@ -0,0 +1,81 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2003-2004, 2007-2012 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/>.
+   */
+
+class A
+{
+public:
+  enum E {X,Y,Z};
+};
+
+class B1 : public A
+{
+};
+
+class B2 : public A
+{
+};
+
+class C : public B1, public B2
+{
+public:
+  void test(E e);
+};
+
+void C::test(E e)
+{
+  if (e == X)  // breakpoint 1
+    {
+    }
+}
+
+namespace N
+{
+  class A
+  {
+  public:
+    enum E {X, Y, Z};
+  };
+
+  class B1 {};
+  class B2 : public A {};
+
+  class C : public B1, public B2
+  {
+  public:
+    void test (E e);
+  };
+
+  void
+  C::test (E e)
+  {
+    if (e == X) // breakpoint 2
+      {
+      }
+  }
+}
+
+int main()
+{
+  C c;
+  c.test(A::X);
+
+  N::C nc;
+  nc.test (N::A::X);
+  return 0;
+}
+
diff --git a/gdb/testsuite/gdb.cp/baseenum.exp b/gdb/testsuite/gdb.cp/baseenum.exp
new file mode 100644
index 0000000..826b4aa
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/baseenum.exp
@@ -0,0 +1,36 @@
+# Copyright 2012 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/>.
+
+# Test searching enum constant symbols derived from base classes.
+
+standard_testfile .cc
+
+if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
+    return -1
+}
+
+if {![runto_main]} {
+    untested "could not run to main"
+    return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "breakpoint 1" $srcfile]
+gdb_continue_to_breakpoint "breakpoint 1"
+gdb_test "print X" "= A::X" "Print enum constant X of class A"
+
+gdb_breakpoint [gdb_get_line_number "breakpoint 2" $srcfile]
+gdb_continue_to_breakpoint "breakpoint 2"
+gdb_test "print X" "= N::A::X" \
+         "Print enum constant X of class A in namespace N"
diff --git a/gdb/testsuite/gdb.cp/derivation.cc b/gdb/testsuite/gdb.cp/derivation.cc
index fcd57ce..da9f64d 100644
--- a/gdb/testsuite/gdb.cp/derivation.cc
+++ b/gdb/testsuite/gdb.cp/derivation.cc
@@ -1,32 +1,63 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2003-2004, 2007-2012 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/>.
+   */
+
+namespace N {
+  typedef double value_type;
+  struct Base { typedef int value_type; };
+  struct Derived : public Base {
+    void doit (void) const {
+       int i = 3;
+
+       while (i > 0)
+         --i;
+     }
+  };
+}
+
 class A {
 public:
-    int a;
-    int aa;
+    typedef int value_type;
+    value_type a;
+    value_type aa;
 
     A()
     {
         a=1;
         aa=2;
     }
-    int afoo();
-    int foo();
-    
+    value_type afoo();
+    value_type foo();
 };
 
 
 
 class B {
 public:
-    int b;
-    int bb;
+    A::value_type b;
+    A::value_type bb;
 
     B()
     {
         b=3;
         bb=4;
     }
-    int bfoo();
-    int foo();
+    A::value_type bfoo();
+    A::value_type foo();
     
 };
 
@@ -51,48 +82,48 @@ public:
 
 class D : private A, public B, protected C {
 public:
-    int d;
-    int dd;
+    value_type d;
+    value_type dd;
 
     D()
     {
         d =7;
         dd=8;
     }
-    int dfoo();
-    int foo();
+    value_type dfoo();
+    value_type foo();
     
 };
 
 
 class E : public A, B, protected C {
 public:
-    int e;
-    int ee;
+    value_type e;
+    value_type ee;
 
     E()
     {
         e =9;
         ee=10;
     }
-    int efoo();
-    int foo();
+    value_type efoo();
+    value_type foo();
     
 };
 
 
 class F : A, public B, C {
 public:
-    int f;
-    int ff;
+    value_type f;
+    value_type ff;
 
     F()
     {
         f =11;
         ff=12;
     }
-    int ffoo();
-    int foo();
+    value_type ffoo();
+    value_type foo();
     
 };
 
@@ -118,6 +149,19 @@ public:
     
 };
 
+class Z : public A
+{
+public:
+  typedef float value_type;
+  value_type z;
+};
+
+class ZZ : public Z
+{
+public:
+  value_type zz;
+};
+
 class V_base
 {
 public:
@@ -150,27 +194,27 @@ public:
 
 V_derived vderived;
 
-int A::afoo() {
+A::value_type A::afoo() {
     return 1;
 }
 
-int B::bfoo() {
+A::value_type B::bfoo() {
     return 2;
 }
 
-int C::cfoo() {
+A::value_type C::cfoo() {
     return 3;
 }
 
-int D::dfoo() {
+D::value_type D::dfoo() {
     return 4;
 }
 
-int E::efoo() {
+E::value_type E::efoo() {
     return 5;
 }
 
-int F::ffoo() {
+F::value_type F::ffoo() {
     return 6;
 }
 
@@ -178,37 +222,37 @@ int G::gfoo() {
     return 77;
 }
 
-int A::foo()
+A::value_type A::foo()
 {
     return 7;
     
 }
 
-int B::foo()
+A::value_type B::foo()
 {
     return 8;
     
 }
 
-int C::foo()
+A::value_type C::foo()
 {
     return 9;
     
 }
 
-int D::foo()
+D::value_type D::foo()
 {
     return 10;
     
 }
 
-int E::foo()
+E::value_type E::foo()
 {
     return 11;
     
 }
 
-int F::foo()
+F::value_type F::foo()
 {
     return 12;
     
@@ -236,7 +280,9 @@ int main(void)
     E e_instance;
     F f_instance;
     G g_instance;
-    
+    Z z_instance;
+    ZZ zz_instance;
+
     marker1(); // marker1-returns-here
     
     a_instance.a = 20; // marker1-returns-here
@@ -251,10 +297,15 @@ int main(void)
     e_instance.ee =29;
     f_instance.f =30;
     f_instance.ff =31;
-    
-    
-    
-
+    g_instance.g = 32;
+    g_instance.gg = 33;
+    z_instance.z = 34.0;
+    zz_instance.zz = 35.0;
+
+    N::Derived dobj;
+    N::Derived::value_type d = 1;
+    N::value_type n = 3.0;
+    dobj.doit ();
     return 0;
     
 }
diff --git a/gdb/testsuite/gdb.cp/derivation.exp b/gdb/testsuite/gdb.cp/derivation.exp
index 68eff4b..594ef1d 100644
--- a/gdb/testsuite/gdb.cp/derivation.exp
+++ b/gdb/testsuite/gdb.cp/derivation.exp
@@ -38,6 +38,18 @@ if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
     return -1
 }
 
+# Check inheritance of typedefs.
+foreach klass {"A" "D" "E" "F"} {
+    gdb_test "ptype ${klass}::value_type" "type = int"
+    gdb_test "whatis ${klass}::value_type" "type = int"
+    gdb_test "p (${klass}::value_type) 0" " = 0"
+}
+foreach klass {"Z" "ZZ"} {
+    gdb_test "ptype ${klass}::value_type" "type = float"
+    gdb_test "whatis ${klass}::value_type" "type = float"
+    gdb_test "p (${klass}::value_type) 0" " = 0"
+}
+
 # Set it up at a breakpoint so we can play with the variable values.
 
 if ![runto 'marker1'] then {
@@ -56,11 +68,12 @@ gdb_test "print a_instance" "\\$\[0-9\]+ = \{a = 1, aa = 2\}" "print value of a_
 cp_test_ptype_class \
     "a_instance" "" "class" "A" \
     {
-	{ field  public "int a;" }
-	{ field  public "int aa;" }
+	{ field  public "A::value_type a;" }
+	{ field  public "A::value_type aa;" }
 	{ method public "A();" }
-	{ method public "int afoo();" }
-	{ method public "int foo();" }
+	{ method public "A::value_type afoo();" }
+	{ method public "A::value_type foo();" }
+	{ typedef public "typedef int value_type;" }
     }
 
 # class D
@@ -77,11 +90,11 @@ cp_test_ptype_class \
 	{ base          "private A" }
 	{ base          "public B" }
 	{ base          "protected C" }
-	{ field  public "int d;" }
-	{ field  public "int dd;" }
+	{ field  public "A::value_type d;" }
+	{ field  public "A::value_type dd;" }
 	{ method public "D();" }
-	{ method public "int dfoo();" }
-	{ method public "int foo();" }
+	{ method public "A::value_type dfoo();" }
+	{ method public "A::value_type foo();" }
     } \
     "" \
     {
@@ -102,11 +115,11 @@ cp_test_ptype_class \
 	{ base          "public A" }
 	{ base          "private B" }
 	{ base          "protected C" }
-	{ field  public "int e;" }
-	{ field  public "int ee;" }
+	{ field  public "A::value_type e;" }
+	{ field  public "A::value_type ee;" }
 	{ method public "E();" }
-	{ method public "int efoo();" }
-	{ method public "int foo();" }
+	{ method public "A::value_type efoo();" }
+	{ method public "A::value_type foo();" }
     } \
     "" \
     {
@@ -127,11 +140,11 @@ cp_test_ptype_class \
 	{ base          "private A" }
 	{ base          "public B" }
 	{ base          "private C" }
-	{ field  public "int f;" }
-	{ field  public "int ff;" }
+	{ field  public "A::value_type f;" }
+	{ field  public "A::value_type ff;" }
 	{ method public "F();" }
-	{ method public "int ffoo();" }
-	{ method public "int foo();" }
+	{ method public "A::value_type ffoo();" }
+	{ method public "A::value_type foo();" }
     }
 
 # class G
@@ -193,6 +206,35 @@ gdb_test_multiple "frame" "re-selected 'main' frame after inferior call" {
 gdb_test "print g_instance.bfoo()" "\\$\[0-9\]+ = 2" "print value of g_instance.bfoo()"
 gdb_test "print g_instance.cfoo()" "\\$\[0-9\]+ = 3" "print value of g_instance.cfoo()"
 
+# Check typedefs of fields
+foreach Klass {"C" "G"} {
+    set klass [string tolower $Klass]
+    set instance "${klass}_instance"
+    set var "${instance}.$klass"
+    gdb_test "whatis $var" "int"
+    gdb_test "ptype $var" "int"
+}
+
+foreach Klass {"A" "B" "D" "E" "F"} {
+    set klass [string tolower $Klass]
+    set instance "${klass}_instance"
+    set var "${instance}.$klass"
+    gdb_test "whatis $var" "A::value_type"
+    gdb_test "ptype $var" "int"
+    if {![string equal $Klass "B"]} {
+	gdb_test "p (${Klass}::value_type) 0" " = 0"
+    }
+}
+
+foreach Klass {"Z" "ZZ"} {
+    set klass [string tolower $Klass]
+    set instance "${klass}_instance"
+    set var "${instance}.$klass"
+    gdb_test "whatis $var" "Z::value_type"
+    gdb_test "ptype $var" "float"
+    gdb_test "p (${Klass}::value_type) 0" " = 0"
+}
+
 # This is a regression test for a bug that caused a crash when trying
 # to print the vtbl pointer.  We don't care about the output so much
 # here (it is tested elsewhere), just that gdb doesn't crash.  We test
@@ -200,3 +242,16 @@ gdb_test "print g_instance.cfoo()" "\\$\[0-9\]+ = 3" "print value of g_instance.
 # path calling get_vptr_fieldno.
 gdb_test "ptype vderived" "type = .*"
 gdb_test "print vderived" " = {.* inter = 0.*x = 0}"
+
+# Test whether inheritance of typedefs is properly
+# reported when stopped.
+gdb_test "ptype N::value_type" "type = double"
+gdb_test "ptype N::Derived::value_type" "type = int"
+
+# Now run to N::Derived::doit and get the type of "value_type"
+if {![runto "N::Derived::doit"]} {
+    perrro "couldn't run to N::Derived::doit"
+    continue
+}
+
+gdb_test "ptype value_type" "type = int"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]