diff options
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r-- | gdb/symtab.c | 198 |
1 files changed, 150 insertions, 48 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c index 1e58770b8b8..aecee8f383a 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -946,6 +946,19 @@ symbol_search_name (const struct general_symbol_info *gsymbol) else return symbol_natural_name (gsymbol); } + +/* See symtab.h. */ + +bool +symbol_matches_search_name (const struct general_symbol_info *gsymbol, + const lookup_name_info &name) +{ + symbol_name_matcher_ftype *name_match + = language_get_symbol_name_matcher (language_def (gsymbol->language), + name); + return name_match (symbol_search_name (gsymbol), name, NULL); +} + /* Return 1 if the two sections are the same, or if they could @@ -1103,11 +1116,12 @@ eq_symbol_entry (const struct symbol_cache_slot *slot, } else if (slot_name != NULL && name != NULL) { - /* It's important that we use the same comparison that was done the - first time through. If the slot records a found symbol, then this - means using strcmp_iw on SYMBOL_SEARCH_NAME. See dictionary.c. - It also means using symbol_matches_domain for found symbols. - See block.c. + /* It's important that we use the same comparison that was done + the first time through. If the slot records a found symbol, + then this means using the symbol name comparison function of + the symbol's language with SYMBOL_SEARCH_NAME. See + dictionary.c. It also means using symbol_matches_domain for + found symbols. See block.c. If the slot records a not-found symbol, then require a precise match. We could still be lax with whitespace like strcmp_iw though. */ @@ -1122,9 +1136,11 @@ eq_symbol_entry (const struct symbol_cache_slot *slot, else { struct symbol *sym = slot->value.found.symbol; + lookup_name_info lookup_name (name, symbol_name_match_type::FULL); - if (strcmp_iw (slot_name, name) != 0) + if (!SYMBOL_MATCHES_SEARCH_NAME (sym, lookup_name)) return 0; + if (!symbol_matches_domain (SYMBOL_LANGUAGE (sym), slot_domain, domain)) return 0; @@ -1743,6 +1759,30 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile) return sym; } +/* See symtab.h. */ + +demangle_for_lookup_info::demangle_for_lookup_info + (const lookup_name_info &lookup_name, language lang) +{ + demangle_result_storage storage; + + m_demangled_name = demangle_for_lookup (lookup_name.name ().c_str (), + lang, storage); +} + +/* See symtab.h. */ + +const lookup_name_info & +lookup_name_info::match_any () +{ + /* Lookup any symbol that "" would complete. I.e., this matches all + symbol names. */ + static const lookup_name_info lookup_name ({}, symbol_name_match_type::FULL, + true); + + return lookup_name; +} + /* Compute the demangled form of NAME as used by the various symbol lookup functions. The result can either be the input NAME directly, or a pointer to a buffer owned by the STORAGE object. @@ -2767,7 +2807,8 @@ basic_lookup_transparent_type (const char *name) search continues. */ void -iterate_over_symbols (const struct block *block, const char *name, +iterate_over_symbols (const struct block *block, + const lookup_name_info &name, const domain_enum domain, gdb::function_view<symbol_found_callback_ftype> callback) { @@ -4231,6 +4272,7 @@ search_symbols (const char *regexp, enum search_domain kind, return file_matches (filename, files, nfiles, basenames); }, + lookup_name_info::match_any (), [&] (const char *symname) { return (!preg || preg->exec (symname, @@ -4587,13 +4629,33 @@ rbreak_command (const char *regexp, int from_tty) information. */ static int -compare_symbol_name (const char *name, const char *sym_text, int sym_text_len) -{ - int (*ncmp) (const char *, const char *, size_t); +compare_symbol_name (const char *name, + language symbol_language, + const lookup_name_info &lookup_name, + const char *sym_text, int sym_text_len, + completion_match_result &match_res) +{ + const language_defn *lang; + + /* If we're completing for an expression and the symbol doesn't have + an explicit language set, fallback to the current language. Ada + minimal symbols won't have their language set to Ada, for + example, and if we compared using the default/C-like matcher, + then when completing e.g., symbols in a package named "pck", we'd + match internal Ada symbols like "pckS", which are invalid in an + Ada expression, unless you wrap them in '<' '>' to request a + verbatim match. */ + if (symbol_language == language_auto + && lookup_name.match_type () == symbol_name_match_type::EXPRESSION) + lang = current_language; + else + lang = language_def (symbol_language); - ncmp = (case_sensitivity == case_sensitive_on ? strncmp : strncasecmp); + symbol_name_matcher_ftype *name_match + = language_get_symbol_name_matcher (lang, lookup_name); - if (ncmp (name, sym_text, sym_text_len) != 0) + /* Clip symbols that cannot match. */ + if (!name_match (name, lookup_name, &match_res.match)) return 0; if (sym_text[sym_text_len] == '(') @@ -4611,20 +4673,32 @@ compare_symbol_name (const char *name, const char *sym_text, int sym_text_len) return 1; } -/* Test to see if the symbol specified by SYMNAME (which is already - demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN - characters. If so, add it to the current completion list. */ +/* See symtab.h. */ -static void +void completion_list_add_name (completion_tracker &tracker, + language symbol_language, const char *symname, + const lookup_name_info &lookup_name, const char *sym_text, int sym_text_len, const char *text, const char *word) { + completion_match_result &match_res + = tracker.reset_completion_match_result (); + /* Clip symbols that cannot match. */ - if (!compare_symbol_name (symname, sym_text, sym_text_len)) + if (!compare_symbol_name (symname, symbol_language, + lookup_name, + sym_text, sym_text_len, + match_res)) return; + /* Refresh SYMNAME from the match string. It's potentially + different depending on language. (E.g., on Ada, the match may be + the encoded symbol name wrapped in "<>"). */ + symname = match_res.match.match (); + gdb_assert (symname != NULL); + /* We have a match for a completion, so add SYMNAME to the current list of matches. Note that the name is moved to freshly malloc'd space. */ @@ -4662,11 +4736,13 @@ completion_list_add_name (completion_tracker &tracker, static void completion_list_add_symbol (completion_tracker &tracker, symbol *sym, + const lookup_name_info &lookup_name, const char *sym_text, int sym_text_len, const char *text, const char *word) { - completion_list_add_name (tracker, SYMBOL_NATURAL_NAME (sym), - sym_text, sym_text_len, text, word); + completion_list_add_name (tracker, SYMBOL_LANGUAGE (sym), + SYMBOL_NATURAL_NAME (sym), + lookup_name, sym_text, sym_text_len, text, word); } /* completion_list_add_name wrapper for struct minimal_symbol. */ @@ -4674,19 +4750,23 @@ completion_list_add_symbol (completion_tracker &tracker, static void completion_list_add_msymbol (completion_tracker &tracker, minimal_symbol *sym, + const lookup_name_info &lookup_name, const char *sym_text, int sym_text_len, const char *text, const char *word) { - completion_list_add_name (tracker, MSYMBOL_NATURAL_NAME (sym), - sym_text, sym_text_len, text, word); + completion_list_add_name (tracker, MSYMBOL_LANGUAGE (sym), + MSYMBOL_NATURAL_NAME (sym), + lookup_name, sym_text, sym_text_len, text, word); } + /* ObjC: In case we are completing on a selector, look as the msymbol again and feed all the selectors into the mill. */ static void completion_list_objc_symbol (completion_tracker &tracker, struct minimal_symbol *msymbol, + const lookup_name_info &lookup_name, const char *sym_text, int sym_text_len, const char *text, const char *word) { @@ -4704,7 +4784,9 @@ completion_list_objc_symbol (completion_tracker &tracker, if (sym_text[0] == '[') /* Complete on shortened method method. */ - completion_list_add_name (tracker, method + 1, + completion_list_add_name (tracker, language_objc, + method + 1, + lookup_name, sym_text, sym_text_len, text, word); while ((strlen (method) + 1) >= tmplen) @@ -4726,10 +4808,12 @@ completion_list_objc_symbol (completion_tracker &tracker, memcpy (tmp, method, (category - method)); tmp[category - method] = ' '; memcpy (tmp + (category - method) + 1, selector, strlen (selector) + 1); - completion_list_add_name (tracker, tmp, + completion_list_add_name (tracker, language_objc, tmp, + lookup_name, sym_text, sym_text_len, text, word); if (sym_text[0] == '[') - completion_list_add_name (tracker, tmp + 1, + completion_list_add_name (tracker, language_objc, tmp + 1, + lookup_name, sym_text, sym_text_len, text, word); } @@ -4741,7 +4825,8 @@ completion_list_objc_symbol (completion_tracker &tracker, if (tmp2 != NULL) *tmp2 = '\0'; - completion_list_add_name (tracker, tmp, + completion_list_add_name (tracker, language_objc, tmp, + lookup_name, sym_text, sym_text_len, text, word); } } @@ -4795,6 +4880,7 @@ language_search_unquoted_string (const char *text, const char *p) static void completion_list_add_fields (completion_tracker &tracker, struct symbol *sym, + const lookup_name_info &lookup_name, const char *sym_text, int sym_text_len, const char *text, const char *word) { @@ -4807,7 +4893,9 @@ completion_list_add_fields (completion_tracker &tracker, if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT) for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++) if (TYPE_FIELD_NAME (t, j)) - completion_list_add_name (tracker, TYPE_FIELD_NAME (t, j), + completion_list_add_name (tracker, SYMBOL_LANGUAGE (sym), + TYPE_FIELD_NAME (t, j), + lookup_name, sym_text, sym_text_len, text, word); } } @@ -4817,6 +4905,7 @@ completion_list_add_fields (completion_tracker &tracker, static void add_symtab_completions (struct compunit_symtab *cust, completion_tracker &tracker, + const lookup_name_info &lookup_name, const char *sym_text, int sym_text_len, const char *text, const char *word, enum type_code code) @@ -4839,6 +4928,7 @@ add_symtab_completions (struct compunit_symtab *cust, || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN && TYPE_CODE (SYMBOL_TYPE (sym)) == code)) completion_list_add_symbol (tracker, sym, + lookup_name, sym_text, sym_text_len, text, word); } @@ -4847,8 +4937,8 @@ add_symtab_completions (struct compunit_symtab *cust, void default_collect_symbol_completion_matches_break_on - (completion_tracker &tracker, - complete_symbol_mode mode, + (completion_tracker &tracker, complete_symbol_mode mode, + symbol_name_match_type name_match_type, const char *text, const char *word, const char *break_on, enum type_code code) { @@ -4939,6 +5029,9 @@ default_collect_symbol_completion_matches_break_on } gdb_assert (sym_text[sym_text_len] == '\0' || sym_text[sym_text_len] == '('); + lookup_name_info lookup_name (std::string (sym_text, sym_text_len), + name_match_type, true); + /* At this point scan through the misc symbol vectors and add each symbol you find to the list. Eventually we want to ignore anything that isn't a text symbol (everything else will be @@ -4950,34 +5043,30 @@ default_collect_symbol_completion_matches_break_on { QUIT; - completion_list_add_msymbol (tracker, - msymbol, sym_text, sym_text_len, + completion_list_add_msymbol (tracker, msymbol, lookup_name, + sym_text, sym_text_len, text, word); - completion_list_objc_symbol (tracker, - msymbol, sym_text, sym_text_len, - text, word); + completion_list_objc_symbol (tracker, msymbol, lookup_name, + sym_text, sym_text_len, text, + word); } } /* Add completions for all currently loaded symbol tables. */ ALL_COMPUNITS (objfile, cust) - add_symtab_completions (cust, tracker, + add_symtab_completions (cust, tracker, lookup_name, sym_text, sym_text_len, text, word, code); /* Look through the partial symtabs for all symbols which begin by matching SYM_TEXT. Expand all CUs that you find to the list. */ expand_symtabs_matching (NULL, - [&] (const char *name) /* symbol matcher */ - { - return compare_symbol_name (name, - sym_text, - sym_text_len); - }, + lookup_name, + NULL, [&] (compunit_symtab *symtab) /* expansion notify */ { add_symtab_completions (symtab, - tracker, + tracker, lookup_name, sym_text, sym_text_len, text, word, code); }, @@ -5000,16 +5089,16 @@ default_collect_symbol_completion_matches_break_on { if (code == TYPE_CODE_UNDEF) { - completion_list_add_symbol (tracker, sym, + completion_list_add_symbol (tracker, sym, lookup_name, sym_text, sym_text_len, text, word); - completion_list_add_fields (tracker, sym, + completion_list_add_fields (tracker, sym, lookup_name, sym_text, sym_text_len, text, word); } else if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN && TYPE_CODE (SYMBOL_TYPE (sym)) == code) - completion_list_add_symbol (tracker, sym, + completion_list_add_symbol (tracker, sym, lookup_name, sym_text, sym_text_len, text, word); } @@ -5028,12 +5117,12 @@ default_collect_symbol_completion_matches_break_on { if (surrounding_static_block != NULL) ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym) - completion_list_add_fields (tracker, sym, + completion_list_add_fields (tracker, sym, lookup_name, sym_text, sym_text_len, text, word); if (surrounding_global_block != NULL) ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym) - completion_list_add_fields (tracker, sym, + completion_list_add_fields (tracker, sym, lookup_name, sym_text, sym_text_len, text, word); } @@ -5050,7 +5139,10 @@ default_collect_symbol_completion_matches_break_on macro_source_file *, int) { - completion_list_add_name (tracker, macro_name, + completion_list_add_name (tracker, + language_c, + macro_name, + lookup_name, sym_text, sym_text_len, text, word); }; @@ -5078,10 +5170,12 @@ default_collect_symbol_completion_matches_break_on void default_collect_symbol_completion_matches (completion_tracker &tracker, complete_symbol_mode mode, + symbol_name_match_type name_match_type, const char *text, const char *word, enum type_code code) { return default_collect_symbol_completion_matches_break_on (tracker, mode, + name_match_type, text, word, "", code); } @@ -5092,9 +5186,11 @@ default_collect_symbol_completion_matches (completion_tracker &tracker, void collect_symbol_completion_matches (completion_tracker &tracker, complete_symbol_mode mode, + symbol_name_match_type name_match_type, const char *text, const char *word) { current_language->la_collect_symbol_completion_matches (tracker, mode, + name_match_type, text, word, TYPE_CODE_UNDEF); } @@ -5108,11 +5204,13 @@ collect_symbol_completion_matches_type (completion_tracker &tracker, enum type_code code) { complete_symbol_mode mode = complete_symbol_mode::EXPRESSION; + symbol_name_match_type name_match_type = symbol_name_match_type::EXPRESSION; gdb_assert (code == TYPE_CODE_UNION || code == TYPE_CODE_STRUCT || code == TYPE_CODE_ENUM); current_language->la_collect_symbol_completion_matches (tracker, mode, + name_match_type, text, word, code); } @@ -5122,6 +5220,7 @@ collect_symbol_completion_matches_type (completion_tracker &tracker, void collect_file_symbol_completion_matches (completion_tracker &tracker, complete_symbol_mode mode, + symbol_name_match_type name_match_type, const char *text, const char *word, const char *srcfile) { @@ -5178,12 +5277,15 @@ collect_file_symbol_completion_matches (completion_tracker &tracker, sym_text_len = strlen (sym_text); + lookup_name_info lookup_name (std::string (sym_text, sym_text_len), + name_match_type, true); + /* Go through symtabs for SRCFILE and check the externs and statics for symbols which match. */ iterate_over_symtabs (srcfile, [&] (symtab *s) { add_symtab_completions (SYMTAB_COMPUNIT (s), - tracker, + tracker, lookup_name, sym_text, sym_text_len, text, word, TYPE_CODE_UNDEF); return false; |