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]

[RFA]: Revised C++ patch


This is the revised patch, which is my last patch - the gratuitous
formatting changes + a solution for the memory leak.

I need approval from a symtab.c maintainer.

Changelog entry:
2000-09-12  Daniel Berlin  <dberlin@redhat.com>
 
 	* symtab.c: Add lookup_symbol_aux prototype, and make it static.
 	(lookup_symbol): Made into wrapper for lookup_symbol_aux, so we
 	can perform case sensitivity/demangling without leaking memory.
 	Moved code to do demangling/case sensitivity from
 	old_lookup_symbol to here.
 	(lookup_symbol_aux): Renamed from lookup_symbol. Removed code to
 	do demangling/case sensitivity. Now done in new lookup_symbol.
 
  2000-09-12  Alexandre Oliva  <aoliva@redhat.com>
  
  	* MAINTAINERS: Added myself.
*************** Fri Aug 25 12:03:15 2000  David Taylor  
*** 487,492 ****
--- 497,522 ----
  	* value.h (struct value) <lazy>: Add a comment about its use for
          watchpoints.
  	
 2000-08-10  Daniel Berlin  <dberlin@redhat.com>
 
 	* valops.c (typecmp): Properly handle reference arguments.
 
 	* symtab.h (OPNAME_PREFIX_P): Change operator prefix to correct value.
 
 	* symtab.c (decode_line_1): Properly handle complex templates
 	without quoting.
 	(completion_list_add_name): Fix completion problems
 	with C++ completions. 
 	(lookup_partial_symbol): Remove linear search for C++.
 	(lookup_symbol): Record blocks we've already checked. Also,
 	demangle names before searching. 
 	(lookup_block_symbol): Stop using linear search for C++.
 	(gdb_mangle_name): Properly handle operators.
 
 	* symfile.c (compare_symbols): Use SYMBOL_SOURCE_NAME instead of
 	SYMBOL_NAME. 
 	(compare_psymbols): Same here.
 	



Patch follows:

===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.675
diff -c -3 -p -w -B -b -r1.675 ChangeLog
*** ChangeLog	2000/09/12 04:58:22	1.675
--- ChangeLog	2000/09/12 16:03:06
***************
*** 1,3 ****
--- 1,13 ----
+ 2000-09-12  Daniel Berlin  <dberlin@redhat.com>
+ 
+ 	* symtab.c: Add lookup_symbol_aux prototype, and make it static.
+ 	(lookup_symbol): Made into wrapper for lookup_symbol_aux, so we
+ 	can perform case sensitivity/demangling without leaking memory.
+ 	Moved code to do demangling/case sensitivity from
+ 	old_lookup_symbol to here.
+ 	(lookup_symbol_aux): Renamed from lookup_symbol. Removed code to
+ 	do demangling/case sensitivity. Now done in new lookup_symbol.
+ 
  2000-09-12  Alexandre Oliva  <aoliva@redhat.com>
  
  	* MAINTAINERS: Added myself.
*************** Fri Aug 25 12:03:15 2000  David Taylor  
*** 487,492 ****
--- 497,522 ----
  	* value.h (struct value) <lazy>: Add a comment about its use for
          watchpoints.
  	
+ 2000-08-10  Daniel Berlin  <dberlin@redhat.com>
+ 
+ 	* valops.c (typecmp): Properly handle reference arguments.
+ 
+ 	* symtab.h (OPNAME_PREFIX_P): Change operator prefix to correct value.
+ 
+ 	* symtab.c (decode_line_1): Properly handle complex templates
+ 	without quoting.
+ 	(completion_list_add_name): Fix completion problems
+ 	with C++ completions. 
+ 	(lookup_partial_symbol): Remove linear search for C++.
+ 	(lookup_symbol): Record blocks we've already checked. Also,
+ 	demangle names before searching. 
+ 	(lookup_block_symbol): Stop using linear search for C++.
+ 	(gdb_mangle_name): Properly handle operators.
+ 
+ 	* symfile.c (compare_symbols): Use SYMBOL_SOURCE_NAME instead of
+ 	SYMBOL_NAME. 
+ 	(compare_psymbols): Same here.
+ 	
  2000-08-12  Kevin Buettner  <kevinb@redhat.com>
  
  	* cxux-nat.c (fetch_inferior_registers): Protoize.
