contrib/gdb-7/gdb/linespec.c
static struct symtabs_and_lines
find_method (struct linespec_state *self, char *saved_arg,
	     char *copy, const char *class_name, VEC (symbolp) *sym_classes)
{
  char *canon;
  struct symbol *sym;
  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
  int ix;
  int last_result_len;
  VEC (typep) *superclass_vec;
  VEC (const_char_ptr) *result_names;
  struct collect_info info;
  char *name_iter;

  /* NAME is typed by the user: it needs to be canonicalized before
     searching the symbol tables.  */
  canon = cp_canonicalize_string_no_typedefs (copy);
  if (canon != NULL)
    {
      copy = canon;
      make_cleanup (xfree, copy);
    }

  /* Sort symbols so that symbols with the same program space are next
     to each other.  */
  qsort (VEC_address (symbolp, sym_classes),
	 VEC_length (symbolp, sym_classes),
	 sizeof (symbolp),
	 compare_symbols);

  info.state = self;
  info.result.sals = NULL;
  info.result.nelts = 0;

  /* Iterate over all the types, looking for the names of existing
     methods matching COPY.  If we cannot find a direct method in a
     given program space, then we consider inherited methods; this is
     not ideal (ideal would be to respect C++ hiding rules), but it
     seems good enough and is what GDB has historically done.  We only
     need to collect the names because later we find all symbols with
     those names.  This loop is written in a somewhat funny way
     because we collect data across the program space before deciding
     what to do.  */
  superclass_vec = NULL;
  make_cleanup (VEC_cleanup (typep), &superclass_vec);
  result_names = NULL;
  make_cleanup (VEC_cleanup (const_char_ptr), &result_names);
  last_result_len = 0;
  for (ix = 0; VEC_iterate (symbolp, sym_classes, ix, sym); ++ix)
    {
      struct type *t;
      struct program_space *pspace;

      /* Program spaces that are executing startup should have
	 been filtered out earlier.  */
      gdb_assert (!SYMTAB_PSPACE (SYMBOL_SYMTAB (sym))->executing_startup);
      pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
      set_current_program_space (pspace);
      t = check_typedef (SYMBOL_TYPE (sym));
      find_methods (t, copy, &result_names, &superclass_vec);

      /* Handle all items from a single program space at once; and be
	 sure not to miss the last batch.  */
      if (ix == VEC_length (symbolp, sym_classes) - 1
	  || (pspace
	      != SYMTAB_PSPACE (SYMBOL_SYMTAB (VEC_index (symbolp, sym_classes,
							  ix + 1)))))
	{
	  /* If we did not find a direct implementation anywhere in
	     this program space, consider superclasses.  */
	  if (VEC_length (const_char_ptr, result_names) == last_result_len)
	    find_superclass_methods (superclass_vec, copy, &result_names);

	  /* We have a list of candidate symbol names, so now we
	     iterate over the symbol tables looking for all
	     matches in this pspace.  */
	  add_all_symbol_names_from_pspace (&info, pspace, result_names);

	  VEC_truncate (typep, superclass_vec, 0);
	  last_result_len = VEC_length (const_char_ptr, result_names);
	}
    }

  if (info.result.nelts > 0)
    {
      if (self->canonical)
	{
	  self->canonical->pre_expanded = 1;
	  if (self->user_filename)
	    self->canonical->addr_string
	      = xstrprintf ("%s:%s", self->user_filename, saved_arg);
	  else
	    self->canonical->addr_string = xstrdup (saved_arg);
	}

      do_cleanups (cleanup);

      return info.result;
    }

  if (copy[0] == '~')
    cplusplus_error (saved_arg,
		     "the class `%s' does not have destructor defined\n",
		     class_name);
  else
    cplusplus_error (saved_arg,
		     "the class %s does not have any method named %s\n",
		     class_name, copy);
}
/* This finds the method COPY in the class whose type is given by one
   of the symbols in SYM_CLASSES.  */
