RFA: revised changes for gdb/mi 792

J. Johnston jjohnstn@redhat.com
Tue Oct 15 14:21:00 GMT 2002


Keith has pointed out some scenarios my original patch did not address and supplied
an alternate solution such that I have modified my patch.  This replaces the former 
patch that was posted.
 

gdb/ChangeLog:

2002-10-15  Jeff Johnston  <jjohnstn@redhat.com>
	    Keith Seitz  <keiths@redhat.com>

	* varobj.c (cplus_name_of_child): Change code to handle the fact that
	fields are not necessarily contiguous with regards to their access control.
	This is a fix for PR gdb/792.

Ok to commit?

-- Jeff J.
-------------- next part --------------
--- varobj.0.c	Fri Oct 11 15:46:03 2002
+++ varobj.c	Tue Oct 15 17:00:14 2002
@@ -2176,7 +2176,6 @@
 {
   char *name;
   struct type *type;
-  int children[3];
 
   if (CPLUS_FAKE_CHILD (parent))
     {
@@ -2191,55 +2190,97 @@
     {
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
-      cplus_class_num_children (type, children);
-
       if (CPLUS_FAKE_CHILD (parent))
 	{
-	  int i;
-
-	  /* Skip over vptr, if it exists. */
-	  if (TYPE_VPTR_BASETYPE (type) == type
-	      && index >= TYPE_VPTR_FIELDNO (type))
-	    index++;
-
-	  /* FIXME: This assumes that type orders
-	     inherited, public, private, protected */
-	  i = index + TYPE_N_BASECLASSES (type);
-	  if (STREQ (parent->name, "private")
-	      || STREQ (parent->name, "protected"))
-	    i += children[v_public];
-	  if (STREQ (parent->name, "protected"))
-	    i += children[v_private];
+	  /* The fields of the class type are ordered as they
+	     appear in the class.  We are given an index for a
+	     particular access control type ("public","protected",
+	     or "private").  We must skip over fields that don't
+	     have the access control we are looking for to properly
+	     find the indexed field. */
+	  int type_index = TYPE_N_BASECLASSES (type);
+	  if (STREQ (parent->name, "private"))
+	    {
+	      while (index >= 0)
+		{
+	  	  if (TYPE_VPTR_BASETYPE (type) == type
+	      	      && type_index == TYPE_VPTR_FIELDNO (type))
+		    ; /* ignore vptr */
+		  else if (TYPE_FIELD_PRIVATE (type, type_index))
+		    --index;
+		  ++type_index;
+		}
+	      --type_index;
+	    }
+	  else if (STREQ (parent->name, "protected"))
+	    {
+	      while (index >= 0)
+		{
+	  	  if (TYPE_VPTR_BASETYPE (type) == type
+	      	      && type_index == TYPE_VPTR_FIELDNO (type))
+		    ; /* ignore vptr */
+		  else if (TYPE_FIELD_PROTECTED (type, type_index))
+		    --index;
+		  ++type_index;
+		}
+	      --type_index;
+	    }
+	  else
+	    {
+	      while (index >= 0)
+		{
+	  	  if (TYPE_VPTR_BASETYPE (type) == type
+	      	      && type_index == TYPE_VPTR_FIELDNO (type))
+		    ; /* ignore vptr */
+		  else if (!TYPE_FIELD_PRIVATE (type, type_index) &&
+		      !TYPE_FIELD_PROTECTED (type, type_index))
+		    --index;
+		  ++type_index;
+		}
+	      --type_index;
+	    }
 
-	  name = TYPE_FIELD_NAME (type, i);
+	  name = TYPE_FIELD_NAME (type, type_index);
 	}
       else if (index < TYPE_N_BASECLASSES (type))
+	/* We are looking up the name of a base class */
 	name = TYPE_FIELD_NAME (type, index);
       else
 	{
+	  int children[3];
+	  cplus_class_num_children(type, children);
+
 	  /* Everything beyond the baseclasses can
-	     only be "public", "private", or "protected" */
+	     only be "public", "private", or "protected"
+
+	     The special "fake" children are always output by varobj in
+	     this order. So if INDEX == 2, it MUST be "protected". */
 	  index -= TYPE_N_BASECLASSES (type);
 	  switch (index)
 	    {
 	    case 0:
-	      if (children[v_public] != 0)
-		{
-		  name = "public";
-		  break;
-		}
+	      if (children[v_public] > 0)
+	 	name = "public";
+	      else if (children[v_private] > 0)
+	 	name = "private";
+	      else 
+	 	name = "protected";
+	      break;
 	    case 1:
-	      if (children[v_private] != 0)
+	      if (children[v_public] > 0)
 		{
-		  name = "private";
-		  break;
+		  if (children[v_private] > 0)
+		    name = "private";
+		  else
+		    name = "protected";
 		}
+	      else if (children[v_private] > 0)
+	 	name = "protected";
+	      break;
 	    case 2:
-	      if (children[v_protected] != 0)
-		{
-		  name = "protected";
-		  break;
-		}
+	      /* Must be protected */
+	      name = "protected";
+	      break;
 	    default:
 	      /* error! */
 	      break;


More information about the Gdb-patches mailing list