X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsymtab.c;h=0fd75e53c86ff6a82f550392345668d278e224bd;hb=b57a636e4b4d23ba89c9d18118ed231500b0de06;hp=c4bd13da8d223dc992a3c818601a7b4ee7a850ab;hpb=ca242aadec5ec762ae852ae80b67772302c534b8;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symtab.c b/gdb/symtab.c index c4bd13da8d..0fd75e53c8 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -62,6 +62,7 @@ #include "macroscope.h" #include "psymtab.h" +#include "parser-defs.h" /* Prototypes for local functions */ @@ -81,7 +82,7 @@ static struct symbol *lookup_symbol_aux (const char *name, const struct block *block, const domain_enum domain, enum language language, - int *is_a_field_of_this); + struct field_of_this_result *is_a_field_of_this); static struct symbol *lookup_symbol_aux_local (const char *name, @@ -146,15 +147,14 @@ const struct block *block_found; /* See whether FILENAME matches SEARCH_NAME using the rule that we advertise to the user. (The manual's description of linespecs - describes what we advertise). SEARCH_LEN is the length of - SEARCH_NAME. We assume that SEARCH_NAME is a relative path. - Returns true if they match, false otherwise. */ + describes what we advertise). We assume that SEARCH_NAME is + a relative path. Returns true if they match, false otherwise. */ int -compare_filenames_for_search (const char *filename, const char *search_name, - int search_len) +compare_filenames_for_search (const char *filename, const char *search_name) { int len = strlen (filename); + size_t search_len = strlen (search_name); if (len < search_len) return 0; @@ -195,7 +195,6 @@ iterate_over_some_symtabs (const char *name, { struct symtab *s = NULL; const char* base_name = lbasename (name); - int name_len = strlen (name); int is_abs = IS_ABSOLUTE_PATH (name); for (s = first; s != NULL && s != after_last; s = s->next) @@ -207,7 +206,7 @@ iterate_over_some_symtabs (const char *name, return 1; } - if (!is_abs && compare_filenames_for_search (s->filename, name, name_len)) + if (!is_abs && compare_filenames_for_search (s->filename, name)) { if (callback (s, data)) return 1; @@ -232,8 +231,7 @@ iterate_over_some_symtabs (const char *name, return 1; } - if (fp != NULL && !is_abs && compare_filenames_for_search (fp, name, - name_len)) + if (fp != NULL && !is_abs && compare_filenames_for_search (fp, name)) { if (callback (s, data)) return 1; @@ -255,7 +253,7 @@ iterate_over_some_symtabs (const char *name, return 1; } - if (!is_abs && compare_filenames_for_search (rp, name, name_len)) + if (!is_abs && compare_filenames_for_search (rp, name)) { if (callback (s, data)) return 1; @@ -1224,7 +1222,7 @@ demangle_for_lookup (const char *name, enum language lang, struct symbol * lookup_symbol_in_language (const char *name, const struct block *block, const domain_enum domain, enum language lang, - int *is_a_field_of_this) + struct field_of_this_result *is_a_field_of_this) { const char *modified_name; struct symbol *returnval; @@ -1242,7 +1240,8 @@ lookup_symbol_in_language (const char *name, const struct block *block, struct symbol * lookup_symbol (const char *name, const struct block *block, - domain_enum domain, int *is_a_field_of_this) + domain_enum domain, + struct field_of_this_result *is_a_field_of_this) { return lookup_symbol_in_language (name, block, domain, current_language->la_language, @@ -1277,24 +1276,68 @@ lookup_language_this (const struct language_defn *lang, return NULL; } +/* Given TYPE, a structure/union, + return 1 if the component named NAME from the ultimate target + structure/union is defined, otherwise, return 0. */ + +static int +check_field (struct type *type, const char *name, + struct field_of_this_result *is_a_field_of_this) +{ + int i; + + /* The type may be a stub. */ + CHECK_TYPEDEF (type); + + for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) + { + const char *t_field_name = TYPE_FIELD_NAME (type, i); + + if (t_field_name && (strcmp_iw (t_field_name, name) == 0)) + { + is_a_field_of_this->type = type; + is_a_field_of_this->field = &TYPE_FIELD (type, i); + return 1; + } + } + + /* C++: If it was not found as a data field, then try to return it + as a pointer to a method. */ + + for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i) + { + if (strcmp_iw (TYPE_FN_FIELDLIST_NAME (type, i), name) == 0) + { + is_a_field_of_this->type = type; + is_a_field_of_this->fn_field = &TYPE_FN_FIELDLIST (type, i); + return 1; + } + } + + for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--) + if (check_field (TYPE_BASECLASS (type, i), name, is_a_field_of_this)) + return 1; + + return 0; +} + /* Behave like lookup_symbol except that NAME is the natural name (e.g., demangled name) of the symbol that we're looking for. */ static struct symbol * lookup_symbol_aux (const char *name, const struct block *block, const domain_enum domain, enum language language, - int *is_a_field_of_this) + struct field_of_this_result *is_a_field_of_this) { struct symbol *sym; const struct language_defn *langdef; /* Make sure we do something sensible with is_a_field_of_this, since the callers that set this parameter to some non-null value will - certainly use it later and expect it to be either 0 or 1. - If we don't set it, the contents of is_a_field_of_this are - undefined. */ + certainly use it later. If we don't set it, the contents of + is_a_field_of_this are undefined. */ if (is_a_field_of_this != NULL) - *is_a_field_of_this = 0; + memset (is_a_field_of_this, 0, sizeof (*is_a_field_of_this)); /* Search specified block and its superiors. Don't search STATIC_BLOCK or GLOBAL_BLOCK. */ @@ -1308,7 +1351,10 @@ lookup_symbol_aux (const char *name, const struct block *block, langdef = language_def (language); - if (is_a_field_of_this != NULL) + /* Don't do this check if we are searching for a struct. It will + not be found by check_field, but will be found by other + means. */ + if (is_a_field_of_this != NULL && domain != STRUCT_DOMAIN) { struct symbol *sym = lookup_language_this (langdef, block); @@ -1328,11 +1374,8 @@ lookup_symbol_aux (const char *name, const struct block *block, error (_("Internal error: `%s' is not an aggregate"), langdef->la_name_of_this); - if (check_field (t, name)) - { - *is_a_field_of_this = 1; - return NULL; - } + if (check_field (t, name, is_a_field_of_this)) + return NULL; } } @@ -2149,6 +2192,8 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section) if (best_s != NULL) return (best_s); + /* Not found in symtabs, search the "quick" symtabs (e.g. psymtabs). */ + ALL_OBJFILES (objfile) { struct symtab *result; @@ -4201,7 +4246,8 @@ expand_partial_symbol_name (const char *name, void *user_data) VEC (char_ptr) * default_make_symbol_completion_list_break_on (char *text, char *word, - const char *break_on) + const char *break_on, + enum type_code code) { /* Problem: All of the symbols have to be copied because readline frees them. I'm not going to worry about this; hopefully there @@ -4308,13 +4354,18 @@ default_make_symbol_completion_list_break_on (char *text, char *word, anything that isn't a text symbol (everything else will be handled by the psymtab code above). */ - ALL_MSYMBOLS (objfile, msymbol) - { - QUIT; - COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word); + if (code == TYPE_CODE_UNDEF) + { + ALL_MSYMBOLS (objfile, msymbol) + { + QUIT; + COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, + word); - completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text, word); - } + completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text, + word); + } + } /* Search upwards from currently selected frame (so that we can complete on local vars). Also catch fields of types defined in @@ -4331,10 +4382,17 @@ default_make_symbol_completion_list_break_on (char *text, char *word, ALL_BLOCK_SYMBOLS (b, iter, sym) { - COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, - word); - completion_list_add_fields (sym, sym_text, sym_text_len, text, - word); + if (code == TYPE_CODE_UNDEF) + { + COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, + word); + completion_list_add_fields (sym, sym_text, sym_text_len, text, + word); + } + else if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN + && TYPE_CODE (SYMBOL_TYPE (sym)) == code) + COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, + word); } /* Stop when we encounter an enclosing function. Do not stop for @@ -4347,13 +4405,16 @@ default_make_symbol_completion_list_break_on (char *text, char *word, /* Add fields from the file's types; symbols will be added below. */ - if (surrounding_static_block != NULL) - ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym) - completion_list_add_fields (sym, sym_text, sym_text_len, text, word); + if (code == TYPE_CODE_UNDEF) + { + if (surrounding_static_block != NULL) + ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym) + completion_list_add_fields (sym, sym_text, sym_text_len, text, word); - if (surrounding_global_block != NULL) - ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym) - completion_list_add_fields (sym, sym_text, sym_text_len, text, word); + if (surrounding_global_block != NULL) + ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym) + completion_list_add_fields (sym, sym_text, sym_text_len, text, word); + } /* Go through the symtabs and check the externs and statics for symbols which match. */ @@ -4364,7 +4425,10 @@ default_make_symbol_completion_list_break_on (char *text, char *word, b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); ALL_BLOCK_SYMBOLS (b, iter, sym) { - COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); + if (code == TYPE_CODE_UNDEF + || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN + && TYPE_CODE (SYMBOL_TYPE (sym)) == code)) + COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); } } @@ -4374,11 +4438,17 @@ default_make_symbol_completion_list_break_on (char *text, char *word, b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); ALL_BLOCK_SYMBOLS (b, iter, sym) { - COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); + if (code == TYPE_CODE_UNDEF + || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN + && TYPE_CODE (SYMBOL_TYPE (sym)) == code)) + COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word); } } - if (current_language->la_macro_expansion == macro_expansion_c) + /* Skip macros if we are completing a struct tag -- arguable but + usually what is expected. */ + if (current_language->la_macro_expansion == macro_expansion_c + && code == TYPE_CODE_UNDEF) { struct macro_scope *scope; @@ -4406,9 +4476,10 @@ default_make_symbol_completion_list_break_on (char *text, char *word, } VEC (char_ptr) * -default_make_symbol_completion_list (char *text, char *word) +default_make_symbol_completion_list (char *text, char *word, + enum type_code code) { - return default_make_symbol_completion_list_break_on (text, word, ""); + return default_make_symbol_completion_list_break_on (text, word, "", code); } /* Return a vector of all symbols (regardless of class) which begin by @@ -4418,7 +4489,21 @@ default_make_symbol_completion_list (char *text, char *word) VEC (char_ptr) * make_symbol_completion_list (char *text, char *word) { - return current_language->la_make_symbol_completion_list (text, word); + return current_language->la_make_symbol_completion_list (text, word, + TYPE_CODE_UNDEF); +} + +/* Like make_symbol_completion_list, but only return STRUCT_DOMAIN + symbols whose type code is CODE. */ + +VEC (char_ptr) * +make_symbol_completion_type (char *text, char *word, enum type_code code) +{ + gdb_assert (code == TYPE_CODE_UNION + || code == TYPE_CODE_STRUCT + || code == TYPE_CODE_CLASS + || code == TYPE_CODE_ENUM); + return current_language->la_make_symbol_completion_list (text, word, code); } /* Like make_symbol_completion_list, but suitable for use as a