Index: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.18
diff -c -3 -p -w -B -b -r1.18 symfile.c
*** symfile.c	2000/09/02 00:09:06	1.18
--- symfile.c	2000/09/12 16:03:07
*************** compare_symbols (const PTR s1p, const PT
*** 212,219 ****
  
    s1 = (struct symbol **) s1p;
    s2 = (struct symbol **) s2p;
! 
!   return (STRCMP (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2)));
  }
  
  /*
--- 209,215 ----
  
    s1 = (struct symbol **) s1p;
    s2 = (struct symbol **) s2p;
!   return (STRCMP (SYMBOL_SOURCE_NAME (*s1), SYMBOL_SOURCE_NAME (*s2)));
  }
  
  /*
*************** compare_symbols (const PTR s1p, const PT
*** 241,248 ****
  static int
  compare_psymbols (const PTR s1p, const PTR s2p)
  {
!   register char *st1 = SYMBOL_NAME (*(struct partial_symbol **) s1p);
!   register char *st2 = SYMBOL_NAME (*(struct partial_symbol **) s2p);
  
    if ((st1[0] - st2[0]) || !st1[0])
      {
--- 237,250 ----
  static int
  compare_psymbols (const PTR s1p, const PTR s2p)
  {
!   register struct partial_symbol **s1, **s2;
!   register char *st1, *st2;
! 
!   s1 = (struct partial_symbol **) s1p;
!   s2 = (struct partial_symbol **) s2p;
!   st1 = SYMBOL_SOURCE_NAME (*s1);
!   st2 = SYMBOL_SOURCE_NAME (*s2);
! 
  
    if ((st1[0] - st2[0]) || !st1[0])
      {
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.15
diff -c -3 -p -w -B -b -r1.15 symtab.c
*** symtab.c	2000/09/04 08:29:25	1.15
--- symtab.c	2000/09/12 16:03:08
*************** static struct partial_symbol *lookup_par
*** 83,88 ****
--- 83,95 ----
  
  static struct symtab *lookup_symtab_1 (char *);
  
+ static struct symbol *lookup_symbol_aux (const char *name, const
+ 					 struct block *block, const
+ 					 namespace_enum namespace, int
+ 					 *is_a_field_of_this, struct
+ 					 symtab **symtab);
+ 
+ 
  static void cplusplus_hint (char *);
  
  static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
*************** gdb_mangle_name (struct type *type, int 
*** 296,301 ****
--- 303,311 ----
    char buf[20];
    int len = (newname == NULL ? 0 : strlen (newname));
  
+   if (OPNAME_PREFIX_P (field_name))
+     return physname;
+ 
    is_full_physname_constructor =
      ((physname[0] == '_' && physname[1] == '_' &&
        (isdigit (physname[2]) || physname[2] == 'Q' || physname[2] == 't'))
*************** gdb_mangle_name (struct type *type, int 
*** 331,355 ****
        sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
      }
    mangled_name_len = ((is_constructor ? 0 : strlen (field_name))
! 		      + strlen (buf) + len
! 		      + strlen (physname)
! 		      + 1);
! 
!   /* Only needed for GNU-mangled names.  ANSI-mangled names
!      work with the normal mechanisms.  */
!   if (OPNAME_PREFIX_P (field_name))
!     {
!       const char *opname = cplus_mangle_opname (field_name + 3, 0);
!       if (opname == NULL)
! 	error ("No mangling for \"%s\"", field_name);
!       mangled_name_len += strlen (opname);
!       mangled_name = (char *) xmalloc (mangled_name_len);
  
-       strncpy (mangled_name, field_name, 3);
-       mangled_name[3] = '\0';
-       strcat (mangled_name, opname);
-     }
-   else
      {
        mangled_name = (char *) xmalloc (mangled_name_len);
        if (is_constructor)
--- 341,348 ----
        sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
      }
    mangled_name_len = ((is_constructor ? 0 : strlen (field_name))
! 		      + strlen (buf) + len + strlen (physname) + 1);
  
    {
      mangled_name = (char *) xmalloc (mangled_name_len);
      if (is_constructor)
*************** fixup_psymbol_section (struct partial_sy
*** 550,555 ****
--- 540,553 ----
    return psym;
  }
  
+ /* We seem to be looking things up in the same block >1 times, because
+    of the global search.*/
+ 
+ #define BLOCK_LOOKUP_HASH_SIZE 16
+ static const struct block *checked_blocks[BLOCK_LOOKUP_HASH_SIZE];
+ 
+ 
+ 
  /* Find the definition for a specified symbol name NAME
     in namespace NAMESPACE, visible from lexical block BLOCK.
     Returns the struct symbol pointer, or zero if no symbol is found.
*************** fixup_psymbol_section (struct partial_sy
*** 572,588 ****
     can probably assume it will never hit the C++ code).  */
  
  struct symbol *
! lookup_symbol (const char *name, register const struct block *block,
  	       const namespace_enum namespace, int *is_a_field_of_this,
  	       struct symtab **symtab)
  {
!   register struct symbol *sym;
!   register struct symtab *s = NULL;
!   register struct partial_symtab *ps;
!   struct blockvector *bv;
!   register struct objfile *objfile = NULL;
!   register struct block *b;
!   register struct minimal_symbol *msymbol;
  
    if (case_sensitivity == case_sensitive_off)
      {
--- 570,583 ----
     can probably assume it will never hit the C++ code).  */
  
  struct symbol *
! lookup_symbol (const char *name, const struct block *block,
  	       const namespace_enum namespace, int *is_a_field_of_this,
  	       struct symtab **symtab)
  {
!   char *modified_name = NULL;
!   char *modified_name2 = NULL;
!   int needtofreename=1;
!   struct symbol *returnval;
  
    if (case_sensitivity == case_sensitive_off)
      {
*************** lookup_symbol (const char *name, registe
*** 594,602 ****
        for (i= 0; i < len; i++)
          copy[i] = tolower (name[i]);
        copy[len] = 0;
!       name = copy;
      }
  
    /* Search specified block and its superiors.  */
  
    while (block != 0)
--- 589,641 ----
        for (i = 0; i < len; i++)
  	copy[i] = tolower (name[i]);
        copy[len] = 0;
!       modified_name = copy;
      }
+   else 
+     {    
+       modified_name = (char *)name;
+     }
+   
+   /* If we are using C++ language, demangle the name before doing a lookup, so
+      we can always binary search. */
+   if (current_language->la_language == language_cplus)
+     {
+       modified_name2 = cplus_demangle (modified_name, DMGL_ANSI |
+ 				       DMGL_PARAMS);
+     }
+   else
+     {
+       needtofreename=0;
+     }
+   
+   if (!modified_name2)
+     {
+       modified_name2 = modified_name;
+       needtofreename=0;
+     }
+   returnval = lookup_symbol_aux (modified_name2, block, namespace,
+ 				 is_a_field_of_this, symtab);
+   if (needtofreename)
+     free(modified_name2);
+ 
+   return returnval;	 
+ }
+ 
+ static struct symbol *
+ lookup_symbol_aux (const char *name, const struct block *block,
+ 	       const namespace_enum namespace, int *is_a_field_of_this,
+ 	       struct symtab **symtab)
+ {
+   register struct symbol *sym;
+   register struct symtab *s = NULL;
+   register struct partial_symtab *ps;
+   register struct blockvector *bv;
+   register struct objfile *objfile = NULL;
+   register struct block *b;
+   register struct minimal_symbol *msymbol;
  
+   memset (&checked_blocks, 0, sizeof (checked_blocks));
+ 
    /* Search specified block and its superiors.  */
  
    while (block != 0)
*************** lookup_symbol (const char *name, registe
*** 690,697 ****
--- 728,748 ----
  
    ALL_SYMTABS (objfile, s)
    {
+     register unsigned long hashval;
      bv = BLOCKVECTOR (s);
      block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+     /* Check if we already tried here */
+     hashval = hash ((unsigned int *) &block, sizeof (struct block *)) %
+       BLOCK_LOOKUP_HASH_SIZE;
+ 
+     if ((checked_blocks[hashval] != NULL) && checked_blocks[hashval] == block)
+       {
+ 	continue;
+       }
+     else
+       {
+ 	checked_blocks[hashval] = block;
+       }
      sym = lookup_block_symbol (block, name, namespace);
      if (sym)
        {
*************** lookup_partial_symbol (struct partial_sy
*** 987,993 ****
  	    {
  	      do_linear_search = 1;
  	    }
! 	  if (STRCMP (SYMBOL_NAME (*center), name) >= 0)
  	    {
  	      top = center;
  	    }
--- 1040,1046 ----
  	    {
  	      do_linear_search = 1;
  	    }
! 	  if (STRCMP (SYMBOL_SOURCE_NAME (*center), name) >= 0)
  	    {
  	      top = center;
  	    }
*************** lookup_block_symbol (register const stru
*** 1190,1198 ****
      {
        /* Reset the linear search flag so if the binary search fails, we
           won't do the linear search once unless we find some reason to
!          do so, such as finding a C++ symbol during the binary search.
!          Note that for C++ modules, ALL the symbols in a block should
!          end up marked as C++ symbols. */
  
        do_linear_search = 0;
        top = BLOCK_NSYMS (block);
--- 1245,1251 ----
      {
        /* Reset the linear search flag so if the binary search fails, we
           won't do the linear search once unless we find some reason to
!          do so */
  
        do_linear_search = 0;
        top = BLOCK_NSYMS (block);
*************** lookup_block_symbol (register const stru
*** 1210,1231 ****
  	    }
  	  inc = (inc >> 1) + bot;
  	  sym = BLOCK_SYM (block, inc);
! 	  if (!do_linear_search
! 	      && (SYMBOL_LANGUAGE (sym) == language_cplus
! 		  || SYMBOL_LANGUAGE (sym) == language_java
! 	      ))
  	    {
  	      do_linear_search = 1;
  	    }
! 	  if (SYMBOL_NAME (sym)[0] < name[0])
  	    {
  	      bot = inc;
  	    }
! 	  else if (SYMBOL_NAME (sym)[0] > name[0])
  	    {
  	      top = inc;
  	    }
! 	  else if (STRCMP (SYMBOL_NAME (sym), name) < 0)
  	    {
  	      bot = inc;
  	    }
--- 1263,1281 ----
  	    }
  	  inc = (inc >> 1) + bot;
  	  sym = BLOCK_SYM (block, inc);
! 	  if (!do_linear_search && (SYMBOL_LANGUAGE (sym) == language_java))
  	    {
  	      do_linear_search = 1;
  	    }
! 	  if (SYMBOL_SOURCE_NAME (sym)[0] < name[0])
  	    {
  	      bot = inc;
  	    }
! 	  else if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
  	    {
  	      top = inc;
  	    }
! 	  else if (STRCMP (SYMBOL_SOURCE_NAME (sym), name) < 0)
  	    {
  	      bot = inc;
  	    }
*************** lookup_block_symbol (register const stru
*** 1247,1265 ****
        while (bot < top)
  	{
  	  sym = BLOCK_SYM (block, bot);
! 	  inc = SYMBOL_NAME (sym)[0] - name[0];
! 	  if (inc == 0)
! 	    {
! 	      inc = STRCMP (SYMBOL_NAME (sym), name);
! 	    }
! 	  if (inc == 0 && SYMBOL_NAMESPACE (sym) == namespace)
! 	    {
! 	      return (sym);
! 	    }
! 	  if (inc > 0)
! 	    {
! 	      break;
! 	    }
  	  bot++;
  	}
      }
--- 1297,1304 ----
        while (bot < top)
  	{
  	  sym = BLOCK_SYM (block, bot);
! 	  if (SYMBOL_MATCHES_NAME (sym, name))
! 	    return sym;
  	  bot++;
  	}
      }
*************** decode_line_1 (char **argptr, int funfir
*** 2473,2478 ****
--- 2511,2517 ----
    register struct minimal_symbol *msymbol;
    char *copy;
    struct symbol *sym_class;
+   int triedonce = 0;
    int i1;
    int is_quoted;
    int is_quote_enclosed;
*************** decode_line_1 (char **argptr, int funfir
*** 2583,2595 ****
      }
    else
      is_quote_enclosed = 0;
    for (; *p; p++)
      {
        if (p[0] == '<')
  	{
  	  char *temp_end = find_template_name_end (p);
! 	  if (!temp_end)
  	    error ("malformed template specification in command");
  	  p = temp_end;
  	}
        /* Check for the end of the first half of the linespec.  End of line,
--- 2622,2647 ----
      }
    else
      is_quote_enclosed = 0;
+ tryagain:
    for (; *p; p++)
      {
        if (p[0] == '<')
  	{
  	  char *temp_end = find_template_name_end (p);
! 	  if (!temp_end && !triedonce)
! 	    {
! 	      triedonce = 1;
! 	      is_quote_enclosed = 1;
! 	      p = *argptr;
! 	      if (has_comma)
! 		*ii = ',';
! 	      s = NULL;
! 	      goto tryagain;
! 	    }
! 	  else if (!temp_end && triedonce)
! 	    {
  	      error ("malformed template specification in command");
+ 	    }
  	  p = temp_end;
  	}
        /* Check for the end of the first half of the linespec.  End of line,
*************** decode_line_1 (char **argptr, int funfir
*** 2798,2806 ****
  
  		      if (OPNAME_PREFIX_P (copy))
  			{
! 			  tmp = (char *) alloca (strlen (copy + 3) + 9);
  			  strcpy (tmp, "operator ");
! 			  strcat (tmp, copy + 3);
  			}
  		      else
  			tmp = copy;
--- 2856,2864 ----
  
  		      if (OPNAME_PREFIX_P (copy))
  			{
! 			  tmp = (char *) alloca (strlen (copy + 8) + 9);
  			  strcpy (tmp, "operator ");
! 			  strcat (tmp, copy + 8);
  			}
  		      else
  			tmp = copy;
*************** make_symbol_completion_list (char *text,
*** 4177,4194 ****
        return NULL;
      else
        {
! 	/* It is not a quoted string.  Break it based on the characters
! 	   which are in symbols.  */
! 	while (p > text)
  	  {
! 	    if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
! 	      --p;
! 	    else
  	      break;
  	  }
  	sym_text = p;
        }
    }
  
    sym_text_len = strlen (sym_text);
  
--- 4244,4262 ----
        return NULL;
      else
        {
! 	for (p = text; *p != '\0'; ++p)
  	  {
! 	    if (!isprint (*p))
  	      break;
  	  }
+ 	if (*p != '\0')
+ 	  {
  	    sym_text = p;
  	  }
+ 	else
+ 	  sym_text = text;
        }
+   }
  
    sym_text_len = strlen (sym_text);
  
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.13
diff -c -3 -p -w -B -b -r1.13 symtab.h
*** symtab.h	2000/08/07 15:02:48	1.13
--- symtab.h	2000/09/12 16:03:08
*************** extern CORE_ADDR symbol_overlayed_addres
*** 170,175 ****
--- 170,177 ----
  #define SYMBOL_INIT_DEMANGLED_NAME(symbol,obstack)			\
   do {                                                                   \
      char *demangled = NULL;						\
+     if (SYMBOL_LANGUAGE (symbol) == language_unknown)                 \
+           SYMBOL_LANGUAGE(symbol) = language_auto;                    \
      if (SYMBOL_LANGUAGE (symbol) == language_cplus			\
  	|| SYMBOL_LANGUAGE (symbol) == language_auto)			\
        {									\
*************** extern CORE_ADDR symbol_overlayed_addres
*** 222,231 ****
  	    SYMBOL_CHILL_DEMANGLED_NAME (symbol) = NULL;		\
  	  }								\
        }									\
-     if (SYMBOL_LANGUAGE (symbol) == language_auto)			\
-       {									\
- 	SYMBOL_LANGUAGE (symbol) = language_unknown;			\
-       }									\
    } while (0)
  
  /* Macro that returns the demangled name for a symbol based on the language
--- 224,229 ----
*************** struct partial_symtab
*** 1053,1059 ****
     Note that this macro is g++ specific (FIXME). */
  
  #define OPNAME_PREFIX_P(NAME) \
!   ((NAME)[0] == 'o' && (NAME)[1] == 'p' && is_cplus_marker ((NAME)[2]))
  
  /* Macro that yields non-zero value iff NAME is the prefix for C++ vtbl
     names.  Note that this macro is g++ specific (FIXME).
--- 1049,1055 ----
     Note that this macro is g++ specific (FIXME). */
  
  #define OPNAME_PREFIX_P(NAME) \
!   (!strncmp(NAME,"operator",8))
  
  /* Macro that yields non-zero value iff NAME is the prefix for C++ vtbl
     names.  Note that this macro is g++ specific (FIXME).




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