This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFA]: Revised C++ patch
- To: gdb-patches at sources dot redhat dot com
- Subject: [RFA]: Revised C++ patch
- From: Daniel Berlin <dberlin at redhat dot com>
- Date: 12 Sep 2000 12:12:49 -0400
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).