diff options
author | David Carlton <carlton@bactrian.org> | 2003-02-01 01:17:22 +0000 |
---|---|---|
committer | David Carlton <carlton@bactrian.org> | 2003-02-01 01:17:22 +0000 |
commit | 3bebe8f1863428e19f3d404f7bf0007c1451e51a (patch) | |
tree | 22d406b74117ece8e00472c3e4cd65235f3d57ae | |
parent | be431c34739ec12c2b1f8172e1d1fd16193db636 (diff) | |
download | gdb-3bebe8f1863428e19f3d404f7bf0007c1451e51a.tar.gz |
2003-01-31 David Carlton <carlton@math.stanford.edu>
From Jim Blandy <jimb@redhat.com>:
Use a single, consistent representation for an empty minimal
symbol table in an objfile.
* objfiles.c (terminate_minimal_symbol_table): New function.
(allocate_objfile): Call it.
* objfiles.h (terminate_minimal_symbol_table): New declaration.
(ALL_MSYMBOLS): No need to test whether (objfile)->msymbols is
non-NULL.
* minsyms.c (lookup_minimal_symbol_by_pc_section): To see whether
objfile has minimal symbols, compare minimal_symbol_count to zero,
instead of comparing msymbols with NULL.
* objfiles.c (have_minimal_symbols): Same.
* solib-sunos.c (solib_add_common_symbols): Call
terminate_minimal_symbol_table.
* symfile.c (reread_symbols): Same.
* objfiles.h: Revert patch from 2003-01-27, to be replaced by
similar patch from Jim Blandy.
* objfiles.c (objfile_relocate): Ditto.
* i386-linux-tdep.c (find_minsym_and_objfile): Ditto.
* arm-linux-tdep.c (find_minsym_and_objfile): Ditto.
* gdbtypes.h: Delete INTEGER_COERCION_BADNESS,
FLOAT_COERCION_BADNESS.
* gdbtypes.c (rank_one_type): Replace all uses of
INTEGER_COERCION_BADNESS by INTEGER_CONVERSION_BADNESS.
* valops.c (find_overload_match): Call cp_func_name.
* cp-support.h: Declare cp_func_name.
* cp-support.c (cp_func_name): New function.
2003-01-30 David Carlton <carlton@math.stanford.edu>
* valops.c (find_overload_match): Move code into
find_oload_champ_namespace.
(find_oload_champ_namespace): New function, which immediately gets
eviscerated and turned into a call to
find_oload_champ_namespace_loop.
(find_oload_champ_namespace_loop): New function.
* symtab.c (make_symbol_overload_list): Move entire body into
make_symbol_overload_list_qualified.
(make_symbol_overload_list_qualified): New.
(read_in_psymtabs): New.
(make_symbol_overload_list_qualified): Rewrite.
(make_symbol_overload_list_using): New.
(lookup_symbol_namespace): Use alloca, not xmalloc.
(make_symbol_overload_list): Put some memory management stuff back
in.
-rw-r--r-- | gdb/ChangeLog | 50 | ||||
-rw-r--r-- | gdb/arm-linux-tdep.c | 16 | ||||
-rw-r--r-- | gdb/cp-support.c | 26 | ||||
-rw-r--r-- | gdb/cp-support.h | 2 | ||||
-rw-r--r-- | gdb/gdbtypes.c | 24 | ||||
-rw-r--r-- | gdb/gdbtypes.h | 4 | ||||
-rw-r--r-- | gdb/i386-linux-tdep.c | 16 | ||||
-rw-r--r-- | gdb/minsyms.c | 3 | ||||
-rw-r--r-- | gdb/objfiles.c | 44 | ||||
-rw-r--r-- | gdb/objfiles.h | 15 | ||||
-rw-r--r-- | gdb/solib-sunos.c | 1 | ||||
-rw-r--r-- | gdb/symfile.c | 1 | ||||
-rw-r--r-- | gdb/symtab.c | 190 | ||||
-rw-r--r-- | gdb/valops.c | 178 |
14 files changed, 452 insertions, 118 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 052f9a34364..74c62362e69 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,53 @@ +2003-01-31 David Carlton <carlton@math.stanford.edu> + + From Jim Blandy <jimb@redhat.com>: + + Use a single, consistent representation for an empty minimal + symbol table in an objfile. + * objfiles.c (terminate_minimal_symbol_table): New function. + (allocate_objfile): Call it. + * objfiles.h (terminate_minimal_symbol_table): New declaration. + (ALL_MSYMBOLS): No need to test whether (objfile)->msymbols is + non-NULL. + * minsyms.c (lookup_minimal_symbol_by_pc_section): To see whether + objfile has minimal symbols, compare minimal_symbol_count to zero, + instead of comparing msymbols with NULL. + * objfiles.c (have_minimal_symbols): Same. + * solib-sunos.c (solib_add_common_symbols): Call + terminate_minimal_symbol_table. + * symfile.c (reread_symbols): Same. + + * objfiles.h: Revert patch from 2003-01-27, to be replaced by + similar patch from Jim Blandy. + * objfiles.c (objfile_relocate): Ditto. + * i386-linux-tdep.c (find_minsym_and_objfile): Ditto. + * arm-linux-tdep.c (find_minsym_and_objfile): Ditto. + * gdbtypes.h: Delete INTEGER_COERCION_BADNESS, + FLOAT_COERCION_BADNESS. + * gdbtypes.c (rank_one_type): Replace all uses of + INTEGER_COERCION_BADNESS by INTEGER_CONVERSION_BADNESS. + * valops.c (find_overload_match): Call cp_func_name. + * cp-support.h: Declare cp_func_name. + * cp-support.c (cp_func_name): New function. + +2003-01-30 David Carlton <carlton@math.stanford.edu> + + * valops.c (find_overload_match): Move code into + find_oload_champ_namespace. + (find_oload_champ_namespace): New function, which immediately gets + eviscerated and turned into a call to + find_oload_champ_namespace_loop. + (find_oload_champ_namespace_loop): New function. + * symtab.c (make_symbol_overload_list): Move entire body into + make_symbol_overload_list_qualified. + (make_symbol_overload_list_qualified): New. + (read_in_psymtabs): New. + (make_symbol_overload_list_qualified): Rewrite. + (make_symbol_overload_list_using): New. + (lookup_symbol_namespace): Use alloca, not xmalloc. + (make_symbol_overload_list): Put some memory management stuff back + in. + 2003-01-28 David Carlton <carlton@math.stanford.edu> * valops.c (find_overload_match): Calculate func_name via diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index a55fea94ad6..627ed8dda47 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -355,15 +355,19 @@ static struct minimal_symbol * find_minsym_and_objfile (char *name, struct objfile **objfile_p) { struct objfile *objfile; - struct minimal_symbol *msym; - ALL_MSYMBOLS (objfile, msym) + ALL_OBJFILES (objfile) { - if (SYMBOL_NAME (msym) - && strcmp (SYMBOL_NAME (msym), name) == 0) + struct minimal_symbol *msym; + + ALL_OBJFILE_MSYMBOLS (objfile, msym) { - *objfile_p = objfile; - return msym; + if (SYMBOL_NAME (msym) + && strcmp (SYMBOL_NAME (msym), name) == 0) + { + *objfile_p = objfile; + return msym; + } } } diff --git a/gdb/cp-support.c b/gdb/cp-support.c index d91070515c8..ecdbabb031c 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -664,6 +664,32 @@ cp_is_anonymous (const char *namespace_name, int namespace_len) return (location - namespace_name) < namespace_len; } +/* If FULL_NAME is the demangled name of a C++ function (including an + arg list, possibly including namespace/class qualifications), + return a new string containing only the function name (without the + arg list/class qualifications). Otherwise, return NULL. Caller is + responsible for freeing the memory in question. */ + +char * +cp_func_name (const char *full_name) +{ + const char *previous_component = full_name; + const char *next_component; + + if (!full_name) + return NULL; + + for (next_component = cp_find_first_component (previous_component); + *next_component == ':'; + next_component = cp_find_first_component (previous_component)) + { + /* Skip '::'. */ + previous_component = next_component + 2; + } + + return remove_params (previous_component); +} + void _initialize_cp_support (void) { diff --git a/gdb/cp-support.h b/gdb/cp-support.h index f14cf994e3c..1bf2f78f89f 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -108,3 +108,5 @@ extern void cp_check_possible_namespace_symbols (const char *name); extern struct symbol *cp_lookup_possible_namespace_symbol (const char *name); extern int cp_is_anonymous (const char *namespace_name, int namespace_len); + +extern char *cp_func_name (const char *full_name); diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index b40d1eac9a0..87bcc2c3a05 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -2570,7 +2570,7 @@ rank_one_type (struct type *parm, struct type *arg) if (TYPE_NOSIGN (arg)) /* plain char -> plain char */ return 0; else - return INTEGER_COERCION_BADNESS; /* signed/unsigned char -> plain char */ + return INTEGER_CONVERSION_BADNESS; /* signed/unsigned char -> plain char */ } else if (TYPE_UNSIGNED (parm)) { @@ -2581,12 +2581,12 @@ rank_one_type (struct type *parm, struct type *arg) else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long")) return INTEGER_PROMOTION_BADNESS; /* unsigned int -> unsigned long */ else - return INTEGER_COERCION_BADNESS; /* unsigned long -> unsigned int */ + return INTEGER_CONVERSION_BADNESS; /* unsigned long -> unsigned int */ } else { if (!strcmp_iw (TYPE_NAME (arg), "long") && !strcmp_iw (TYPE_NAME (parm), "int")) - return INTEGER_COERCION_BADNESS; /* signed long -> unsigned int */ + return INTEGER_CONVERSION_BADNESS; /* signed long -> unsigned int */ else return INTEGER_CONVERSION_BADNESS; /* signed int/long -> unsigned int/long */ } @@ -2598,15 +2598,15 @@ rank_one_type (struct type *parm, struct type *arg) else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long")) return INTEGER_PROMOTION_BADNESS; else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; } else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; } else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm)) return INTEGER_PROMOTION_BADNESS; else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; case TYPE_CODE_ENUM: case TYPE_CODE_CHAR: case TYPE_CODE_RANGE: @@ -2628,7 +2628,7 @@ rank_one_type (struct type *parm, struct type *arg) case TYPE_CODE_RANGE: case TYPE_CODE_BOOL: case TYPE_CODE_ENUM: - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; case TYPE_CODE_FLT: return INT_FLOAT_CONVERSION_BADNESS; default: @@ -2641,12 +2641,12 @@ rank_one_type (struct type *parm, struct type *arg) case TYPE_CODE_RANGE: case TYPE_CODE_BOOL: case TYPE_CODE_ENUM: - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; case TYPE_CODE_FLT: return INT_FLOAT_CONVERSION_BADNESS; case TYPE_CODE_INT: if (TYPE_LENGTH (arg) > TYPE_LENGTH (parm)) - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm)) return INTEGER_PROMOTION_BADNESS; /* >>> !! else fall through !! <<< */ @@ -2658,7 +2658,7 @@ rank_one_type (struct type *parm, struct type *arg) if (TYPE_NOSIGN (arg)) return 0; else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; } else if (TYPE_UNSIGNED (parm)) { @@ -2670,7 +2670,7 @@ rank_one_type (struct type *parm, struct type *arg) else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg)) return 0; else - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; default: return INCOMPATIBLE_TYPE_BADNESS; } @@ -2683,7 +2683,7 @@ rank_one_type (struct type *parm, struct type *arg) case TYPE_CODE_RANGE: case TYPE_CODE_BOOL: case TYPE_CODE_ENUM: - return INTEGER_COERCION_BADNESS; + return INTEGER_CONVERSION_BADNESS; case TYPE_CODE_FLT: return INT_FLOAT_CONVERSION_BADNESS; default: diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 8adc89eeb2c..525ffd7e2be 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -1221,10 +1221,6 @@ extern int count_virtual_fns (struct type *); #define TOO_FEW_PARAMS_BADNESS 100 /* Badness if no conversion among types */ #define INCOMPATIBLE_TYPE_BADNESS 100 -/* Badness of coercing large integer to smaller size */ -#define INTEGER_COERCION_BADNESS 100 -/* Badness of coercing large floating type to smaller size */ -#define FLOAT_COERCION_BADNESS 100 /* Badness of integral promotion */ #define INTEGER_PROMOTION_BADNESS 1 diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c index 6dca390021c..1ef14fcb900 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -322,15 +322,19 @@ static struct minimal_symbol * find_minsym_and_objfile (char *name, struct objfile **objfile_p) { struct objfile *objfile; - struct minimal_symbol *msym; - ALL_MSYMBOLS (objfile, msym) + ALL_OBJFILES (objfile) { - if (SYMBOL_NAME (msym) - && STREQ (SYMBOL_NAME (msym), name)) + struct minimal_symbol *msym; + + ALL_OBJFILE_MSYMBOLS (objfile, msym) { - *objfile_p = objfile; - return msym; + if (SYMBOL_NAME (msym) + && STREQ (SYMBOL_NAME (msym), name)) + { + *objfile_p = objfile; + return msym; + } } } diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 080c5bc33cc..5d5506bff32 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -405,8 +405,9 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) "null symbol". If there are no real symbols, then there is no minimal symbol table at all. */ - if ((msymbol = objfile->msymbols) != NULL) + if (objfile->minimal_symbol_count > 0) { + msymbol = objfile->msymbols; lo = 0; hi = objfile->minimal_symbol_count - 1; diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 48e4bf52a4a..d2578d7229e 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -283,6 +283,8 @@ allocate_objfile (bfd *abfd, int flags) obstack_specify_allocation (&objfile->type_obstack, 0, 0, xmalloc, xfree); flags &= ~OBJF_MAPPED; + + terminate_minimal_symbol_table (objfile); } /* Update the per-objfile information that comes from the bfd, ensuring @@ -339,6 +341,31 @@ allocate_objfile (bfd *abfd, int flags) return (objfile); } +/* Create the terminating entry of OBJFILE's minimal symbol table. + If OBJFILE->msymbols is zero, allocate a single entry from + OBJFILE->symbol_obstack; otherwise, just initialize + OBJFILE->msymbols[OBJFILE->minimal_symbol_count]. */ +void +terminate_minimal_symbol_table (struct objfile *objfile) +{ + if (! objfile->msymbols) + objfile->msymbols = ((struct minimal_symbol *) + obstack_alloc (&objfile->symbol_obstack, + sizeof (objfile->msymbols[0]))); + + { + struct minimal_symbol *m + = &objfile->msymbols[objfile->minimal_symbol_count]; + + memset (m, 0, sizeof (*m)); + SYMBOL_NAME (m) = NULL; + SYMBOL_VALUE_ADDRESS (m) = 0; + MSYMBOL_INFO (m) = NULL; + MSYMBOL_TYPE (m) = mst_unknown; + SYMBOL_INIT_LANGUAGE_SPECIFIC (m, language_unknown); + } +} + /* Put OBJFILE at the front of the list. */ void @@ -644,15 +671,12 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets) } } - if (objfile->msymbols != NULL) - { - struct minimal_symbol *msym; - ALL_OBJFILE_MSYMBOLS (objfile, msym) - if (SYMBOL_SECTION (msym) >= 0) - SYMBOL_VALUE_ADDRESS (msym) - += ANOFFSET (delta, SYMBOL_SECTION (msym)); - } - + { + struct minimal_symbol *msym; + ALL_OBJFILE_MSYMBOLS (objfile, msym) + if (SYMBOL_SECTION (msym) >= 0) + SYMBOL_VALUE_ADDRESS (msym) += ANOFFSET (delta, SYMBOL_SECTION (msym)); + } /* Relocating different sections by different amounts may cause the symbols to be out of order. */ msymbols_sort (objfile); @@ -783,7 +807,7 @@ have_minimal_symbols (void) ALL_OBJFILES (ofp) { - if (ofp->msymbols != NULL) + if (ofp->minimal_symbol_count > 0) { return 1; } diff --git a/gdb/objfiles.h b/gdb/objfiles.h index ea82a4166c3..a082cb081de 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -300,12 +300,6 @@ struct objfile null symbol. The array itself, as well as all the data that it points to, should be allocated on the symbol_obstack for this file. */ - /* NOTE: carlton/2003-01-27: For a newly-created objfile, msymbols - is set to NULL, rather than a one-element array ending in a - null symbol. ALL_MSYMBOLS already guarded against that case, - so that seems to be a valid possibility; it can be useful if - you like to create artificial objfiles. */ - struct minimal_symbol *msymbols; int minimal_symbol_count; @@ -511,6 +505,8 @@ extern struct objfile *allocate_objfile (bfd *, int); extern int build_objfile_section_table (struct objfile *); +extern void terminate_minimal_symbol_table (struct objfile *objfile); + extern void objfile_to_front (struct objfile *); extern void unlink_objfile (struct objfile *); @@ -570,10 +566,6 @@ extern int is_in_import_list (char *, struct objfile *); /* Traverse all minimal symbols in one objfile. */ -/* NOTE: carlton/2003-01-27: Don't call this macro unless - objfile->msymbols is non-NULL. See NOTE above in the declaration - of 'struct objfile'. */ - #define ALL_OBJFILE_MSYMBOLS(objfile, m) \ for ((m) = (objfile) -> msymbols; SYMBOL_NAME(m) != NULL; (m)++) @@ -593,8 +585,7 @@ extern int is_in_import_list (char *, struct objfile *); #define ALL_MSYMBOLS(objfile, m) \ ALL_OBJFILES (objfile) \ - if ((objfile)->msymbols) \ - ALL_OBJFILE_MSYMBOLS (objfile, m) + ALL_OBJFILE_MSYMBOLS (objfile, m) #define ALL_OBJFILE_OSECTIONS(objfile, osect) \ for (osect = objfile->sections; osect < objfile->sections_end; osect++) diff --git a/gdb/solib-sunos.c b/gdb/solib-sunos.c index ae115673c2b..25682e02caa 100644 --- a/gdb/solib-sunos.c +++ b/gdb/solib-sunos.c @@ -184,6 +184,7 @@ solib_add_common_symbols (CORE_ADDR rtc_symp) xmalloc, xfree); rt_common_objfile->minimal_symbol_count = 0; rt_common_objfile->msymbols = NULL; + terminate_minimal_symbol_table (rt_common_objfile); } init_minimal_symbol_collection (); diff --git a/gdb/symfile.c b/gdb/symfile.c index 37a0d20dba9..6372aa4c987 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -1756,6 +1756,7 @@ reread_symbols (void) error ("Can't find the file sections in `%s': %s", objfile->name, bfd_errmsg (bfd_get_error ())); } + terminate_minimal_symbol_table (objfile); /* We use the same section offsets as from last time. I'm not sure whether that is always correct for shared libraries. */ diff --git a/gdb/symtab.c b/gdb/symtab.c index 3b83aeba4b7..332eb16973c 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -167,6 +167,15 @@ static void symtab_symbol_info (char *, namespace_enum, int); static void overload_list_add_symbol (struct symbol *sym, const char *oload_name); +static void make_symbol_overload_list_using (const char *func_name, + const char *namespace_name, + int namespace_len, + const struct block *block); + +static void make_symbol_overload_list_qualified (const char *func_name); + +static void read_in_psymtabs (const char *oload_name); + void _initialize_symtab (void); /* */ @@ -1293,7 +1302,7 @@ lookup_symbol_namespace (const char *namespace_name, else { char *concatenated_name - = xmalloc (namespace_len + 2 + strlen (name) + 1); + = alloca (namespace_len + 2 + strlen (name) + 1); strncpy (concatenated_name, namespace_name, namespace_len); strcpy (concatenated_name + namespace_len, "::"); strcpy (concatenated_name + namespace_len + 2, name); @@ -1302,7 +1311,6 @@ lookup_symbol_namespace (const char *namespace_name, cp_is_anonymous (namespace_name, namespace_len)); - xfree (concatenated_name); return sym; } } @@ -3959,88 +3967,137 @@ overload_list_add_symbol (struct symbol *sym, const char *oload_name) used in finding all overloaded instances of a function name. This has been modified from make_symbol_completion_list. */ +/* FIXME: carlton/2003-01-30: Should BLOCK be here? Maybe it's better + to use get_selected_block (0). */ + struct symbol ** make_symbol_overload_list (const char *func_name, const char *namespace_name, int namespace_len, const struct block *block) { - register struct symbol *sym; - register struct symtab *s; - register struct partial_symtab *ps; - register struct objfile *objfile; - register struct block *b, *surrounding_static_block = 0; - struct dict_iterator iter; - /* The name we are completing on. */ - const char *oload_name = func_name; + struct cleanup *old_cleanups; sym_return_val_size = 100; sym_return_val_index = 0; - sym_return_val = - (struct symbol **) xmalloc ((sym_return_val_size + 1) * - sizeof (struct symbol *)); + sym_return_val = xmalloc ((sym_return_val_size + 1) * + sizeof (struct symbol *)); sym_return_val[0] = NULL; - /* Look through the partial symtabs for all symbols which begin - by matching OLOAD_NAME. Make sure we read that symbol table in. */ + old_cleanups = make_cleanup (xfree, sym_return_val); - ALL_PSYMTABS (objfile, ps) - { - struct partial_symbol **psym; + make_symbol_overload_list_using (func_name, namespace_name, + namespace_len, block); - /* If the psymtab's been read in we'll get it when we search - through the blockvector. */ - if (ps->readin) - continue; + discard_cleanups (old_cleanups); - for (psym = objfile->global_psymbols.list + ps->globals_offset; - psym < (objfile->global_psymbols.list + ps->globals_offset - + ps->n_global_syms); psym++) - { - /* If interrupted, then quit. */ - QUIT; - /* This will cause the symbol table to be read if it has not yet been */ - s = PSYMTAB_TO_SYMTAB (ps); - } + return sym_return_val; +} - for (psym = objfile->static_psymbols.list + ps->statics_offset; - psym < (objfile->static_psymbols.list + ps->statics_offset - + ps->n_static_syms); psym++) - { - QUIT; - /* This will cause the symbol table to be read if it has not yet been */ - s = PSYMTAB_TO_SYMTAB (ps); - } - } +/* This applies the using directives to add namespaces to search in, + and then searches for overloads in all of those namespaces. It + adds the symbols found to sym_return_val. Arguments are as in + make_symbol_overload_list. */ + +static void +make_symbol_overload_list_using (const char *func_name, + const char *namespace_name, + int namespace_len, + const struct block *block) +{ + struct block_using_iterator iter; + const struct using_direct *current; + + /* First, go through the using directives. If any of them apply, + look in the appropriate namespaces for new functions to match + on. */ + + for (current = block_using_iterator_first (block, &iter); + current != NULL; + current = block_using_iterator_next (&iter)) + { + if (namespace_len == current->outer_length + && strncmp (namespace_name, current->name, namespace_len) == 0) + { + make_symbol_overload_list_using (func_name, + current->name, + current->inner_length, + block); + } + } + + /* Now, add names for this namespace. */ + + if (namespace_len == 0) + { + make_symbol_overload_list_qualified (func_name); + } + else + { + char *concatenated_name + = alloca (namespace_len + 2 + strlen (func_name) + 1); + strncpy (concatenated_name, namespace_name, namespace_len); + strcpy (concatenated_name + namespace_len, "::"); + strcpy (concatenated_name + namespace_len + 2, func_name); + make_symbol_overload_list_qualified (concatenated_name); + } +} + +/* This does the bulk of the work of finding overloaded symbols. + FUNC_NAME is the name of the overloaded function we're looking for + (possibly including namespace info); NEW_LIST is 1 if we should + allocate a new list of overloads and 0 if we should continue using + the same old list. */ + +static void +make_symbol_overload_list_qualified (const char *func_name) +{ + struct symbol *sym; + struct symtab *s; + struct objfile *objfile; + const struct block *b, *surrounding_static_block = 0; + struct dict_iterator iter; + const struct dictionary *dict; + + /* Look through the partial symtabs for all symbols which begin + by matching FUNC_NAME. Make sure we read that symbol table in. */ + + read_in_psymtabs (func_name); /* Search upwards from currently selected frame (so that we can complete on local vars. */ for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b)) { - if (!BLOCK_SUPERBLOCK (b)) + dict = BLOCK_DICT (b); + + for (sym = dict_iter_name_first (dict, func_name, &iter); + sym; + sym = dict_iter_name_next (func_name, &iter)) { - surrounding_static_block = b; /* For elimination of dups */ + overload_list_add_symbol (sym, func_name); } - - /* Also catch fields of types defined in this places which match our - text string. Only complete on types visible from current context. */ - - ALL_BLOCK_SYMBOLS (b, iter, sym) - { - overload_list_add_symbol (sym, oload_name); - } } + surrounding_static_block = block_static_block (get_selected_block (0)); + /* Go through the symtabs and check the externs and statics for symbols which match. */ + /* FIXME: carlton/2003-01-30: Why are we checking all the statics? + Also, this shouldn't check all the globals if there's an + anonymous namespace involved somewhere. */ + ALL_SYMTABS (objfile, s) { QUIT; b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); - ALL_BLOCK_SYMBOLS (b, iter, sym) + dict = BLOCK_DICT (b); + + for (sym = dict_iter_name_first (dict, func_name, &iter); + sym; + sym = dict_iter_name_next (func_name, &iter)) { - overload_list_add_symbol (sym, oload_name); + overload_list_add_symbol (sym, func_name); } } @@ -4051,13 +4108,36 @@ make_symbol_overload_list (const char *func_name, /* Don't do this block twice. */ if (b == surrounding_static_block) continue; - ALL_BLOCK_SYMBOLS (b, iter, sym) + dict = BLOCK_DICT (b); + + for (sym = dict_iter_name_first (dict, func_name, &iter); + sym; + sym = dict_iter_name_next (func_name, &iter)) { - overload_list_add_symbol (sym, oload_name); + overload_list_add_symbol (sym, func_name); } } +} + +/* Look through the partial symtabs for all symbols which begin + by matching FUNC_NAME. Make sure we read that symbol table in. */ + +/* FIXME: carlton/2003-01-30. Lies, all lies. The function does + nothing of the kind: it just reads in every single partial symtab. + (It used to do it in a particularly amusing way, but I've fixed + that.) */ + +static void +read_in_psymtabs (const char *func_name) +{ + struct partial_symtab *ps; + struct objfile *objfile; - return (sym_return_val); + ALL_PSYMTABS (objfile, ps) + { + if (!ps->readin) + psymtab_to_symtab (ps); + } } /* End of overload resolution functions */ diff --git a/gdb/valops.c b/gdb/valops.c index 4a6e3ac498b..39eafaacdc9 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -64,7 +64,22 @@ static struct value *search_struct_method (char *, struct value **, struct value **, int, int *, struct type *); -enum oload_classification { STANDARD, NON_STANDARD, INCOMPATIBLE }; +static int find_oload_champ_namespace (struct type **arg_types, int nargs, + const struct block *current_block, + const char *func_name, + const char *qualified_name, + struct symbol ***oload_syms, + struct badness_vector **oload_champ_bv); + +static +int find_oload_champ_namespace_loop (struct type **arg_types, int nargs, + const struct block *current_block, + const char *func_name, + const char *qualified_name, + int namespace_len, + struct symbol ***oload_syms, + struct badness_vector **oload_champ_bv, + int *oload_champ); static int find_oload_champ (struct type **arg_types, int nargs, int method, int num_fns, @@ -75,6 +90,8 @@ static int find_oload_champ (struct type **arg_types, int nargs, int method, static int oload_method_static (int method, struct fn_field *fns_ptr, int index); +enum oload_classification { STANDARD, NON_STANDARD, INCOMPATIBLE }; + static enum oload_classification classify_oload_match (struct badness_vector * oload_champ_bv, @@ -2846,11 +2863,13 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, been resolved by find_method_list via value_find_oload_method_list above. */ gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL); + oload_champ = find_oload_champ (arg_types, nargs, method, num_fns, + fns_ptr, oload_syms, &oload_champ_bv); } else { - int i = -1; - func_name = remove_params (SYMBOL_CPLUS_DEMANGLED_NAME (fsym)); + const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym); + func_name = cp_func_name (qualified_name); /* If the name is NULL this must be a C-style function. Just return the same symbol. */ @@ -2861,16 +2880,14 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, } old_cleanups = make_cleanup (xfree, func_name); - oload_syms = make_symbol_overload_list (func_name, "", 0, current_block); - make_cleanup (xfree, oload_syms); - while (oload_syms[++i]) - num_fns++; - if (!num_fns) - error ("Couldn't find function %s", func_name); - } - oload_champ = find_oload_champ (arg_types, nargs, method, num_fns, fns_ptr, - oload_syms, &oload_champ_bv); + oload_champ = find_oload_champ_namespace (arg_types, nargs, + current_block, + func_name, + qualified_name, + &oload_syms, + &oload_champ_bv); + } /* NOTE: dan/2000-03-10: Seems to be a better idea to just pick one if they have the exact same goodness. This is because there is no @@ -2957,6 +2974,143 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method, } } +/* This finds the best overload, searching for FUNC_NAME in namespaces + contained in QUALIFIED_NAME until it either finds a good match or + runs out of namespaces. It stores the overloaded functions in + *OLOAD_SYMS, and the badness vector in *OLOAD_CHAMP_BV. The + calling function is responsible for freeing *OLOAD_SYMS. */ + +static int +find_oload_champ_namespace (struct type **arg_types, int nargs, + const struct block *current_block, + const char *func_name, + const char *qualified_name, + struct symbol ***oload_syms, + struct badness_vector **oload_champ_bv) +{ + int oload_champ; + + find_oload_champ_namespace_loop (arg_types, nargs, + current_block, func_name, + qualified_name, 0, + oload_syms, oload_champ_bv, + &oload_champ); + + return oload_champ; +} + +/* Helper function for find_oload_champ_namespace; NAMESPACE_LEN is + how deep we've looked for namespaces, and the champ is stored in + OLOAD_CHAMP. The return value is 1 if the champ is a good one, 0 + if it isn't. */ + +/* FIXME: carlton/2003-01-30: This isn't the cleanest function I've + ever written, to put it mildly. All this overloading stuff could + use some refactoring. */ + +static int +find_oload_champ_namespace_loop (struct type **arg_types, int nargs, + const struct block *current_block, + const char *func_name, + const char *qualified_name, + int namespace_len, + struct symbol ***oload_syms, + struct badness_vector **oload_champ_bv, + int *oload_champ) +{ + int modified_namespace_len = namespace_len; + int next_namespace_len; + int searched_deeper = 0; + int num_fns = 0; + struct cleanup *old_cleanups; + int new_oload_champ; + struct symbol **new_oload_syms; + struct badness_vector *new_oload_champ_bv; + + if (modified_namespace_len != 0) + { + gdb_assert (qualified_name[modified_namespace_len] == ':'); + modified_namespace_len += 2; + } + next_namespace_len + = (cp_find_first_component (qualified_name + modified_namespace_len) + - qualified_name); + + /* First, see if we have a deeper namespace we can search in. If we + get a good match there, use it. */ + + if (qualified_name[next_namespace_len] == ':') + { + searched_deeper = 1; + + if (find_oload_champ_namespace_loop (arg_types, nargs, current_block, + func_name, qualified_name, + next_namespace_len, + oload_syms, oload_champ_bv, + oload_champ)) + { + return 1; + } + }; + + /* If we reach here, either we're in the deepest namespace or we + didn't find a good match in a deeper namespace. But, in the + latter case, we still have a bad match in a deeper namespace; + note that we might not find any match at all in the current + namespace. (There's always a match in the deepest namespace, + because this overload mechanism only gets called if there's a + function symbol to start off with.) */ + + old_cleanups = make_cleanup (xfree, *oload_syms); + new_oload_syms = make_symbol_overload_list (func_name, + qualified_name, + namespace_len, + current_block); + old_cleanups = make_cleanup (xfree, new_oload_syms); + while (new_oload_syms[num_fns]) + ++num_fns; + if (!num_fns) + error ("Couldn't find function %s", func_name); + + new_oload_champ = find_oload_champ (arg_types, nargs, 0, num_fns, + NULL, new_oload_syms, + &new_oload_champ_bv); + + /* Case 1: We found a good match. Free earlier matches (if any), + and return it. Case 2: We didn't find a good match, but we're + not the deepest function. Then go with the bad match that the + deeper function found. Case 3: We found a bad match, and we're + the deepest function. Then return what we found, even though + it's a bad match. */ + + if (new_oload_champ != -1 + && classify_oload_match (new_oload_champ_bv, nargs, 0) == STANDARD) + { + if (searched_deeper) + xfree (*oload_syms); + *oload_syms = new_oload_syms; + *oload_champ = new_oload_champ; + *oload_champ_bv = new_oload_champ_bv; + discard_cleanups (old_cleanups); + return 1; + } + else if (searched_deeper) + { + xfree (new_oload_syms); + discard_cleanups (old_cleanups); + return 0; + } + else + { + gdb_assert (new_oload_champ != -1); + *oload_syms = new_oload_syms; + *oload_champ = new_oload_champ; + *oload_champ_bv = new_oload_champ_bv; + discard_cleanups (old_cleanups); + return 0; + } +} + /* Look for a function to take NARGS args of types ARG_TYPES. Find the best match from among the overloaded methods or functions (depending on METHOD) given by FNS_PTR or OLOAD_SYMS, respectively. |