This finds the method COPY in the class whose type is given by one
of the symbols in SYM_CLASSES.
This finds the method COPY in the class whose type is given by one of the symbols in SYM_CLASSES .
static struct symtabs_and_lines
find_method (struct linespec_state *self, char *saved_arg,
	     char *copy, const char *class_name, VEC (symbolp) *sym_classes)
{
  char *canon;
  struct symbol *sym;
  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
  int ix;
  int last_result_len;
  VEC (typep) *superclass_vec;
  VEC (const_char_ptr) *result_names;
  struct collect_info info;
  char *name_iter;
  canon = cp_canonicalize_string_no_typedefs (copy);
  if (canon != NULL)
    {
      copy = canon;
      make_cleanup (xfree, copy);
    }
  qsort (VEC_address (symbolp, sym_classes),
	 VEC_length (symbolp, sym_classes),
	 sizeof (symbolp),
	 compare_symbols);
  info.state = self;
  info.result.sals = NULL;
  info.result.nelts = 0;
  superclass_vec = NULL;
  make_cleanup (VEC_cleanup (typep), &superclass_vec);
  result_names = NULL;
  make_cleanup (VEC_cleanup (const_char_ptr), &result_names);
  last_result_len = 0;
  for (ix = 0; VEC_iterate (symbolp, sym_classes, ix, sym); ++ix)
    {
      struct type *t;
      struct program_space *pspace;
      gdb_assert (!SYMTAB_PSPACE (SYMBOL_SYMTAB (sym))->executing_startup);
      pspace = SYMTAB_PSPACE (SYMBOL_SYMTAB (sym));
      set_current_program_space (pspace);
      t = check_typedef (SYMBOL_TYPE (sym));
      find_methods (t, copy, &result_names, &superclass_vec);
      if (ix == VEC_length (symbolp, sym_classes) - 1
	  || (pspace
	      != SYMTAB_PSPACE (SYMBOL_SYMTAB (VEC_index (symbolp, sym_classes,
							  ix + 1)))))
	{
	  if (VEC_length (const_char_ptr, result_names) == last_result_len)
	    find_superclass_methods (superclass_vec, copy, &result_names);
	  add_all_symbol_names_from_pspace (&info, pspace, result_names);
	  VEC_truncate (typep, superclass_vec, 0);
	  last_result_len = VEC_length (const_char_ptr, result_names);
	}
    }
  if (info.result.nelts > 0)
    {
      if (self->canonical)
	{
	  self->canonical->pre_expanded = 1;
	  if (self->user_filename)
	    self->canonical->addr_string
	      = xstrprintf ("%s:%s", self->user_filename, saved_arg);
	  else
	    self->canonical->addr_string = xstrdup (saved_arg);
	}
      do_cleanups (cleanup);
      return info.result;
    }
  if (copy[0] == '~')
    cplusplus_error (saved_arg,
		     "the class `%s' does not have destructor defined\n",
		     class_name);
  else
    cplusplus_error (saved_arg,
		     "the class %s does not have any method named %s\n",
		     class_name, copy);
}
static struct symtabs_and_lines find_method ( struct linespec_state * self , char * saved_arg , char * copy , const char * class_name , VEC ( symbolp ) * sym_classes ) { char * canon ; struct symbol * sym ; struct cleanup * cleanup = make_cleanup ( null_cleanup , NULL ) ; int ix ; int last_result_len ; VEC ( typep ) * superclass_vec ; VEC ( const_char_ptr ) * result_names ; struct collect_info info ; char * name_iter ; canon = cp_canonicalize_string_no_typedefs ( copy ) ; if ( canon != NULL ) { copy = canon ; make_cleanup ( xfree , copy ) ; } qsort ( VEC_address ( symbolp , sym_classes ) , VEC_length ( symbolp , sym_classes ) , sizeof ( symbolp ) , compare_symbols ) ; info . state = self ; info . result . sals = NULL ; info . result . nelts = 0 ; superclass_vec = NULL ; make_cleanup ( VEC_cleanup ( typep ) , & superclass_vec ) ; result_names = NULL ; make_cleanup ( VEC_cleanup ( const_char_ptr ) , & result_names ) ; last_result_len = 0 ; for ( ix = 0 ; VEC_iterate ( symbolp , sym_classes , ix , sym ) ; ++ ix ) { struct type * t ; struct program_space * pspace ; gdb_assert ( ! SYMTAB_PSPACE ( SYMBOL_SYMTAB ( sym ) ) -> executing_startup ) ; pspace = SYMTAB_PSPACE ( SYMBOL_SYMTAB ( sym ) ) ; set_current_program_space ( pspace ) ; t = check_typedef ( SYMBOL_TYPE ( sym ) ) ; find_methods ( t , copy , & result_names , & superclass_vec ) ; if ( ix == VEC_length ( symbolp , sym_classes ) - 1 || ( pspace != SYMTAB_PSPACE ( SYMBOL_SYMTAB ( VEC_index ( symbolp , sym_classes , ix + 1 ) ) ) ) ) { if ( VEC_length ( const_char_ptr , result_names ) == last_result_len ) find_superclass_methods ( superclass_vec , copy , & result_names ) ; add_all_symbol_names_from_pspace ( & info , pspace , result_names ) ; VEC_truncate ( typep , superclass_vec , 0 ) ; last_result_len = VEC_length ( const_char_ptr , result_names ) ; } } if ( info . result . nelts > 0 ) { if ( self -> canonical ) { self -> canonical -> pre_expanded = 1 ; if ( self -> user_filename ) self -> canonical -> addr_string = xstrprintf ( " " , self -> user_filename , saved_arg ) ; else self -> canonical -> addr_string = xstrdup ( saved_arg ) ; } do_cleanups ( cleanup ) ; return info . result ; } if ( copy [ 0 ] == ' ' ) cplusplus_error ( saved_arg , " \n " , class_name ) ; else cplusplus_error ( saved_arg , " \n " , class_name , copy ) ; }
This finds the method COPY in the class whose type is given by one
of the symbols in SYM_CLASSES.
This finds the method COPY in the class whose type is given by one of the symbols in SYM_CLASSES .
/* NAME is typed by the user: it needs to be canonicalized before
     searching the symbol tables.  */ /* Sort symbols so that symbols with the same program space are next
     to each other.  */ /* Iterate over all the types, looking for the names of existing
     methods matching COPY.  If we cannot find a direct method in a
     given program space, then we consider inherited methods; this is
     not ideal (ideal would be to respect C++ hiding rules), but it
     seems good enough and is what GDB has historically done.  We only
     need to collect the names because later we find all symbols with
     those names.  This loop is written in a somewhat funny way
     because we collect data across the program space before deciding
     what to do.  */ /* Program spaces that are executing startup should have
	 been filtered out earlier.  */ /* Handle all items from a single program space at once; and be
	 sure not to miss the last batch.  */ /* If we did not find a direct implementation anywhere in
	     this program space, consider superclasses.  */ /* We have a list of candidate symbol names, so now we
	     iterate over the symbol tables looking for all
	     matches in this pspace.  */