This is the mail archive of the gdb-patches@sources.redhat.com 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: Correct field names for class methods


I understand the method code very little, so I have only superficial
comments.  I'll try to do a more thorough reading next week, if Elena
doesn't beat me to it.

Daniel Jacobowitz <drow@mvista.com> writes:
> @@ -129,15 +128,11 @@ cp_print_class_method (char *valaddr,
>  	  f = TYPE_FN_FIELDLIST1 (domain, i);
>  	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
>  
> +	  check_stub_method_group (f, j);
>  	  for (j = 0; j < len2; j++)
>  	    {
> -	      QUIT;
> -	      if (TYPE_FN_FIELD_STUB (f, j))
> -		check_stub_method (domain, i, j);
>  	      if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
> -		{
> -		  goto common;
> -		}
> +		goto common;
>  	    }
>  	}
>      }

Not that it matters much, but why are you removing the QUIT from this
loop?

> +/* Find the last component of the demangled C++ name NAME.
> +
> +   This function return a pointer to the first colon before the
> +   last component, or NULL if the name had only one component.  */

Hmm, not every demangled name contains a closing paren.  Shouldn't this
comment clarify that it only works on demangled method names?

> @@ -646,15 +644,11 @@ pascal_object_print_class_method (char *
>  	  f = TYPE_FN_FIELDLIST1 (domain, i);
>  	  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
>  
> +	  check_stub_method_group (domain, i);
>  	  for (j = 0; j < len2; j++)
>  	    {
> -	      QUIT;
> -	      if (TYPE_FN_FIELD_STUB (f, j))
> -		check_stub_method (domain, i, j);
>  	      if (STREQ (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
> -		{
> -		  goto common;
> -		}
> +		goto common;
>  	    }
>  	}
>      }

QUIT is deleted here, too.

> @@ -3377,6 +3378,127 @@ read_member_functions (struct field_info
>  	}
>        else
>  	{
> +	  int has_stub = 0;
> +	  int has_nondestructor = 0, has_destructor = 0;
> +	  int is_v3 = 0;
> +	  struct next_fnfield *tmp_sublist;
> +
> +	  /* Various versions of GCC emit various mostly-useless
> +	     strings in the name field for special member functions.
> +	     For some methods, we have a complete physname, so we
> +	     could fix this up now.  For stub methods we will do this
> +	     later, in check_stub_method_group.  For non-stub methods,
> +	     we have no clear way to know whether or not the physname
> +	     is correct; g++ 2.95.x only reliably emits full physnames
> +	     for operators which do not start with the method name
> +	     (constructors, destructors fall in this category; there
> +	     may be others?).  But for other methods it may or may not
> +	     emit a full physname depending on the platform (if
> +	     CPLUS_MARKER can be `$' or `.', it will use minimal debug
> +	     information, but not otherwise).
> +
> +	     Rather than dealing with this, we take a different approach.
> +	     For v3 mangled names, we can use the full physname; for v2,
> +	     we use cplus_demangle_opname, because the only interesting
> +	     names are all operators.  Skip if any method in the group
> +	     is a stub, to prevent our fouling up the workings of
> +	     gdb_mangle_name.
> +
> +	     Another thing that we need to clean up here: GCC 2.95.x
> +	     puts constructors and destructors in the same group.  We
> +	     need to split this into two groups.  */
> +
> +	  tmp_sublist = sublist;
> +	  while (tmp_sublist != NULL)
> +	    {
> +	      if (tmp_sublist->fn_field.is_stub)
> +		has_stub = 1;
> +	      if (tmp_sublist->fn_field.physname[0] == '_'
> +		  && tmp_sublist->fn_field.physname[1] == 'Z')
> +		is_v3 = 1;
> +
> +	      if (is_destructor_name (tmp_sublist->fn_field.physname))
> +		has_destructor++;
> +	      else
> +		has_nondestructor++;
> +
> +	      tmp_sublist = tmp_sublist->next;
> +	    }
> +
> +	  if (has_destructor && has_nondestructor)
> +	    {
> +	      struct next_fnfieldlist *destr_fnlist;
> +	      struct next_fnfield *last_sublist;
> +
> +	      /* Create a new fn_fieldlist for the destructors.  */;
> +	      destr_fnlist = (struct next_fnfieldlist *)
> +		xmalloc (sizeof (struct next_fnfieldlist));
> +	      make_cleanup (xfree, destr_fnlist);
> +	      memset (destr_fnlist, 0, sizeof (struct next_fnfieldlist));
> +	      destr_fnlist->fn_fieldlist.name
> +		= obconcat (&objfile->type_obstack, "", "~",
> +			    new_fnlist->fn_fieldlist.name);
> +
> +	      destr_fnlist->fn_fieldlist.fn_fields = (struct fn_field *)
> +		obstack_alloc (&objfile->type_obstack,
> +			       sizeof (struct fn_field) * has_destructor);
> +	      memset (destr_fnlist->fn_fieldlist.fn_fields, 0,
> +		  sizeof (struct fn_field) * has_destructor);
> +	      tmp_sublist = sublist;
> +	      last_sublist = NULL;
> +	      i = 0;
> +	      while (tmp_sublist != NULL)
> +		{
> +		  if (!is_destructor_name (tmp_sublist->fn_field.physname))
> +		    {
> +		      tmp_sublist = tmp_sublist->next;
> +		      continue;
> +		    }
> +		  
> +		  destr_fnlist->fn_fieldlist.fn_fields[i]
> +		    = tmp_sublist->fn_field;
> +		  if (last_sublist)
> +		    last_sublist->next = tmp_sublist->next;
> +		  else
> +		    sublist = tmp_sublist->next;
> +		  last_sublist = tmp_sublist;
> +		  tmp_sublist = tmp_sublist->next;
> +		}
> +
> +	      destr_fnlist->fn_fieldlist.length = has_destructor;
> +	      destr_fnlist->next = fip->fnlist;
> +	      fip->fnlist = destr_fnlist;
> +	      nfn_fields++;
> +	      total_length += has_destructor;
> +	      length -= has_destructor;
> +	    }
> +	  else if (is_v3)
> +	    {
> +	      /* v3 mangling prevents the use of abbreviated physnames,
> +		 so we can do this here.  There are stubbed methods in v3
> +		 only:
> +		 - in -gstabs instead of -gstabs+
> +		 - or for static methods, who are output as a function type
> +		   instead of a method type.  */
> +
> +	      update_method_name_from_physname (&new_fnlist->fn_fieldlist.name,
> +						sublist->fn_field.physname);
> +	    }
> +	  else if (!has_stub)
> +	    {
> +	      char dem_opname[256];
> +	      int ret;
> +	      ret = cplus_demangle_opname (new_fnlist->fn_fieldlist.name,
> +					      dem_opname, DMGL_ANSI);
> +	      if (!ret)
> +		ret = cplus_demangle_opname (new_fnlist->fn_fieldlist.name,
> +					     dem_opname, 0);
> +	      if (ret)
> +		new_fnlist->fn_fieldlist.name
> +		  = obsavestring (dem_opname, strlen (dem_opname),
> +				  &objfile->type_obstack);
> +	    }
> +

Is there any way we could pull this out into a separate function or
functions?  read_member_functions is bad enough already.


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