Introduce lookup_name_info and generalize Ada's FULL/WILD name matching
Summary: - This is preparation for supporting wild name matching on C++ too. - This is also preparation for TAB-completion fixes. - Makes symbol name matching (think strcmp_iw) be based on a per-language method. - Merges completion and non-completion name comparison (think language_ops::la_get_symbol_name_cmp generalized). - Avoid re-hashing lookup name multiple times - Centralizes preparing a name for lookup (Ada name encoding / C++ Demangling), both completion and non-completion. - Fixes Ada latent bug with verbatim name matches in expressions - Makes ada-lang.c use common|symtab.c completion code a bit more. Ada's wild matching basically means that "(gdb) break foo" will find all methods named "foo" in all packages. Translating to C++, it's roughly the same as saying that "break klass::method" sets breakpoints on all "klass::method" methods of all classes, no matter the namespace. A following patch will teach GDB about fullname vs wild matching for C++ too. This patch is preparatory work to get there. Another idea here is to do symbol name matching based on the symbol language's algorithm. I.e., avoid dependency on current language set. This allows for example doing (gdb) b foo::bar< int > (<tab> and having gdb name match the C++ symbols correctly even if the current language is C or Assembly (or Rust, or Ada, or ...), which can easily happen if you step into an Assembly/C runtime library frame. By encapsulating all the information related to a lookup name in a class, we can also cache hash computation for a given language in the lookup name object, to avoid recomputing it over and over. Similarly, because we don't really know upfront which languages the lookup name will be matched against, for each language we store the lookup name transformed into a search name. E.g., for C++, that means demangling the name. But for Ada, it means encoding the name. This actually forces us to centralize all the different lookup name encoding in a central place, resulting in clearer code, IMO. See e.g., the new ada_lookup_name_info class. The lookup name -> symbol search name computation is also done only once per language. The old language->la_get_symbol_name_cmp / symbol_name_cmp_ftype are generalized to work with both completion, and normal symbol look up. At some point early on, I had separate completion vs non-completion language vector entry points, but a single method ends up being better IMO for simplifying things -- the more we merge the completion / non-completion name lookup code paths, the less changes for bugs causing completion vs normal lookup finding different symbols. The ada-lex.l change is necessary because when doing (gdb) p <UpperCase> then the name that is passed to write_ write_var_or_type -> ada_lookup_symbol_list misses the "<>", i.e., it's just "UpperCase", and we end up doing a wild match against "UpperCase" lowercased by ada_lookup_name_info's constructor. I.e., "uppercase" wouldn't ever match "UpperCase", and the symbol lookup fails. This wouldn't cause any regression in the testsuite, but I added a new test that would pass before the patch and fail after, if it weren't for that fix. This is latent bug that happens to go unnoticed because that particular path was inconsistent with the rest of Ada symbol lookup by not lowercasing the lookup name. Ada's symbol_completion_add is deleted, replaced by using common code's completion_list_add_name. To make the latter work for Ada, we needed to add a new output parameter, because Ada wants to return back a custom completion candidates that are not the symbol name. With this patch, minimal symbol demangled name hashing is made consistent with regular symbol hashing. I.e., it now goes via the language vector's search_name_hash method too, as I had suggested in a previous patch. dw2_expand_symtabs_matching / .gdb_index symbol names were a challenge. The problem is that we have no way to telling what is the language of each symbol name found in the index, until we expand the corresponding full symbol, which is off course what we're trying to avoid. Language information is simply not considered in the index format... Since the symbol name hashing and comparison routines are per-language, we now have a problem. The patch sorts this out by matching each name against all languages. This is inneficient, and indeed slows down completion several times. E.g., with: $ cat script.cmd set pagination off set $count = 0 while $count < 400 complete b string_prin printf "count = %d\n", $count set $count = $count + 1 end $ time gdb --batch -q ./gdb-with-index -ex "source script-string_printf.cmd" I get, before patch (-O2, x86-64): real 0m1.773s user 0m1.737s sys 0m0.040s While after patch (-O2, x86-64): real 0m9.843s user 0m9.482s sys 0m0.034s However, the following patch will optimize this, and will actually make this use case faster compared to the "before patch" above: real 0m1.321s user 0m1.285s sys 0m0.039s gdb/ChangeLog: 2017-11-08 Pedro Alves <palves@redhat.com> * ada-lang.c (ada_encode): Rename to .. (ada_encode_1): ... this. Add throw_errors parameter and handle it. (ada_encode): Reimplement. (match_name): Delete, folded into full_name. (resolve_subexp): No longer pass the encoded name to ada_lookup_symbol_list. (should_use_wild_match): Delete. (name_match_type_from_name): New. (ada_lookup_simple_minsym): Use lookup_name_info and the language's symbol_name_matcher_ftype. (add_symbols_from_enclosing_procs, ada_add_local_symbols) (ada_add_block_renamings): Adjust to use lookup_name_info. (ada_lookup_name): New. (add_nonlocal_symbols, ada_add_all_symbols) (ada_lookup_symbol_list_worker, ada_lookup_symbol_list) (ada_iterate_over_symbols): Adjust to use lookup_name_info. (ada_name_for_lookup): Delete. (ada_lookup_encoded_symbol): Construct a verbatim name. (wild_match): Reverse sense of return type. Use bool. (full_match): Reverse sense of return type. Inline bits of old match_name here. (ada_add_block_symbols): Adjust to use lookup_name_info. (symbol_completion_match): Delete, folded into... (ada_lookup_name_info::matches): ... .this new method. (symbol_completion_add): Delete. (ada_collect_symbol_completion_matches): Add name_match_type parameter. Adjust to use lookup_name_info and completion_list_add_name. (get_var_value, ada_add_global_exceptions): Adjust to use lookup_name_info. (ada_get_symbol_name_cmp): Delete. (do_wild_match, do_full_match): New functions. (ada_lookup_name_info::ada_lookup_name_info): New method. (ada_symbol_name_matches, ada_get_symbol_name_matcher): New functions. (ada_language_defn): Install ada_get_symbol_name_matcher. * ada-lex.l (processId): If name starts with '<', copy it verbatim. * block.c (block_iter_match_step, block_iter_match_first) (block_iter_match_next, block_lookup_symbol) (block_lookup_symbol_primary, block_find_symbol): Adjust to use lookup_name_info. * block.h (block_iter_match_first, block_iter_match_next) (ALL_BLOCK_SYMBOLS_WITH_NAME): Adjust to use lookup_name_info. * c-lang.c (c_language_defn, cplus_language_defn) (asm_language_defn, minimal_language_defn): Adjust comments to refer to la_get_symbol_name_matcher. * completer.c (complete_files_symbols) (collect_explicit_location_matches, symbol_completer): Pass a symbol_name_match_type down. * completer.h (class completion_match, completion_match_result): New classes. (completion_tracker::reset_completion_match_result): New method. (completion_tracker::m_completion_match_result): New field. * cp-support.c (make_symbol_overload_list_block): Adjust to use lookup_name_info. (cp_fq_symbol_name_matches, cp_get_symbol_name_matcher): New functions. * cp-support.h (cp_get_symbol_name_matcher): New declaration. * d-lang.c: Adjust comments to refer to la_get_symbol_name_matcher. * dictionary.c (dict_vector) <iter_match_first, iter_match_next>: Adjust to use lookup_name_info. (dict_iter_match_first, dict_iter_match_next) (iter_match_first_hashed, iter_match_next_hashed) (iter_match_first_linear, iter_match_next_linear): Adjust to work with a lookup_name_info. * dictionary.h (dict_iter_match_first, dict_iter_match_next): Likewise. * dwarf2read.c (dw2_lookup_symbol): Adjust to use lookup_name_info. (dw2_map_matching_symbols): Adjust to use symbol_name_match_type. (gdb_index_symbol_name_matcher): New class. (dw2_expand_symtabs_matching) Adjust to use lookup_name_info and gdb_index_symbol_name_matcher. Accept a NULL symbol_matcher. * f-lang.c (f_collect_symbol_completion_matches): Adjust to work with a symbol_name_match_type. (f_language_defn): Adjust comments to refer to la_get_symbol_name_matcher. * go-lang.c (go_language_defn): Adjust comments to refer to la_get_symbol_name_matcher. * language.c (default_symbol_name_matcher) (language_get_symbol_name_matcher): New functions. (unknown_language_defn, auto_language_defn): Adjust comments to refer to la_get_symbol_name_matcher. * language.h (symbol_name_cmp_ftype): Delete. (language_defn) <la_collect_symbol_completion_matches>: Add match type parameter. <la_get_symbol_name_cmp>: Delete field. <la_get_symbol_name_matcher>: New field. <la_iterate_over_symbols>: Adjust to use lookup_name_info. (default_symbol_name_matcher, language_get_symbol_name_matcher): Declare. * linespec.c (iterate_over_all_matching_symtabs) (iterate_over_file_blocks): Adjust to use lookup_name_info. (find_methods): Add language parameter, and use lookup_name_info and the language's symbol_name_matcher_ftype. (linespec_complete_function): Adjust. (lookup_prefix_sym): Use lookup_name_info. (add_all_symbol_names_from_pspace): Adjust. (find_superclass_methods): Add language parameter and pass it down. (find_method): Pass symbol language down. (find_linespec_symbols): Don't demangle or Ada encode here. (search_minsyms_for_name): Add lookup_name_info parameter. (add_matching_symbols_to_info): Add name_match_type parameter. Use lookup_name_info. * m2-lang.c (m2_language_defn): Adjust comments to refer to la_get_symbol_name_matcher. * minsyms.c: Include <algorithm>. (add_minsym_to_demangled_hash_table): Remove table parameter and add objfile parameter. Use search_name_hash, and add language to demangled languages vector. (struct found_minimal_symbols): New struct. (lookup_minimal_symbol_mangled, lookup_minimal_symbol_demangled): New functions. (lookup_minimal_symbol): Adjust to use them. Don't canonicalize input names here. Use lookup_name_info instead. Lookup up demangled names once for each language in the demangled names vector. (iterate_over_minimal_symbols): Use lookup_name_info. Lookup up demangled names once for each language in the demangled names vector. (build_minimal_symbol_hash_tables): Adjust. * minsyms.h (iterate_over_minimal_symbols): Adjust to pass down a lookup_name_info. * objc-lang.c (objc_language_defn): Adjust comment to refer to la_get_symbol_name_matcher. * objfiles.h: Include <vector>. (objfile_per_bfd_storage) <demangled_hash_languages>: New field. * opencl-lang.c (opencl_language_defn): Adjust comment to refer to la_get_symbol_name_matcher. * p-lang.c (pascal_language_defn): Adjust comment to refer to la_get_symbol_name_matcher. * psymtab.c (psym_lookup_symbol): Use lookup_name_info. (match_partial_symbol): Use symbol_name_match_type, lookup_name_info and psymbol_name_matches. (lookup_partial_symbol): Use lookup_name_info. (map_block): Use symbol_name_match_type and lookup_name_info. (psym_map_matching_symbols): Use symbol_name_match_type. (psymbol_name_matches): New. (recursively_search_psymtabs): Use lookup_name_info and psymbol_name_matches. Rename 'kind' parameter to 'domain'. (psym_expand_symtabs_matching): Use lookup_name_info. Rename 'kind' parameter to 'domain'. * rust-lang.c (rust_language_defn): Adjust comment to refer to la_get_symbol_name_matcher. * symfile-debug.c (debug_qf_map_matching_symbols) (debug_qf_map_matching_symbols): Use symbol_name_match_type. (debug_qf_expand_symtabs_matching): Use lookup_name_info. * symfile.c (expand_symtabs_matching): Use lookup_name_info. * symfile.h (quick_symbol_functions) <map_matching_symbols>: Adjust to use symbol_name_match_type. <expand_symtabs_matching>: Adjust to use lookup_name_info. (expand_symtabs_matching): Adjust to use lookup_name_info. * symmisc.c (maintenance_expand_symtabs): Use lookup_name_info::match_any (). * symtab.c (symbol_matches_search_name): New. (eq_symbol_entry): Adjust to use lookup_name_info and the language's matcher. (demangle_for_lookup_info::demangle_for_lookup_info): New. (lookup_name_info::match_any): New. (iterate_over_symbols, search_symbols): Use lookup_name_info. (compare_symbol_name): Add language, lookup_name_info and completion_match_result parameters, and use them. (completion_list_add_name): Make extern. Add language and lookup_name_info parameters. Use them. (completion_list_add_symbol, completion_list_add_msymbol) (completion_list_objc_symbol): Add lookup_name_info parameters and adjust. Pass down language. (completion_list_add_fields): Add lookup_name_info parameters and adjust. Pass down language. (add_symtab_completions): Add lookup_name_info parameters and adjust. (default_collect_symbol_completion_matches_break_on): Add name_match_type parameter, and use it. Use lookup_name_info. (default_collect_symbol_completion_matches) (collect_symbol_completion_matches): Add name_match_type parameter, and pass it down. (collect_symbol_completion_matches_type): Adjust. (collect_file_symbol_completion_matches): Add name_match_type parameter, and use lookup_name_info. * symtab.h: Include <string> and "common/gdb_optional.h". (enum class symbol_name_match_type): New. (class ada_lookup_name_info): New. (struct demangle_for_lookup_info): New. (class lookup_name_info): New. (symbol_name_matcher_ftype): New. (SYMBOL_MATCHES_SEARCH_NAME): Use symbol_matches_search_name. (symbol_matches_search_name): Declare. (MSYMBOL_MATCHES_SEARCH_NAME): Delete. (default_collect_symbol_completion_matches) (collect_symbol_completion_matches) (collect_file_symbol_completion_matches): Add name_match_type parameter. (iterate_over_symbols): Use lookup_name_info. (completion_list_add_name): Declare. * utils.c (enum class strncmp_iw_mode): Moved to utils.h. (strncmp_iw_with_mode): Now extern. * utils.h (enum class strncmp_iw_mode): Moved from utils.c. (strncmp_iw_with_mode): Declare. gdb/testsuite/ChangeLog: 2017-11-08 Pedro Alves <palves@redhat.com> * gdb.ada/complete.exp (p <Exported_Capitalized>): New test. (p Exported_Capitalized): New test. (p exported_capitalized): New test.
This commit is contained in:
parent
5ffa079369
commit
b5ec771e60
38 changed files with 1787 additions and 794 deletions
204
gdb/ChangeLog
204
gdb/ChangeLog
|
@ -1,3 +1,207 @@
|
||||||
|
2017-11-08 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
* ada-lang.c (ada_encode): Rename to ..
|
||||||
|
(ada_encode_1): ... this. Add throw_errors parameter and handle
|
||||||
|
it.
|
||||||
|
(ada_encode): Reimplement.
|
||||||
|
(match_name): Delete, folded into full_name.
|
||||||
|
(resolve_subexp): No longer pass the encoded name to
|
||||||
|
ada_lookup_symbol_list.
|
||||||
|
(should_use_wild_match): Delete.
|
||||||
|
(name_match_type_from_name): New.
|
||||||
|
(ada_lookup_simple_minsym): Use lookup_name_info and the
|
||||||
|
language's symbol_name_matcher_ftype.
|
||||||
|
(add_symbols_from_enclosing_procs, ada_add_local_symbols)
|
||||||
|
(ada_add_block_renamings): Adjust to use lookup_name_info.
|
||||||
|
(ada_lookup_name): New.
|
||||||
|
(add_nonlocal_symbols, ada_add_all_symbols)
|
||||||
|
(ada_lookup_symbol_list_worker, ada_lookup_symbol_list)
|
||||||
|
(ada_iterate_over_symbols): Adjust to use lookup_name_info.
|
||||||
|
(ada_name_for_lookup): Delete.
|
||||||
|
(ada_lookup_encoded_symbol): Construct a verbatim name.
|
||||||
|
(wild_match): Reverse sense of return type. Use bool.
|
||||||
|
(full_match): Reverse sense of return type. Inline bits of old
|
||||||
|
match_name here.
|
||||||
|
(ada_add_block_symbols): Adjust to use lookup_name_info.
|
||||||
|
(symbol_completion_match): Delete, folded into...
|
||||||
|
(ada_lookup_name_info::matches): ... .this new method.
|
||||||
|
(symbol_completion_add): Delete.
|
||||||
|
(ada_collect_symbol_completion_matches): Add name_match_type
|
||||||
|
parameter. Adjust to use lookup_name_info and
|
||||||
|
completion_list_add_name.
|
||||||
|
(get_var_value, ada_add_global_exceptions): Adjust to use
|
||||||
|
lookup_name_info.
|
||||||
|
(ada_get_symbol_name_cmp): Delete.
|
||||||
|
(do_wild_match, do_full_match): New functions.
|
||||||
|
(ada_lookup_name_info::ada_lookup_name_info): New method.
|
||||||
|
(ada_symbol_name_matches, ada_get_symbol_name_matcher): New
|
||||||
|
functions.
|
||||||
|
(ada_language_defn): Install ada_get_symbol_name_matcher.
|
||||||
|
* ada-lex.l (processId): If name starts with '<', copy it
|
||||||
|
verbatim.
|
||||||
|
* block.c (block_iter_match_step, block_iter_match_first)
|
||||||
|
(block_iter_match_next, block_lookup_symbol)
|
||||||
|
(block_lookup_symbol_primary, block_find_symbol): Adjust to use
|
||||||
|
lookup_name_info.
|
||||||
|
* block.h (block_iter_match_first, block_iter_match_next)
|
||||||
|
(ALL_BLOCK_SYMBOLS_WITH_NAME): Adjust to use lookup_name_info.
|
||||||
|
* c-lang.c (c_language_defn, cplus_language_defn)
|
||||||
|
(asm_language_defn, minimal_language_defn): Adjust comments to
|
||||||
|
refer to la_get_symbol_name_matcher.
|
||||||
|
* completer.c (complete_files_symbols)
|
||||||
|
(collect_explicit_location_matches, symbol_completer): Pass a
|
||||||
|
symbol_name_match_type down.
|
||||||
|
* completer.h (class completion_match, completion_match_result):
|
||||||
|
New classes.
|
||||||
|
(completion_tracker::reset_completion_match_result): New method.
|
||||||
|
(completion_tracker::m_completion_match_result): New field.
|
||||||
|
* cp-support.c (make_symbol_overload_list_block): Adjust to use
|
||||||
|
lookup_name_info.
|
||||||
|
(cp_fq_symbol_name_matches, cp_get_symbol_name_matcher): New
|
||||||
|
functions.
|
||||||
|
* cp-support.h (cp_get_symbol_name_matcher): New declaration.
|
||||||
|
* d-lang.c: Adjust comments to refer to
|
||||||
|
la_get_symbol_name_matcher.
|
||||||
|
* dictionary.c (dict_vector) <iter_match_first, iter_match_next>:
|
||||||
|
Adjust to use lookup_name_info.
|
||||||
|
(dict_iter_match_first, dict_iter_match_next)
|
||||||
|
(iter_match_first_hashed, iter_match_next_hashed)
|
||||||
|
(iter_match_first_linear, iter_match_next_linear): Adjust to work
|
||||||
|
with a lookup_name_info.
|
||||||
|
* dictionary.h (dict_iter_match_first, dict_iter_match_next):
|
||||||
|
Likewise.
|
||||||
|
* dwarf2read.c (dw2_lookup_symbol): Adjust to use lookup_name_info.
|
||||||
|
(dw2_map_matching_symbols): Adjust to use symbol_name_match_type.
|
||||||
|
(gdb_index_symbol_name_matcher): New class.
|
||||||
|
(dw2_expand_symtabs_matching) Adjust to use lookup_name_info and
|
||||||
|
gdb_index_symbol_name_matcher. Accept a NULL symbol_matcher.
|
||||||
|
* f-lang.c (f_collect_symbol_completion_matches): Adjust to work
|
||||||
|
with a symbol_name_match_type.
|
||||||
|
(f_language_defn): Adjust comments to refer to
|
||||||
|
la_get_symbol_name_matcher.
|
||||||
|
* go-lang.c (go_language_defn): Adjust comments to refer to
|
||||||
|
la_get_symbol_name_matcher.
|
||||||
|
* language.c (default_symbol_name_matcher)
|
||||||
|
(language_get_symbol_name_matcher): New functions.
|
||||||
|
(unknown_language_defn, auto_language_defn): Adjust comments to
|
||||||
|
refer to la_get_symbol_name_matcher.
|
||||||
|
* language.h (symbol_name_cmp_ftype): Delete.
|
||||||
|
(language_defn) <la_collect_symbol_completion_matches>: Add match
|
||||||
|
type parameter.
|
||||||
|
<la_get_symbol_name_cmp>: Delete field.
|
||||||
|
<la_get_symbol_name_matcher>: New field.
|
||||||
|
<la_iterate_over_symbols>: Adjust to use lookup_name_info.
|
||||||
|
(default_symbol_name_matcher, language_get_symbol_name_matcher):
|
||||||
|
Declare.
|
||||||
|
* linespec.c (iterate_over_all_matching_symtabs)
|
||||||
|
(iterate_over_file_blocks): Adjust to use lookup_name_info.
|
||||||
|
(find_methods): Add language parameter, and use lookup_name_info
|
||||||
|
and the language's symbol_name_matcher_ftype.
|
||||||
|
(linespec_complete_function): Adjust.
|
||||||
|
(lookup_prefix_sym): Use lookup_name_info.
|
||||||
|
(add_all_symbol_names_from_pspace): Adjust.
|
||||||
|
(find_superclass_methods): Add language parameter and pass it
|
||||||
|
down.
|
||||||
|
(find_method): Pass symbol language down.
|
||||||
|
(find_linespec_symbols): Don't demangle or Ada encode here.
|
||||||
|
(search_minsyms_for_name): Add lookup_name_info parameter.
|
||||||
|
(add_matching_symbols_to_info): Add name_match_type parameter.
|
||||||
|
Use lookup_name_info.
|
||||||
|
* m2-lang.c (m2_language_defn): Adjust comments to refer to
|
||||||
|
la_get_symbol_name_matcher.
|
||||||
|
* minsyms.c: Include <algorithm>.
|
||||||
|
(add_minsym_to_demangled_hash_table): Remove table parameter and
|
||||||
|
add objfile parameter. Use search_name_hash, and add language to
|
||||||
|
demangled languages vector.
|
||||||
|
(struct found_minimal_symbols): New struct.
|
||||||
|
(lookup_minimal_symbol_mangled, lookup_minimal_symbol_demangled):
|
||||||
|
New functions.
|
||||||
|
(lookup_minimal_symbol): Adjust to use them. Don't canonicalize
|
||||||
|
input names here. Use lookup_name_info instead. Lookup up
|
||||||
|
demangled names once for each language in the demangled names
|
||||||
|
vector.
|
||||||
|
(iterate_over_minimal_symbols): Use lookup_name_info. Lookup up
|
||||||
|
demangled names once for each language in the demangled names
|
||||||
|
vector.
|
||||||
|
(build_minimal_symbol_hash_tables): Adjust.
|
||||||
|
* minsyms.h (iterate_over_minimal_symbols): Adjust to pass down a
|
||||||
|
lookup_name_info.
|
||||||
|
* objc-lang.c (objc_language_defn): Adjust comment to refer to
|
||||||
|
la_get_symbol_name_matcher.
|
||||||
|
* objfiles.h: Include <vector>.
|
||||||
|
(objfile_per_bfd_storage) <demangled_hash_languages>: New field.
|
||||||
|
* opencl-lang.c (opencl_language_defn): Adjust comment to refer to
|
||||||
|
la_get_symbol_name_matcher.
|
||||||
|
* p-lang.c (pascal_language_defn): Adjust comment to refer to
|
||||||
|
la_get_symbol_name_matcher.
|
||||||
|
* psymtab.c (psym_lookup_symbol): Use lookup_name_info.
|
||||||
|
(match_partial_symbol): Use symbol_name_match_type,
|
||||||
|
lookup_name_info and psymbol_name_matches.
|
||||||
|
(lookup_partial_symbol): Use lookup_name_info.
|
||||||
|
(map_block): Use symbol_name_match_type and lookup_name_info.
|
||||||
|
(psym_map_matching_symbols): Use symbol_name_match_type.
|
||||||
|
(psymbol_name_matches): New.
|
||||||
|
(recursively_search_psymtabs): Use lookup_name_info and
|
||||||
|
psymbol_name_matches. Rename 'kind' parameter to 'domain'.
|
||||||
|
(psym_expand_symtabs_matching): Use lookup_name_info. Rename
|
||||||
|
'kind' parameter to 'domain'.
|
||||||
|
* rust-lang.c (rust_language_defn): Adjust comment to refer to
|
||||||
|
la_get_symbol_name_matcher.
|
||||||
|
* symfile-debug.c (debug_qf_map_matching_symbols)
|
||||||
|
(debug_qf_map_matching_symbols): Use symbol_name_match_type.
|
||||||
|
(debug_qf_expand_symtabs_matching): Use lookup_name_info.
|
||||||
|
* symfile.c (expand_symtabs_matching): Use lookup_name_info.
|
||||||
|
* symfile.h (quick_symbol_functions) <map_matching_symbols>:
|
||||||
|
Adjust to use symbol_name_match_type.
|
||||||
|
<expand_symtabs_matching>: Adjust to use lookup_name_info.
|
||||||
|
(expand_symtabs_matching): Adjust to use lookup_name_info.
|
||||||
|
* symmisc.c (maintenance_expand_symtabs): Use
|
||||||
|
lookup_name_info::match_any ().
|
||||||
|
* symtab.c (symbol_matches_search_name): New.
|
||||||
|
(eq_symbol_entry): Adjust to use lookup_name_info and the
|
||||||
|
language's matcher.
|
||||||
|
(demangle_for_lookup_info::demangle_for_lookup_info): New.
|
||||||
|
(lookup_name_info::match_any): New.
|
||||||
|
(iterate_over_symbols, search_symbols): Use lookup_name_info.
|
||||||
|
(compare_symbol_name): Add language, lookup_name_info and
|
||||||
|
completion_match_result parameters, and use them.
|
||||||
|
(completion_list_add_name): Make extern. Add language and
|
||||||
|
lookup_name_info parameters. Use them.
|
||||||
|
(completion_list_add_symbol, completion_list_add_msymbol)
|
||||||
|
(completion_list_objc_symbol): Add lookup_name_info parameters and
|
||||||
|
adjust. Pass down language.
|
||||||
|
(completion_list_add_fields): Add lookup_name_info parameters and
|
||||||
|
adjust. Pass down language.
|
||||||
|
(add_symtab_completions): Add lookup_name_info parameters and
|
||||||
|
adjust.
|
||||||
|
(default_collect_symbol_completion_matches_break_on): Add
|
||||||
|
name_match_type parameter, and use it. Use lookup_name_info.
|
||||||
|
(default_collect_symbol_completion_matches)
|
||||||
|
(collect_symbol_completion_matches): Add name_match_type
|
||||||
|
parameter, and pass it down.
|
||||||
|
(collect_symbol_completion_matches_type): Adjust.
|
||||||
|
(collect_file_symbol_completion_matches): Add name_match_type
|
||||||
|
parameter, and use lookup_name_info.
|
||||||
|
* symtab.h: Include <string> and "common/gdb_optional.h".
|
||||||
|
(enum class symbol_name_match_type): New.
|
||||||
|
(class ada_lookup_name_info): New.
|
||||||
|
(struct demangle_for_lookup_info): New.
|
||||||
|
(class lookup_name_info): New.
|
||||||
|
(symbol_name_matcher_ftype): New.
|
||||||
|
(SYMBOL_MATCHES_SEARCH_NAME): Use symbol_matches_search_name.
|
||||||
|
(symbol_matches_search_name): Declare.
|
||||||
|
(MSYMBOL_MATCHES_SEARCH_NAME): Delete.
|
||||||
|
(default_collect_symbol_completion_matches)
|
||||||
|
(collect_symbol_completion_matches)
|
||||||
|
(collect_file_symbol_completion_matches): Add name_match_type
|
||||||
|
parameter.
|
||||||
|
(iterate_over_symbols): Use lookup_name_info.
|
||||||
|
(completion_list_add_name): Declare.
|
||||||
|
* utils.c (enum class strncmp_iw_mode): Moved to utils.h.
|
||||||
|
(strncmp_iw_with_mode): Now extern.
|
||||||
|
* utils.h (enum class strncmp_iw_mode): Moved from utils.c.
|
||||||
|
(strncmp_iw_with_mode): Declare.
|
||||||
|
|
||||||
2017-11-08 Keith Seitz <keiths@redhat.com>
|
2017-11-08 Keith Seitz <keiths@redhat.com>
|
||||||
Pedro Alves <palves@redhat.com>
|
Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
|
732
gdb/ada-lang.c
732
gdb/ada-lang.c
File diff suppressed because it is too large
Load diff
|
@ -416,13 +416,12 @@ processReal (struct parser_state *par_state, const char *num0)
|
||||||
/* Store a canonicalized version of NAME0[0..LEN-1] in yylval.ssym. The
|
/* Store a canonicalized version of NAME0[0..LEN-1] in yylval.ssym. The
|
||||||
resulting string is valid until the next call to ada_parse. If
|
resulting string is valid until the next call to ada_parse. If
|
||||||
NAME0 contains the substring "___", it is assumed to be already
|
NAME0 contains the substring "___", it is assumed to be already
|
||||||
encoded and the resulting name is equal to it. Otherwise, it differs
|
encoded and the resulting name is equal to it. Similarly, if the name
|
||||||
|
starts with '<', it is copied verbatim. Otherwise, it differs
|
||||||
from NAME0 in that:
|
from NAME0 in that:
|
||||||
+ Characters between '...' or <...> are transfered verbatim to
|
+ Characters between '...' are transfered verbatim to yylval.ssym.
|
||||||
yylval.ssym.
|
+ Trailing "'" characters in quoted sequences are removed (a leading quote is
|
||||||
+ <, >, and trailing "'" characters in quoted sequences are removed
|
preserved to indicate that the name is not to be GNAT-encoded).
|
||||||
(a leading quote is preserved to indicate that the name is not to be
|
|
||||||
GNAT-encoded).
|
|
||||||
+ Unquoted whitespace is removed.
|
+ Unquoted whitespace is removed.
|
||||||
+ Unquoted alphabetic characters are mapped to lower case.
|
+ Unquoted alphabetic characters are mapped to lower case.
|
||||||
Result is returned as a struct stoken, but for convenience, the string
|
Result is returned as a struct stoken, but for convenience, the string
|
||||||
|
@ -440,7 +439,7 @@ processId (const char *name0, int len)
|
||||||
while (len > 0 && isspace (name0[len-1]))
|
while (len > 0 && isspace (name0[len-1]))
|
||||||
len -= 1;
|
len -= 1;
|
||||||
|
|
||||||
if (strstr (name0, "___") != NULL)
|
if (name0[0] == '<' || strstr (name0, "___") != NULL)
|
||||||
{
|
{
|
||||||
strncpy (name, name0, len);
|
strncpy (name, name0, len);
|
||||||
name[len] = '\000';
|
name[len] = '\000';
|
||||||
|
@ -474,15 +473,6 @@ processId (const char *name0, int len)
|
||||||
while (i0 < len && name0[i0] != '\'');
|
while (i0 < len && name0[i0] != '\'');
|
||||||
i0 += 1;
|
i0 += 1;
|
||||||
break;
|
break;
|
||||||
case '<':
|
|
||||||
i0 += 1;
|
|
||||||
while (i0 < len && name0[i0] != '>')
|
|
||||||
{
|
|
||||||
name[i] = name0[i0];
|
|
||||||
i += 1; i0 += 1;
|
|
||||||
}
|
|
||||||
i0 += 1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name[i] = '\000';
|
name[i] = '\000';
|
||||||
|
|
38
gdb/block.c
38
gdb/block.c
|
@ -595,8 +595,7 @@ block_iterator_next (struct block_iterator *iterator)
|
||||||
|
|
||||||
static struct symbol *
|
static struct symbol *
|
||||||
block_iter_match_step (struct block_iterator *iterator,
|
block_iter_match_step (struct block_iterator *iterator,
|
||||||
const char *name,
|
const lookup_name_info &name,
|
||||||
symbol_compare_ftype *compare,
|
|
||||||
int first)
|
int first)
|
||||||
{
|
{
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
@ -618,10 +617,10 @@ block_iter_match_step (struct block_iterator *iterator,
|
||||||
block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust),
|
block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust),
|
||||||
iterator->which);
|
iterator->which);
|
||||||
sym = dict_iter_match_first (BLOCK_DICT (block), name,
|
sym = dict_iter_match_first (BLOCK_DICT (block), name,
|
||||||
compare, &iterator->dict_iter);
|
&iterator->dict_iter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sym = dict_iter_match_next (name, compare, &iterator->dict_iter);
|
sym = dict_iter_match_next (name, &iterator->dict_iter);
|
||||||
|
|
||||||
if (sym != NULL)
|
if (sym != NULL)
|
||||||
return sym;
|
return sym;
|
||||||
|
@ -638,30 +637,27 @@ block_iter_match_step (struct block_iterator *iterator,
|
||||||
|
|
||||||
struct symbol *
|
struct symbol *
|
||||||
block_iter_match_first (const struct block *block,
|
block_iter_match_first (const struct block *block,
|
||||||
const char *name,
|
const lookup_name_info &name,
|
||||||
symbol_compare_ftype *compare,
|
|
||||||
struct block_iterator *iterator)
|
struct block_iterator *iterator)
|
||||||
{
|
{
|
||||||
initialize_block_iterator (block, iterator);
|
initialize_block_iterator (block, iterator);
|
||||||
|
|
||||||
if (iterator->which == FIRST_LOCAL_BLOCK)
|
if (iterator->which == FIRST_LOCAL_BLOCK)
|
||||||
return dict_iter_match_first (block->dict, name, compare,
|
return dict_iter_match_first (block->dict, name, &iterator->dict_iter);
|
||||||
&iterator->dict_iter);
|
|
||||||
|
|
||||||
return block_iter_match_step (iterator, name, compare, 1);
|
return block_iter_match_step (iterator, name, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See block.h. */
|
/* See block.h. */
|
||||||
|
|
||||||
struct symbol *
|
struct symbol *
|
||||||
block_iter_match_next (const char *name,
|
block_iter_match_next (const lookup_name_info &name,
|
||||||
symbol_compare_ftype *compare,
|
|
||||||
struct block_iterator *iterator)
|
struct block_iterator *iterator)
|
||||||
{
|
{
|
||||||
if (iterator->which == FIRST_LOCAL_BLOCK)
|
if (iterator->which == FIRST_LOCAL_BLOCK)
|
||||||
return dict_iter_match_next (name, compare, &iterator->dict_iter);
|
return dict_iter_match_next (name, &iterator->dict_iter);
|
||||||
|
|
||||||
return block_iter_match_step (iterator, name, compare, 0);
|
return block_iter_match_step (iterator, name, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See block.h.
|
/* See block.h.
|
||||||
|
@ -682,11 +678,13 @@ block_lookup_symbol (const struct block *block, const char *name,
|
||||||
struct block_iterator iter;
|
struct block_iterator iter;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
|
||||||
|
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
|
||||||
|
|
||||||
if (!BLOCK_FUNCTION (block))
|
if (!BLOCK_FUNCTION (block))
|
||||||
{
|
{
|
||||||
struct symbol *other = NULL;
|
struct symbol *other = NULL;
|
||||||
|
|
||||||
ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
|
ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
|
||||||
{
|
{
|
||||||
if (SYMBOL_DOMAIN (sym) == domain)
|
if (SYMBOL_DOMAIN (sym) == domain)
|
||||||
return sym;
|
return sym;
|
||||||
|
@ -713,7 +711,7 @@ block_lookup_symbol (const struct block *block, const char *name,
|
||||||
|
|
||||||
struct symbol *sym_found = NULL;
|
struct symbol *sym_found = NULL;
|
||||||
|
|
||||||
ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
|
ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
|
||||||
{
|
{
|
||||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
||||||
SYMBOL_DOMAIN (sym), domain))
|
SYMBOL_DOMAIN (sym), domain))
|
||||||
|
@ -738,14 +736,16 @@ block_lookup_symbol_primary (const struct block *block, const char *name,
|
||||||
struct symbol *sym, *other;
|
struct symbol *sym, *other;
|
||||||
struct dict_iterator dict_iter;
|
struct dict_iterator dict_iter;
|
||||||
|
|
||||||
|
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
|
||||||
|
|
||||||
/* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK. */
|
/* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK. */
|
||||||
gdb_assert (BLOCK_SUPERBLOCK (block) == NULL
|
gdb_assert (BLOCK_SUPERBLOCK (block) == NULL
|
||||||
|| BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL);
|
|| BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL);
|
||||||
|
|
||||||
other = NULL;
|
other = NULL;
|
||||||
for (sym = dict_iter_match_first (block->dict, name, strcmp_iw, &dict_iter);
|
for (sym = dict_iter_match_first (block->dict, lookup_name, &dict_iter);
|
||||||
sym != NULL;
|
sym != NULL;
|
||||||
sym = dict_iter_match_next (name, strcmp_iw, &dict_iter))
|
sym = dict_iter_match_next (lookup_name, &dict_iter))
|
||||||
{
|
{
|
||||||
if (SYMBOL_DOMAIN (sym) == domain)
|
if (SYMBOL_DOMAIN (sym) == domain)
|
||||||
return sym;
|
return sym;
|
||||||
|
@ -772,11 +772,13 @@ block_find_symbol (const struct block *block, const char *name,
|
||||||
struct block_iterator iter;
|
struct block_iterator iter;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
|
||||||
|
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
|
||||||
|
|
||||||
/* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK. */
|
/* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK. */
|
||||||
gdb_assert (BLOCK_SUPERBLOCK (block) == NULL
|
gdb_assert (BLOCK_SUPERBLOCK (block) == NULL
|
||||||
|| BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL);
|
|| BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL);
|
||||||
|
|
||||||
ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
|
ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
|
||||||
{
|
{
|
||||||
/* MATCHER is deliberately called second here so that it never sees
|
/* MATCHER is deliberately called second here so that it never sees
|
||||||
a non-domain-matching symbol. */
|
a non-domain-matching symbol. */
|
||||||
|
|
33
gdb/block.h
33
gdb/block.h
|
@ -237,27 +237,22 @@ extern struct symbol *block_iterator_first (const struct block *block,
|
||||||
extern struct symbol *block_iterator_next (struct block_iterator *iterator);
|
extern struct symbol *block_iterator_next (struct block_iterator *iterator);
|
||||||
|
|
||||||
/* Initialize ITERATOR to point at the first symbol in BLOCK whose
|
/* Initialize ITERATOR to point at the first symbol in BLOCK whose
|
||||||
SYMBOL_SEARCH_NAME is NAME, as tested using COMPARE (which must use
|
SYMBOL_SEARCH_NAME matches NAME, and return that first symbol, or
|
||||||
the same conventions as strcmp_iw and be compatible with any
|
NULL if there are no such symbols. */
|
||||||
block hashing function), and return that first symbol, or NULL
|
|
||||||
if there are no such symbols. */
|
|
||||||
|
|
||||||
extern struct symbol *block_iter_match_first (const struct block *block,
|
extern struct symbol *block_iter_match_first (const struct block *block,
|
||||||
const char *name,
|
const lookup_name_info &name,
|
||||||
symbol_compare_ftype *compare,
|
|
||||||
struct block_iterator *iterator);
|
struct block_iterator *iterator);
|
||||||
|
|
||||||
/* Advance ITERATOR to point at the next symbol in BLOCK whose
|
/* Advance ITERATOR to point at the next symbol in BLOCK whose
|
||||||
SYMBOL_SEARCH_NAME is NAME, as tested using COMPARE (see
|
SYMBOL_SEARCH_NAME matches NAME, or NULL if there are no more such
|
||||||
block_iter_match_first), or NULL if there are no more such symbols.
|
symbols. Don't call this if you've previously received NULL from
|
||||||
Don't call this if you've previously received NULL from
|
|
||||||
block_iterator_match_first or block_iterator_match_next on this
|
block_iterator_match_first or block_iterator_match_next on this
|
||||||
iteration. And don't call it unless ITERATOR was created by a
|
iteration. And don't call it unless ITERATOR was created by a
|
||||||
previous call to block_iter_match_first with the same NAME and COMPARE. */
|
previous call to block_iter_match_first with the same NAME. */
|
||||||
|
|
||||||
extern struct symbol *block_iter_match_next (const char *name,
|
extern struct symbol *block_iter_match_next
|
||||||
symbol_compare_ftype *compare,
|
(const lookup_name_info &name, struct block_iterator *iterator);
|
||||||
struct block_iterator *iterator);
|
|
||||||
|
|
||||||
/* Search BLOCK for symbol NAME in DOMAIN. */
|
/* Search BLOCK for symbol NAME in DOMAIN. */
|
||||||
|
|
||||||
|
@ -316,14 +311,14 @@ extern int block_find_non_opaque_type_preferred (struct symbol *sym,
|
||||||
(sym); \
|
(sym); \
|
||||||
(sym) = block_iterator_next (&(iter)))
|
(sym) = block_iterator_next (&(iter)))
|
||||||
|
|
||||||
/* Macro to loop through all symbols with name NAME in BLOCK,
|
/* Macro to loop through all symbols in BLOCK with a name that matches
|
||||||
in no particular order. ITER helps keep track of the iteration, and
|
NAME, in no particular order. ITER helps keep track of the
|
||||||
must be a struct block_iterator. SYM points to the current symbol. */
|
iteration, and must be a struct block_iterator. SYM points to the
|
||||||
|
current symbol. */
|
||||||
|
|
||||||
#define ALL_BLOCK_SYMBOLS_WITH_NAME(block, name, iter, sym) \
|
#define ALL_BLOCK_SYMBOLS_WITH_NAME(block, name, iter, sym) \
|
||||||
for ((sym) = block_iter_match_first ((block), (name), \
|
for ((sym) = block_iter_match_first ((block), (name), &(iter)); \
|
||||||
strcmp_iw, &(iter)); \
|
|
||||||
(sym) != NULL; \
|
(sym) != NULL; \
|
||||||
(sym) = block_iter_match_next ((name), strcmp_iw, &(iter)))
|
(sym) = block_iter_match_next ((name), &(iter)))
|
||||||
|
|
||||||
#endif /* BLOCK_H */
|
#endif /* BLOCK_H */
|
||||||
|
|
|
@ -869,7 +869,7 @@ extern const struct language_defn c_language_defn =
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_get_symbol_name_matcher */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&c_varobj_ops,
|
&c_varobj_ops,
|
||||||
|
@ -1014,7 +1014,7 @@ extern const struct language_defn cplus_language_defn =
|
||||||
cp_pass_by_reference,
|
cp_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
cp_get_symbol_name_matcher,
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&cplus_varobj_ops,
|
&cplus_varobj_ops,
|
||||||
|
@ -1068,7 +1068,7 @@ extern const struct language_defn asm_language_defn =
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_get_symbol_name_matcher */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&default_varobj_ops,
|
&default_varobj_ops,
|
||||||
|
@ -1122,7 +1122,7 @@ extern const struct language_defn minimal_language_defn =
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_get_symbol_name_matcher */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&default_varobj_ops,
|
&default_varobj_ops,
|
||||||
|
|
|
@ -499,6 +499,7 @@ complete_files_symbols (completion_tracker &tracker,
|
||||||
{
|
{
|
||||||
collect_file_symbol_completion_matches (tracker,
|
collect_file_symbol_completion_matches (tracker,
|
||||||
complete_symbol_mode::EXPRESSION,
|
complete_symbol_mode::EXPRESSION,
|
||||||
|
symbol_name_match_type::EXPRESSION,
|
||||||
symbol_start, word,
|
symbol_start, word,
|
||||||
file_to_match);
|
file_to_match);
|
||||||
xfree (file_to_match);
|
xfree (file_to_match);
|
||||||
|
@ -509,6 +510,7 @@ complete_files_symbols (completion_tracker &tracker,
|
||||||
|
|
||||||
collect_symbol_completion_matches (tracker,
|
collect_symbol_completion_matches (tracker,
|
||||||
complete_symbol_mode::EXPRESSION,
|
complete_symbol_mode::EXPRESSION,
|
||||||
|
symbol_name_match_type::EXPRESSION,
|
||||||
symbol_start, word);
|
symbol_start, word);
|
||||||
/* If text includes characters which cannot appear in a file
|
/* If text includes characters which cannot appear in a file
|
||||||
name, they cannot be asking for completion on files. */
|
name, they cannot be asking for completion on files. */
|
||||||
|
@ -551,6 +553,7 @@ complete_files_symbols (completion_tracker &tracker,
|
||||||
on the entire text as a symbol. */
|
on the entire text as a symbol. */
|
||||||
collect_symbol_completion_matches (tracker,
|
collect_symbol_completion_matches (tracker,
|
||||||
complete_symbol_mode::EXPRESSION,
|
complete_symbol_mode::EXPRESSION,
|
||||||
|
symbol_name_match_type::EXPRESSION,
|
||||||
orig_text, word);
|
orig_text, word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1104,6 +1107,7 @@ symbol_completer (struct cmd_list_element *ignore,
|
||||||
const char *text, const char *word)
|
const char *text, const char *word)
|
||||||
{
|
{
|
||||||
collect_symbol_completion_matches (tracker, complete_symbol_mode::EXPRESSION,
|
collect_symbol_completion_matches (tracker, complete_symbol_mode::EXPRESSION,
|
||||||
|
symbol_name_match_type::EXPRESSION,
|
||||||
text, word);
|
text, word);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,62 @@ struct match_list_displayer
|
||||||
calls free on each element. */
|
calls free on each element. */
|
||||||
typedef std::vector<gdb::unique_xmalloc_ptr<char>> completion_list;
|
typedef std::vector<gdb::unique_xmalloc_ptr<char>> completion_list;
|
||||||
|
|
||||||
|
/* The result of a successful completion match. When doing symbol
|
||||||
|
comparison, we use the symbol search name for the symbol name match
|
||||||
|
check, but the matched name that is shown to the user may be
|
||||||
|
different. For example, Ada uses encoded names for lookup, but
|
||||||
|
then wants to decode the symbol name to show to the user, and also
|
||||||
|
in some cases wrap the matched name in "<sym>" (meaning we can't
|
||||||
|
always use the symbol's print name). */
|
||||||
|
|
||||||
|
class completion_match
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* Get the completion match result. See m_match/m_storage's
|
||||||
|
descriptions. */
|
||||||
|
const char *match ()
|
||||||
|
{ return m_match; }
|
||||||
|
|
||||||
|
/* Set the completion match result. See m_match/m_storage's
|
||||||
|
descriptions. */
|
||||||
|
void set_match (const char *match)
|
||||||
|
{ m_match = match; }
|
||||||
|
|
||||||
|
/* Get temporary storage for generating a match result, dynamically.
|
||||||
|
The built string is only good until the next clear() call. I.e.,
|
||||||
|
good until the next symbol comparison. */
|
||||||
|
std::string &storage ()
|
||||||
|
{ return m_storage; }
|
||||||
|
|
||||||
|
/* Prepare for another completion matching sequence. */
|
||||||
|
void clear ()
|
||||||
|
{
|
||||||
|
m_match = NULL;
|
||||||
|
m_storage.clear ();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* The completion match result. This can either be a pointer into
|
||||||
|
M_STORAGE string, or it can be a pointer into the some other
|
||||||
|
string that outlives the completion matching sequence (usually, a
|
||||||
|
pointer to a symbol's name). */
|
||||||
|
const char *m_match;
|
||||||
|
|
||||||
|
/* Storage a symbol comparison routine can use for generating a
|
||||||
|
match result, dynamically. The built string is only good until
|
||||||
|
the next clear() call. I.e., good until the next symbol
|
||||||
|
comparison. */
|
||||||
|
std::string m_storage;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Convenience aggregate holding info returned by the symbol name
|
||||||
|
matching routines (see symbol_name_matcher_ftype). */
|
||||||
|
struct completion_match_result
|
||||||
|
{
|
||||||
|
/* The completion match candidate. */
|
||||||
|
completion_match match;
|
||||||
|
};
|
||||||
|
|
||||||
/* The final result of a completion that is handed over to either
|
/* The final result of a completion that is handed over to either
|
||||||
readline or the "completion" command (which pretends to be
|
readline or the "completion" command (which pretends to be
|
||||||
readline). Mainly a wrapper for a readline-style match list array,
|
readline). Mainly a wrapper for a readline-style match list array,
|
||||||
|
@ -203,6 +259,18 @@ public:
|
||||||
already have. */
|
already have. */
|
||||||
bool completes_to_completion_word (const char *word);
|
bool completes_to_completion_word (const char *word);
|
||||||
|
|
||||||
|
/* Get a reference to the shared (between all the multiple symbol
|
||||||
|
name comparison calls) completion_match_result object, ready for
|
||||||
|
another symbol name match sequence. */
|
||||||
|
completion_match_result &reset_completion_match_result ()
|
||||||
|
{
|
||||||
|
completion_match_result &res = m_completion_match_result;
|
||||||
|
|
||||||
|
/* Clear any previous match. */
|
||||||
|
res.match.clear ();
|
||||||
|
return m_completion_match_result;
|
||||||
|
}
|
||||||
|
|
||||||
/* True if we have any completion match recorded. */
|
/* True if we have any completion match recorded. */
|
||||||
bool have_completions () const
|
bool have_completions () const
|
||||||
{ return !m_entries_vec.empty (); }
|
{ return !m_entries_vec.empty (); }
|
||||||
|
@ -228,6 +296,13 @@ private:
|
||||||
to hand over to readline. */
|
to hand over to readline. */
|
||||||
void recompute_lowest_common_denominator (const char *new_match);
|
void recompute_lowest_common_denominator (const char *new_match);
|
||||||
|
|
||||||
|
/* Completion match outputs returned by the symbol name matching
|
||||||
|
routines (see symbol_name_matcher_ftype). These results are only
|
||||||
|
valid for a single match call. This is here in order to be able
|
||||||
|
to conveniently share the same storage among all the calls to the
|
||||||
|
symbol name matching routines. */
|
||||||
|
completion_match_result m_completion_match_result;
|
||||||
|
|
||||||
/* The completion matches found so far, in a vector. */
|
/* The completion matches found so far, in a vector. */
|
||||||
completion_list m_entries_vec;
|
completion_list m_entries_vec;
|
||||||
|
|
||||||
|
|
|
@ -1181,7 +1181,9 @@ make_symbol_overload_list_block (const char *name,
|
||||||
struct block_iterator iter;
|
struct block_iterator iter;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
|
||||||
ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
|
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
|
||||||
|
|
||||||
|
ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
|
||||||
overload_list_add_symbol (sym, name);
|
overload_list_add_symbol (sym, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1564,6 +1566,40 @@ gdb_sniff_from_mangled_name (const char *mangled, char **demangled)
|
||||||
return *demangled != NULL;
|
return *demangled != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* C++ symbol_name_matcher_ftype implementation. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cp_fq_symbol_name_matches (const char *symbol_search_name,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
|
completion_match *match)
|
||||||
|
{
|
||||||
|
/* Get the demangled name. */
|
||||||
|
const std::string &name = lookup_name.cplus ().lookup_name ();
|
||||||
|
|
||||||
|
strncmp_iw_mode mode = (lookup_name.completion_mode ()
|
||||||
|
? strncmp_iw_mode::NORMAL
|
||||||
|
: strncmp_iw_mode::MATCH_PARAMS);
|
||||||
|
|
||||||
|
if (strncmp_iw_with_mode (symbol_search_name,
|
||||||
|
name.c_str (), name.size (),
|
||||||
|
mode) == 0)
|
||||||
|
{
|
||||||
|
if (match != NULL)
|
||||||
|
match->set_match (symbol_search_name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See cp-support.h. */
|
||||||
|
|
||||||
|
symbol_name_matcher_ftype *
|
||||||
|
cp_get_symbol_name_matcher (const lookup_name_info &lookup_name)
|
||||||
|
{
|
||||||
|
return cp_fq_symbol_name_matches;
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't allow just "maintenance cplus". */
|
/* Don't allow just "maintenance cplus". */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -108,6 +108,11 @@ extern struct symbol **make_symbol_overload_list_adl (struct type **arg_types,
|
||||||
extern struct type *cp_lookup_rtti_type (const char *name,
|
extern struct type *cp_lookup_rtti_type (const char *name,
|
||||||
struct block *block);
|
struct block *block);
|
||||||
|
|
||||||
|
/* Implement the "la_get_symbol_name_matcher" language_defn method for
|
||||||
|
C++. */
|
||||||
|
extern symbol_name_matcher_ftype *cp_get_symbol_name_matcher
|
||||||
|
(const lookup_name_info &lookup_name);
|
||||||
|
|
||||||
/* Functions/variables from cp-namespace.c. */
|
/* Functions/variables from cp-namespace.c. */
|
||||||
|
|
||||||
extern int cp_is_in_anonymous (const char *symbol_name);
|
extern int cp_is_in_anonymous (const char *symbol_name);
|
||||||
|
|
|
@ -245,7 +245,7 @@ extern const struct language_defn d_language_defn =
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_get_symbol_name_matcher */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&default_varobj_ops,
|
&default_varobj_ops,
|
||||||
|
|
|
@ -115,11 +115,9 @@ struct dict_vector
|
||||||
struct symbol *(*iterator_next) (struct dict_iterator *iterator);
|
struct symbol *(*iterator_next) (struct dict_iterator *iterator);
|
||||||
/* Functions to iterate over symbols with a given name. */
|
/* Functions to iterate over symbols with a given name. */
|
||||||
struct symbol *(*iter_match_first) (const struct dictionary *dict,
|
struct symbol *(*iter_match_first) (const struct dictionary *dict,
|
||||||
const char *name,
|
const lookup_name_info &name,
|
||||||
symbol_compare_ftype *equiv,
|
|
||||||
struct dict_iterator *iterator);
|
struct dict_iterator *iterator);
|
||||||
struct symbol *(*iter_match_next) (const char *name,
|
struct symbol *(*iter_match_next) (const lookup_name_info &name,
|
||||||
symbol_compare_ftype *equiv,
|
|
||||||
struct dict_iterator *iterator);
|
struct dict_iterator *iterator);
|
||||||
/* A size function, for maint print symtabs. */
|
/* A size function, for maint print symtabs. */
|
||||||
int (*size) (const struct dictionary *dict);
|
int (*size) (const struct dictionary *dict);
|
||||||
|
@ -239,12 +237,10 @@ static struct symbol *iterator_first_hashed (const struct dictionary *dict,
|
||||||
static struct symbol *iterator_next_hashed (struct dict_iterator *iterator);
|
static struct symbol *iterator_next_hashed (struct dict_iterator *iterator);
|
||||||
|
|
||||||
static struct symbol *iter_match_first_hashed (const struct dictionary *dict,
|
static struct symbol *iter_match_first_hashed (const struct dictionary *dict,
|
||||||
const char *name,
|
const lookup_name_info &name,
|
||||||
symbol_compare_ftype *compare,
|
|
||||||
struct dict_iterator *iterator);
|
struct dict_iterator *iterator);
|
||||||
|
|
||||||
static struct symbol *iter_match_next_hashed (const char *name,
|
static struct symbol *iter_match_next_hashed (const lookup_name_info &name,
|
||||||
symbol_compare_ftype *compare,
|
|
||||||
struct dict_iterator *iterator);
|
struct dict_iterator *iterator);
|
||||||
|
|
||||||
/* Functions only for DICT_HASHED. */
|
/* Functions only for DICT_HASHED. */
|
||||||
|
@ -269,12 +265,10 @@ static struct symbol *iterator_first_linear (const struct dictionary *dict,
|
||||||
static struct symbol *iterator_next_linear (struct dict_iterator *iterator);
|
static struct symbol *iterator_next_linear (struct dict_iterator *iterator);
|
||||||
|
|
||||||
static struct symbol *iter_match_first_linear (const struct dictionary *dict,
|
static struct symbol *iter_match_first_linear (const struct dictionary *dict,
|
||||||
const char *name,
|
const lookup_name_info &name,
|
||||||
symbol_compare_ftype *compare,
|
|
||||||
struct dict_iterator *iterator);
|
struct dict_iterator *iterator);
|
||||||
|
|
||||||
static struct symbol *iter_match_next_linear (const char *name,
|
static struct symbol *iter_match_next_linear (const lookup_name_info &name,
|
||||||
symbol_compare_ftype *compare,
|
|
||||||
struct dict_iterator *iterator);
|
struct dict_iterator *iterator);
|
||||||
|
|
||||||
static int size_linear (const struct dictionary *dict);
|
static int size_linear (const struct dictionary *dict);
|
||||||
|
@ -526,19 +520,18 @@ dict_iterator_next (struct dict_iterator *iterator)
|
||||||
|
|
||||||
struct symbol *
|
struct symbol *
|
||||||
dict_iter_match_first (const struct dictionary *dict,
|
dict_iter_match_first (const struct dictionary *dict,
|
||||||
const char *name, symbol_compare_ftype *compare,
|
const lookup_name_info &name,
|
||||||
struct dict_iterator *iterator)
|
struct dict_iterator *iterator)
|
||||||
{
|
{
|
||||||
return (DICT_VECTOR (dict))->iter_match_first (dict, name,
|
return (DICT_VECTOR (dict))->iter_match_first (dict, name, iterator);
|
||||||
compare, iterator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct symbol *
|
struct symbol *
|
||||||
dict_iter_match_next (const char *name, symbol_compare_ftype *compare,
|
dict_iter_match_next (const lookup_name_info &name,
|
||||||
struct dict_iterator *iterator)
|
struct dict_iterator *iterator)
|
||||||
{
|
{
|
||||||
return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator)))
|
return (DICT_VECTOR (DICT_ITERATOR_DICT (iterator)))
|
||||||
->iter_match_next (name, compare, iterator);
|
->iter_match_next (name, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -629,13 +622,15 @@ iterator_hashed_advance (struct dict_iterator *iterator)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct symbol *
|
static struct symbol *
|
||||||
iter_match_first_hashed (const struct dictionary *dict, const char *name,
|
iter_match_first_hashed (const struct dictionary *dict,
|
||||||
symbol_compare_ftype *compare,
|
const lookup_name_info &name,
|
||||||
struct dict_iterator *iterator)
|
struct dict_iterator *iterator)
|
||||||
{
|
{
|
||||||
unsigned int hash_index
|
const language_defn *lang = DICT_LANGUAGE (dict);
|
||||||
= (search_name_hash (DICT_LANGUAGE (dict)->la_language, name)
|
unsigned int hash_index = (name.search_name_hash (lang->la_language)
|
||||||
% DICT_HASHED_NBUCKETS (dict));
|
% DICT_HASHED_NBUCKETS (dict));
|
||||||
|
symbol_name_matcher_ftype *matches_name
|
||||||
|
= language_get_symbol_name_matcher (lang, name);
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
|
||||||
DICT_ITERATOR_DICT (iterator) = dict;
|
DICT_ITERATOR_DICT (iterator) = dict;
|
||||||
|
@ -649,11 +644,8 @@ iter_match_first_hashed (const struct dictionary *dict, const char *name,
|
||||||
sym = sym->hash_next)
|
sym = sym->hash_next)
|
||||||
{
|
{
|
||||||
/* Warning: the order of arguments to compare matters! */
|
/* Warning: the order of arguments to compare matters! */
|
||||||
if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0)
|
if (matches_name (SYMBOL_SEARCH_NAME (sym), name, NULL))
|
||||||
{
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DICT_ITERATOR_CURRENT (iterator) = sym;
|
DICT_ITERATOR_CURRENT (iterator) = sym;
|
||||||
|
@ -661,16 +653,19 @@ iter_match_first_hashed (const struct dictionary *dict, const char *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct symbol *
|
static struct symbol *
|
||||||
iter_match_next_hashed (const char *name, symbol_compare_ftype *compare,
|
iter_match_next_hashed (const lookup_name_info &name,
|
||||||
struct dict_iterator *iterator)
|
struct dict_iterator *iterator)
|
||||||
{
|
{
|
||||||
|
const language_defn *lang = DICT_LANGUAGE (DICT_ITERATOR_DICT (iterator));
|
||||||
|
symbol_name_matcher_ftype *matches_name
|
||||||
|
= language_get_symbol_name_matcher (lang, name);
|
||||||
struct symbol *next;
|
struct symbol *next;
|
||||||
|
|
||||||
for (next = DICT_ITERATOR_CURRENT (iterator)->hash_next;
|
for (next = DICT_ITERATOR_CURRENT (iterator)->hash_next;
|
||||||
next != NULL;
|
next != NULL;
|
||||||
next = next->hash_next)
|
next = next->hash_next)
|
||||||
{
|
{
|
||||||
if (compare (SYMBOL_SEARCH_NAME (next), name) == 0)
|
if (matches_name (SYMBOL_SEARCH_NAME (next), name, NULL))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -863,27 +858,32 @@ iterator_next_linear (struct dict_iterator *iterator)
|
||||||
|
|
||||||
static struct symbol *
|
static struct symbol *
|
||||||
iter_match_first_linear (const struct dictionary *dict,
|
iter_match_first_linear (const struct dictionary *dict,
|
||||||
const char *name, symbol_compare_ftype *compare,
|
const lookup_name_info &name,
|
||||||
struct dict_iterator *iterator)
|
struct dict_iterator *iterator)
|
||||||
{
|
{
|
||||||
DICT_ITERATOR_DICT (iterator) = dict;
|
DICT_ITERATOR_DICT (iterator) = dict;
|
||||||
DICT_ITERATOR_INDEX (iterator) = -1;
|
DICT_ITERATOR_INDEX (iterator) = -1;
|
||||||
|
|
||||||
return iter_match_next_linear (name, compare, iterator);
|
return iter_match_next_linear (name, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct symbol *
|
static struct symbol *
|
||||||
iter_match_next_linear (const char *name, symbol_compare_ftype *compare,
|
iter_match_next_linear (const lookup_name_info &name,
|
||||||
struct dict_iterator *iterator)
|
struct dict_iterator *iterator)
|
||||||
{
|
{
|
||||||
const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
|
const struct dictionary *dict = DICT_ITERATOR_DICT (iterator);
|
||||||
|
const language_defn *lang = DICT_LANGUAGE (dict);
|
||||||
|
symbol_name_matcher_ftype *matches_name
|
||||||
|
= language_get_symbol_name_matcher (lang, name);
|
||||||
|
|
||||||
int i, nsyms = DICT_LINEAR_NSYMS (dict);
|
int i, nsyms = DICT_LINEAR_NSYMS (dict);
|
||||||
struct symbol *sym, *retval = NULL;
|
struct symbol *sym, *retval = NULL;
|
||||||
|
|
||||||
for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nsyms; ++i)
|
for (i = DICT_ITERATOR_INDEX (iterator) + 1; i < nsyms; ++i)
|
||||||
{
|
{
|
||||||
sym = DICT_LINEAR_SYM (dict, i);
|
sym = DICT_LINEAR_SYM (dict, i);
|
||||||
if (compare (SYMBOL_SEARCH_NAME (sym), name) == 0)
|
|
||||||
|
if (matches_name (SYMBOL_SEARCH_NAME (sym), name, NULL))
|
||||||
{
|
{
|
||||||
retval = sym;
|
retval = sym;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -133,8 +133,7 @@ extern struct symbol *dict_iterator_next (struct dict_iterator *iterator);
|
||||||
if there are no such symbols. */
|
if there are no such symbols. */
|
||||||
|
|
||||||
extern struct symbol *dict_iter_match_first (const struct dictionary *dict,
|
extern struct symbol *dict_iter_match_first (const struct dictionary *dict,
|
||||||
const char *name,
|
const lookup_name_info &name,
|
||||||
symbol_compare_ftype *compare,
|
|
||||||
struct dict_iterator *iterator);
|
struct dict_iterator *iterator);
|
||||||
|
|
||||||
/* Advance ITERATOR to point at the next symbol in DICT whose
|
/* Advance ITERATOR to point at the next symbol in DICT whose
|
||||||
|
@ -145,8 +144,7 @@ extern struct symbol *dict_iter_match_first (const struct dictionary *dict,
|
||||||
iteration. And don't call it unless ITERATOR was created by a
|
iteration. And don't call it unless ITERATOR was created by a
|
||||||
previous call to dict_iter_match_first with the same NAME and COMPARE. */
|
previous call to dict_iter_match_first with the same NAME and COMPARE. */
|
||||||
|
|
||||||
extern struct symbol *dict_iter_match_next (const char *name,
|
extern struct symbol *dict_iter_match_next (const lookup_name_info &name,
|
||||||
symbol_compare_ftype *compare,
|
|
||||||
struct dict_iterator *iterator);
|
struct dict_iterator *iterator);
|
||||||
|
|
||||||
/* Return some notion of the size of the dictionary: the number of
|
/* Return some notion of the size of the dictionary: the number of
|
||||||
|
|
|
@ -3878,6 +3878,8 @@ dw2_lookup_symbol (struct objfile *objfile, int block_index,
|
||||||
|
|
||||||
dw2_setup (objfile);
|
dw2_setup (objfile);
|
||||||
|
|
||||||
|
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
|
||||||
|
|
||||||
index = dwarf2_per_objfile->index_table;
|
index = dwarf2_per_objfile->index_table;
|
||||||
|
|
||||||
/* index is NULL if OBJF_READNOW. */
|
/* index is NULL if OBJF_READNOW. */
|
||||||
|
@ -3904,10 +3906,10 @@ dw2_lookup_symbol (struct objfile *objfile, int block_index,
|
||||||
information (but NAME might contain it). */
|
information (but NAME might contain it). */
|
||||||
|
|
||||||
if (sym != NULL
|
if (sym != NULL
|
||||||
&& SYMBOL_MATCHES_SEARCH_NAME (sym, name))
|
&& SYMBOL_MATCHES_SEARCH_NAME (sym, lookup_name))
|
||||||
return stab;
|
return stab;
|
||||||
if (with_opaque != NULL
|
if (with_opaque != NULL
|
||||||
&& SYMBOL_MATCHES_SEARCH_NAME (with_opaque, name))
|
&& SYMBOL_MATCHES_SEARCH_NAME (with_opaque, lookup_name))
|
||||||
stab_best = stab;
|
stab_best = stab;
|
||||||
|
|
||||||
/* Keep looking through other CUs. */
|
/* Keep looking through other CUs. */
|
||||||
|
@ -4052,7 +4054,7 @@ dw2_map_matching_symbols (struct objfile *objfile,
|
||||||
int global,
|
int global,
|
||||||
int (*callback) (struct block *,
|
int (*callback) (struct block *,
|
||||||
struct symbol *, void *),
|
struct symbol *, void *),
|
||||||
void *data, symbol_compare_ftype *match,
|
void *data, symbol_name_match_type match,
|
||||||
symbol_compare_ftype *ordered_compare)
|
symbol_compare_ftype *ordered_compare)
|
||||||
{
|
{
|
||||||
/* Currently unimplemented; used for Ada. The function can be called if the
|
/* Currently unimplemented; used for Ada. The function can be called if the
|
||||||
|
@ -4060,10 +4062,96 @@ dw2_map_matching_symbols (struct objfile *objfile,
|
||||||
does not look for non-Ada symbols this function should just return. */
|
does not look for non-Ada symbols this function should just return. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Symbol name matcher for .gdb_index names.
|
||||||
|
|
||||||
|
Symbol names in .gdb_index have a few particularities:
|
||||||
|
|
||||||
|
- There's no indication of which is the language of each symbol.
|
||||||
|
|
||||||
|
Since each language has its own symbol name matching algorithm,
|
||||||
|
and we don't know which language is the right one, we must match
|
||||||
|
each symbol against all languages.
|
||||||
|
|
||||||
|
- Symbol names in the index have no overload (parameter)
|
||||||
|
information. I.e., in C++, "foo(int)" and "foo(long)" both
|
||||||
|
appear as "foo" in the index, for example.
|
||||||
|
|
||||||
|
This means that the lookup names passed to the symbol name
|
||||||
|
matcher functions must have no parameter information either
|
||||||
|
because (e.g.) symbol search name "foo" does not match
|
||||||
|
lookup-name "foo(int)" [while swapping search name for lookup
|
||||||
|
name would match].
|
||||||
|
*/
|
||||||
|
class gdb_index_symbol_name_matcher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* Prepares the vector of comparison functions for LOOKUP_NAME. */
|
||||||
|
gdb_index_symbol_name_matcher (const lookup_name_info &lookup_name);
|
||||||
|
|
||||||
|
/* Walk all the matcher routines and match SYMBOL_NAME against them.
|
||||||
|
Returns true if any matcher matches. */
|
||||||
|
bool matches (const char *symbol_name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* A reference to the lookup name we're matching against. */
|
||||||
|
const lookup_name_info &m_lookup_name;
|
||||||
|
|
||||||
|
/* A vector holding all the different symbol name matchers, for all
|
||||||
|
languages. */
|
||||||
|
std::vector<symbol_name_matcher_ftype *> m_symbol_name_matcher_funcs;
|
||||||
|
};
|
||||||
|
|
||||||
|
gdb_index_symbol_name_matcher::gdb_index_symbol_name_matcher
|
||||||
|
(const lookup_name_info &lookup_name)
|
||||||
|
: m_lookup_name (lookup_name)
|
||||||
|
{
|
||||||
|
/* Prepare the vector of comparison functions upfront, to avoid
|
||||||
|
doing the same work for each symbol. Care is taken to avoid
|
||||||
|
matching with the same matcher more than once if/when multiple
|
||||||
|
languages use the same matcher function. */
|
||||||
|
auto &matchers = m_symbol_name_matcher_funcs;
|
||||||
|
matchers.reserve (nr_languages);
|
||||||
|
|
||||||
|
matchers.push_back (default_symbol_name_matcher);
|
||||||
|
|
||||||
|
for (int i = 0; i < nr_languages; i++)
|
||||||
|
{
|
||||||
|
const language_defn *lang = language_def ((enum language) i);
|
||||||
|
if (lang->la_get_symbol_name_matcher != NULL)
|
||||||
|
{
|
||||||
|
symbol_name_matcher_ftype *name_matcher
|
||||||
|
= lang->la_get_symbol_name_matcher (m_lookup_name);
|
||||||
|
|
||||||
|
/* Don't insert the same comparison routine more than once.
|
||||||
|
Note that we do this linear walk instead of a cheaper
|
||||||
|
sorted insert, or use a std::set or something like that,
|
||||||
|
because relative order of function addresses is not
|
||||||
|
stable. This is not a problem in practice because the
|
||||||
|
number of supported languages is low, and the cost here
|
||||||
|
is tiny compared to the number of searches we'll do
|
||||||
|
afterwards using this object. */
|
||||||
|
if (std::find (matchers.begin (), matchers.end (), name_matcher)
|
||||||
|
== matchers.end ())
|
||||||
|
matchers.push_back (name_matcher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
gdb_index_symbol_name_matcher::matches (const char *symbol_name)
|
||||||
|
{
|
||||||
|
for (auto matches_name : m_symbol_name_matcher_funcs)
|
||||||
|
if (matches_name (symbol_name, m_lookup_name, NULL))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dw2_expand_symtabs_matching
|
dw2_expand_symtabs_matching
|
||||||
(struct objfile *objfile,
|
(struct objfile *objfile,
|
||||||
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
|
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
||||||
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
||||||
enum search_domain kind)
|
enum search_domain kind)
|
||||||
|
@ -4151,6 +4239,8 @@ dw2_expand_symtabs_matching
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gdb_index_symbol_name_matcher lookup_name_matcher (lookup_name);
|
||||||
|
|
||||||
for (iter = 0; iter < index->symbol_table_slots; ++iter)
|
for (iter = 0; iter < index->symbol_table_slots; ++iter)
|
||||||
{
|
{
|
||||||
offset_type idx = 2 * iter;
|
offset_type idx = 2 * iter;
|
||||||
|
@ -4165,7 +4255,8 @@ dw2_expand_symtabs_matching
|
||||||
|
|
||||||
name = index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]);
|
name = index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]);
|
||||||
|
|
||||||
if (!symbol_matcher (name))
|
if (!lookup_name_matcher.matches (name)
|
||||||
|
|| (symbol_matcher != NULL && !symbol_matcher (name)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* The name was matched, now expand corresponding CUs that were
|
/* The name was matched, now expand corresponding CUs that were
|
||||||
|
|
|
@ -229,10 +229,12 @@ f_word_break_characters (void)
|
||||||
static void
|
static void
|
||||||
f_collect_symbol_completion_matches (completion_tracker &tracker,
|
f_collect_symbol_completion_matches (completion_tracker &tracker,
|
||||||
complete_symbol_mode mode,
|
complete_symbol_mode mode,
|
||||||
|
symbol_name_match_type compare_name,
|
||||||
const char *text, const char *word,
|
const char *text, const char *word,
|
||||||
enum type_code code)
|
enum type_code code)
|
||||||
{
|
{
|
||||||
default_collect_symbol_completion_matches_break_on (tracker, mode,
|
default_collect_symbol_completion_matches_break_on (tracker, mode,
|
||||||
|
compare_name,
|
||||||
text, word, ":", code);
|
text, word, ":", code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +291,7 @@ extern const struct language_defn f_language_defn =
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_get_symbol_name_matcher */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&default_varobj_ops,
|
&default_varobj_ops,
|
||||||
|
|
|
@ -606,7 +606,7 @@ extern const struct language_defn go_language_defn =
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_get_symbol_name_matcher */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&default_varobj_ops,
|
&default_varobj_ops,
|
||||||
|
|
|
@ -699,6 +699,41 @@ default_get_string (struct value *value, gdb_byte **buffer, int *length,
|
||||||
error (_("Getting a string is unsupported in this language."));
|
error (_("Getting a string is unsupported in this language."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See language.h. */
|
||||||
|
|
||||||
|
bool
|
||||||
|
default_symbol_name_matcher (const char *symbol_search_name,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
|
completion_match *match)
|
||||||
|
{
|
||||||
|
const std::string &name = lookup_name.name ();
|
||||||
|
|
||||||
|
strncmp_iw_mode mode = (lookup_name.completion_mode ()
|
||||||
|
? strncmp_iw_mode::NORMAL
|
||||||
|
: strncmp_iw_mode::MATCH_PARAMS);
|
||||||
|
|
||||||
|
if (strncmp_iw_with_mode (symbol_search_name, name.c_str (), name.size (),
|
||||||
|
mode) == 0)
|
||||||
|
{
|
||||||
|
if (match != NULL)
|
||||||
|
match->set_match (symbol_search_name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See language.h. */
|
||||||
|
|
||||||
|
symbol_name_matcher_ftype *
|
||||||
|
language_get_symbol_name_matcher (const language_defn *lang,
|
||||||
|
const lookup_name_info &lookup_name)
|
||||||
|
{
|
||||||
|
if (lang->la_get_symbol_name_matcher != nullptr)
|
||||||
|
return lang->la_get_symbol_name_matcher (lookup_name);
|
||||||
|
return default_symbol_name_matcher;
|
||||||
|
}
|
||||||
|
|
||||||
/* Define the language that is no language. */
|
/* Define the language that is no language. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -837,7 +872,7 @@ const struct language_defn unknown_language_defn =
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_get_symbol_name_matcher */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&default_varobj_ops,
|
&default_varobj_ops,
|
||||||
|
@ -888,7 +923,7 @@ const struct language_defn auto_language_defn =
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_get_symbol_name_matcher */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&default_varobj_ops,
|
&default_varobj_ops,
|
||||||
|
|
|
@ -126,16 +126,6 @@ struct language_arch_info
|
||||||
struct type *bool_type_default;
|
struct type *bool_type_default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A pointer to a function expected to return nonzero if
|
|
||||||
SYMBOL_SEARCH_NAME matches the given LOOKUP_NAME.
|
|
||||||
|
|
||||||
SYMBOL_SEARCH_NAME should be a symbol's "search" name.
|
|
||||||
LOOKUP_NAME should be the name of an entity after it has been
|
|
||||||
transformed for lookup. */
|
|
||||||
|
|
||||||
typedef int (*symbol_name_cmp_ftype) (const char *symbol_search_name,
|
|
||||||
const char *lookup_name);
|
|
||||||
|
|
||||||
/* Structure tying together assorted information about a language. */
|
/* Structure tying together assorted information about a language. */
|
||||||
|
|
||||||
struct language_defn
|
struct language_defn
|
||||||
|
@ -331,6 +321,7 @@ struct language_defn
|
||||||
void (*la_collect_symbol_completion_matches)
|
void (*la_collect_symbol_completion_matches)
|
||||||
(completion_tracker &tracker,
|
(completion_tracker &tracker,
|
||||||
complete_symbol_mode mode,
|
complete_symbol_mode mode,
|
||||||
|
symbol_name_match_type match_type,
|
||||||
const char *text,
|
const char *text,
|
||||||
const char *word,
|
const char *word,
|
||||||
enum type_code code);
|
enum type_code code);
|
||||||
|
@ -367,13 +358,18 @@ struct language_defn
|
||||||
gdb::unique_xmalloc_ptr<char> (*la_watch_location_expression)
|
gdb::unique_xmalloc_ptr<char> (*la_watch_location_expression)
|
||||||
(struct type *type, CORE_ADDR addr);
|
(struct type *type, CORE_ADDR addr);
|
||||||
|
|
||||||
/* Return a pointer to the function that should be used to match
|
/* Return a pointer to the function that should be used to match a
|
||||||
a symbol name against LOOKUP_NAME. This is mostly for languages
|
symbol name against LOOKUP_NAME, according to this language's
|
||||||
such as Ada where the matching algorithm depends on LOOKUP_NAME.
|
rules. The matching algorithm depends on LOOKUP_NAME. For
|
||||||
|
example, on Ada, the matching algorithm depends on the symbol
|
||||||
|
name (wild/full/verbatim matching), and on whether we're doing
|
||||||
|
a normal lookup or a completion match lookup.
|
||||||
|
|
||||||
This field may be NULL, in which case strcmp_iw will be used
|
This field may be NULL, in which case
|
||||||
to perform the matching. */
|
default_symbol_name_matcher is used to perform the
|
||||||
symbol_name_cmp_ftype (*la_get_symbol_name_cmp) (const char *lookup_name);
|
matching. */
|
||||||
|
symbol_name_matcher_ftype *(*la_get_symbol_name_matcher)
|
||||||
|
(const lookup_name_info &);
|
||||||
|
|
||||||
/* Find all symbols in the current program space matching NAME in
|
/* Find all symbols in the current program space matching NAME in
|
||||||
DOMAIN, according to this language's rules.
|
DOMAIN, according to this language's rules.
|
||||||
|
@ -389,7 +385,8 @@ struct language_defn
|
||||||
special processing here, 'iterate_over_symbols' should be
|
special processing here, 'iterate_over_symbols' should be
|
||||||
used as the definition. */
|
used as the definition. */
|
||||||
void (*la_iterate_over_symbols)
|
void (*la_iterate_over_symbols)
|
||||||
(const struct block *block, const char *name, domain_enum domain,
|
(const struct block *block, const lookup_name_info &name,
|
||||||
|
domain_enum domain,
|
||||||
gdb::function_view<symbol_found_callback_ftype> callback);
|
gdb::function_view<symbol_found_callback_ftype> callback);
|
||||||
|
|
||||||
/* Hash the given symbol search name. Use
|
/* Hash the given symbol search name. Use
|
||||||
|
@ -627,6 +624,18 @@ extern unsigned int default_search_name_hash (const char *search_name);
|
||||||
void c_get_string (struct value *value, gdb_byte **buffer, int *length,
|
void c_get_string (struct value *value, gdb_byte **buffer, int *length,
|
||||||
struct type **char_type, const char **charset);
|
struct type **char_type, const char **charset);
|
||||||
|
|
||||||
|
/* The default implementation of la_symbol_name_matcher. Matches with
|
||||||
|
strncmp_iw. */
|
||||||
|
extern bool default_symbol_name_matcher
|
||||||
|
(const char *symbol_search_name,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
|
completion_match *match);
|
||||||
|
|
||||||
|
/* Get LANG's symbol_name_matcher method for LOOKUP_NAME. Returns
|
||||||
|
default_symbol_name_matcher if not set. */
|
||||||
|
symbol_name_matcher_ftype *language_get_symbol_name_matcher
|
||||||
|
(const language_defn *lang, const lookup_name_info &lookup_name);
|
||||||
|
|
||||||
/* The languages supported by GDB. */
|
/* The languages supported by GDB. */
|
||||||
|
|
||||||
extern const struct language_defn auto_language_defn;
|
extern const struct language_defn auto_language_defn;
|
||||||
|
|
132
gdb/linespec.c
132
gdb/linespec.c
|
@ -334,7 +334,8 @@ typedef struct ls_parser linespec_parser;
|
||||||
/* Prototypes for local functions. */
|
/* Prototypes for local functions. */
|
||||||
|
|
||||||
static void iterate_over_file_blocks
|
static void iterate_over_file_blocks
|
||||||
(struct symtab *symtab, const char *name, domain_enum domain,
|
(struct symtab *symtab, const lookup_name_info &name,
|
||||||
|
domain_enum domain,
|
||||||
gdb::function_view<symbol_found_callback_ftype> callback);
|
gdb::function_view<symbol_found_callback_ftype> callback);
|
||||||
|
|
||||||
static void initialize_defaults (struct symtab **default_symtab,
|
static void initialize_defaults (struct symtab **default_symtab,
|
||||||
|
@ -369,6 +370,7 @@ static int symbol_to_sal (struct symtab_and_line *result,
|
||||||
int funfirstline, struct symbol *sym);
|
int funfirstline, struct symbol *sym);
|
||||||
|
|
||||||
static void add_matching_symbols_to_info (const char *name,
|
static void add_matching_symbols_to_info (const char *name,
|
||||||
|
symbol_name_match_type name_match_type,
|
||||||
struct collect_info *info,
|
struct collect_info *info,
|
||||||
struct program_space *pspace);
|
struct program_space *pspace);
|
||||||
|
|
||||||
|
@ -1101,19 +1103,15 @@ maybe_add_address (htab_t set, struct program_space *pspace, CORE_ADDR addr)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iterate_over_all_matching_symtabs
|
iterate_over_all_matching_symtabs
|
||||||
(struct linespec_state *state, const char *name, const domain_enum domain,
|
(struct linespec_state *state,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
|
const domain_enum name_domain,
|
||||||
struct program_space *search_pspace, bool include_inline,
|
struct program_space *search_pspace, bool include_inline,
|
||||||
gdb::function_view<symbol_found_callback_ftype> callback)
|
gdb::function_view<symbol_found_callback_ftype> callback)
|
||||||
{
|
{
|
||||||
struct objfile *objfile;
|
struct objfile *objfile;
|
||||||
struct program_space *pspace;
|
struct program_space *pspace;
|
||||||
|
|
||||||
/* The routine to be used for comparison. */
|
|
||||||
symbol_name_cmp_ftype symbol_name_cmp
|
|
||||||
= (state->language->la_get_symbol_name_cmp != NULL
|
|
||||||
? state->language->la_get_symbol_name_cmp (name)
|
|
||||||
: strcmp_iw);
|
|
||||||
|
|
||||||
ALL_PSPACES (pspace)
|
ALL_PSPACES (pspace)
|
||||||
{
|
{
|
||||||
if (search_pspace != NULL && search_pspace != pspace)
|
if (search_pspace != NULL && search_pspace != pspace)
|
||||||
|
@ -1128,21 +1126,17 @@ iterate_over_all_matching_symtabs
|
||||||
struct compunit_symtab *cu;
|
struct compunit_symtab *cu;
|
||||||
|
|
||||||
if (objfile->sf)
|
if (objfile->sf)
|
||||||
objfile->sf->qf->expand_symtabs_matching
|
objfile->sf->qf->expand_symtabs_matching (objfile,
|
||||||
(objfile,
|
NULL,
|
||||||
NULL,
|
lookup_name,
|
||||||
[&] (const char *symbol_name)
|
NULL, NULL,
|
||||||
{
|
ALL_DOMAIN);
|
||||||
return symbol_name_cmp (symbol_name, name) == 0;
|
|
||||||
},
|
|
||||||
NULL,
|
|
||||||
ALL_DOMAIN);
|
|
||||||
|
|
||||||
ALL_OBJFILE_COMPUNITS (objfile, cu)
|
ALL_OBJFILE_COMPUNITS (objfile, cu)
|
||||||
{
|
{
|
||||||
struct symtab *symtab = COMPUNIT_FILETABS (cu);
|
struct symtab *symtab = COMPUNIT_FILETABS (cu);
|
||||||
|
|
||||||
iterate_over_file_blocks (symtab, name, domain, callback);
|
iterate_over_file_blocks (symtab, lookup_name, name_domain, callback);
|
||||||
|
|
||||||
if (include_inline)
|
if (include_inline)
|
||||||
{
|
{
|
||||||
|
@ -1155,7 +1149,7 @@ iterate_over_all_matching_symtabs
|
||||||
{
|
{
|
||||||
block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
|
block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
|
||||||
state->language->la_iterate_over_symbols
|
state->language->la_iterate_over_symbols
|
||||||
(block, name, domain, [&] (symbol *sym)
|
(block, lookup_name, name_domain, [&] (symbol *sym)
|
||||||
{
|
{
|
||||||
/* Restrict calls to CALLBACK to symbols
|
/* Restrict calls to CALLBACK to symbols
|
||||||
representing inline symbols only. */
|
representing inline symbols only. */
|
||||||
|
@ -1192,8 +1186,8 @@ get_current_search_block (void)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iterate_over_file_blocks
|
iterate_over_file_blocks
|
||||||
(struct symtab *symtab, const char *name, domain_enum domain,
|
(struct symtab *symtab, const lookup_name_info &name,
|
||||||
gdb::function_view<symbol_found_callback_ftype> callback)
|
domain_enum domain, gdb::function_view<symbol_found_callback_ftype> callback)
|
||||||
{
|
{
|
||||||
struct block *block;
|
struct block *block;
|
||||||
|
|
||||||
|
@ -1203,12 +1197,12 @@ iterate_over_file_blocks
|
||||||
LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback);
|
LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A helper for find_method. This finds all methods in type T which
|
/* A helper for find_method. This finds all methods in type T of
|
||||||
match NAME. It adds matching symbol names to RESULT_NAMES, and
|
language T_LANG which match NAME. It adds matching symbol names to
|
||||||
adds T's direct superclasses to SUPERCLASSES. */
|
RESULT_NAMES, and adds T's direct superclasses to SUPERCLASSES. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
find_methods (struct type *t, const char *name,
|
find_methods (struct type *t, enum language t_lang, const char *name,
|
||||||
VEC (const_char_ptr) **result_names,
|
VEC (const_char_ptr) **result_names,
|
||||||
VEC (typep) **superclasses)
|
VEC (typep) **superclasses)
|
||||||
{
|
{
|
||||||
|
@ -1221,6 +1215,9 @@ find_methods (struct type *t, const char *name,
|
||||||
if (class_name)
|
if (class_name)
|
||||||
{
|
{
|
||||||
int method_counter;
|
int method_counter;
|
||||||
|
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
|
||||||
|
symbol_name_matcher_ftype *symbol_name_compare
|
||||||
|
= language_get_symbol_name_matcher (language_def (t_lang), lookup_name);
|
||||||
|
|
||||||
t = check_typedef (t);
|
t = check_typedef (t);
|
||||||
|
|
||||||
|
@ -1245,7 +1242,7 @@ find_methods (struct type *t, const char *name,
|
||||||
method_name = dem_opname;
|
method_name = dem_opname;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp_iw (method_name, name) == 0)
|
if (symbol_name_compare (method_name, lookup_name, NULL))
|
||||||
{
|
{
|
||||||
int field_counter;
|
int field_counter;
|
||||||
|
|
||||||
|
@ -2831,15 +2828,19 @@ linespec_complete_function (completion_tracker &tracker,
|
||||||
const char *source_filename)
|
const char *source_filename)
|
||||||
{
|
{
|
||||||
complete_symbol_mode mode = complete_symbol_mode::LINESPEC;
|
complete_symbol_mode mode = complete_symbol_mode::LINESPEC;
|
||||||
|
symbol_name_match_type func_match_type = symbol_name_match_type::WILD;
|
||||||
|
|
||||||
if (source_filename != NULL)
|
if (source_filename != NULL)
|
||||||
{
|
{
|
||||||
collect_file_symbol_completion_matches (tracker, mode,
|
collect_file_symbol_completion_matches (tracker, mode, func_match_type,
|
||||||
function, function,
|
function, function, source_filename);
|
||||||
source_filename);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
collect_symbol_completion_matches (tracker, mode, function, function);
|
{
|
||||||
|
collect_symbol_completion_matches (tracker, mode, func_match_type,
|
||||||
|
function, function);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper for complete_linespec to simplify it. SOURCE_FILENAME is
|
/* Helper for complete_linespec to simplify it. SOURCE_FILENAME is
|
||||||
|
@ -3576,14 +3577,18 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs,
|
||||||
struct symtab *elt;
|
struct symtab *elt;
|
||||||
decode_compound_collector collector;
|
decode_compound_collector collector;
|
||||||
|
|
||||||
|
lookup_name_info lookup_name (class_name, symbol_name_match_type::FULL);
|
||||||
|
|
||||||
for (ix = 0; VEC_iterate (symtab_ptr, file_symtabs, ix, elt); ++ix)
|
for (ix = 0; VEC_iterate (symtab_ptr, file_symtabs, ix, elt); ++ix)
|
||||||
{
|
{
|
||||||
if (elt == NULL)
|
if (elt == NULL)
|
||||||
{
|
{
|
||||||
iterate_over_all_matching_symtabs (state, class_name, STRUCT_DOMAIN,
|
iterate_over_all_matching_symtabs (state, lookup_name,
|
||||||
NULL, false, collector);
|
STRUCT_DOMAIN, NULL, false,
|
||||||
iterate_over_all_matching_symtabs (state, class_name, VAR_DOMAIN,
|
collector);
|
||||||
NULL, false, collector);
|
iterate_over_all_matching_symtabs (state, lookup_name,
|
||||||
|
VAR_DOMAIN, NULL, false,
|
||||||
|
collector);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3591,8 +3596,8 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs,
|
||||||
been filtered out earlier. */
|
been filtered out earlier. */
|
||||||
gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
|
gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
|
||||||
set_current_program_space (SYMTAB_PSPACE (elt));
|
set_current_program_space (SYMTAB_PSPACE (elt));
|
||||||
iterate_over_file_blocks (elt, class_name, STRUCT_DOMAIN, collector);
|
iterate_over_file_blocks (elt, lookup_name, STRUCT_DOMAIN, collector);
|
||||||
iterate_over_file_blocks (elt, class_name, VAR_DOMAIN, collector);
|
iterate_over_file_blocks (elt, lookup_name, VAR_DOMAIN, collector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3673,12 +3678,14 @@ add_all_symbol_names_from_pspace (struct collect_info *info,
|
||||||
const char *iter;
|
const char *iter;
|
||||||
|
|
||||||
for (ix = 0; VEC_iterate (const_char_ptr, names, ix, iter); ++ix)
|
for (ix = 0; VEC_iterate (const_char_ptr, names, ix, iter); ++ix)
|
||||||
add_matching_symbols_to_info (iter, info, pspace);
|
add_matching_symbols_to_info (iter,
|
||||||
|
symbol_name_match_type::FULL,
|
||||||
|
info, pspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
find_superclass_methods (VEC (typep) *superclasses,
|
find_superclass_methods (VEC (typep) *superclasses,
|
||||||
const char *name,
|
const char *name, enum language name_lang,
|
||||||
VEC (const_char_ptr) **result_names)
|
VEC (const_char_ptr) **result_names)
|
||||||
{
|
{
|
||||||
int old_len = VEC_length (const_char_ptr, *result_names);
|
int old_len = VEC_length (const_char_ptr, *result_names);
|
||||||
|
@ -3694,7 +3701,7 @@ find_superclass_methods (VEC (typep) *superclasses,
|
||||||
|
|
||||||
make_cleanup (VEC_cleanup (typep), &new_supers);
|
make_cleanup (VEC_cleanup (typep), &new_supers);
|
||||||
for (ix = 0; VEC_iterate (typep, iter_classes, ix, t); ++ix)
|
for (ix = 0; VEC_iterate (typep, iter_classes, ix, t); ++ix)
|
||||||
find_methods (t, name, result_names, &new_supers);
|
find_methods (t, name_lang, name, result_names, &new_supers);
|
||||||
|
|
||||||
if (VEC_length (const_char_ptr, *result_names) != old_len
|
if (VEC_length (const_char_ptr, *result_names) != old_len
|
||||||
|| VEC_empty (typep, new_supers))
|
|| VEC_empty (typep, new_supers))
|
||||||
|
@ -3761,7 +3768,8 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
|
||||||
gdb_assert (!pspace->executing_startup);
|
gdb_assert (!pspace->executing_startup);
|
||||||
set_current_program_space (pspace);
|
set_current_program_space (pspace);
|
||||||
t = check_typedef (SYMBOL_TYPE (sym));
|
t = check_typedef (SYMBOL_TYPE (sym));
|
||||||
find_methods (t, method_name, &result_names, &superclass_vec);
|
find_methods (t, SYMBOL_LANGUAGE (sym),
|
||||||
|
method_name, &result_names, &superclass_vec);
|
||||||
|
|
||||||
/* Handle all items from a single program space at once; and be
|
/* Handle all items from a single program space at once; and be
|
||||||
sure not to miss the last batch. */
|
sure not to miss the last batch. */
|
||||||
|
@ -3774,7 +3782,7 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs,
|
||||||
this program space, consider superclasses. */
|
this program space, consider superclasses. */
|
||||||
if (VEC_length (const_char_ptr, result_names) == last_result_len)
|
if (VEC_length (const_char_ptr, result_names) == last_result_len)
|
||||||
find_superclass_methods (superclass_vec, method_name,
|
find_superclass_methods (superclass_vec, method_name,
|
||||||
&result_names);
|
SYMBOL_LANGUAGE (sym), &result_names);
|
||||||
|
|
||||||
/* We have a list of candidate symbol names, so now we
|
/* We have a list of candidate symbol names, so now we
|
||||||
iterate over the symbol tables looking for all
|
iterate over the symbol tables looking for all
|
||||||
|
@ -3941,7 +3949,8 @@ find_function_symbols (struct linespec_state *state,
|
||||||
add_all_symbol_names_from_pspace (&info, state->search_pspace,
|
add_all_symbol_names_from_pspace (&info, state->search_pspace,
|
||||||
symbol_names);
|
symbol_names);
|
||||||
else
|
else
|
||||||
add_matching_symbols_to_info (name, &info, state->search_pspace);
|
add_matching_symbols_to_info (name, symbol_name_match_type::WILD,
|
||||||
|
&info, state->search_pspace);
|
||||||
|
|
||||||
do_cleanups (cleanup);
|
do_cleanups (cleanup);
|
||||||
|
|
||||||
|
@ -3968,28 +3977,10 @@ find_function_symbols (struct linespec_state *state,
|
||||||
static void
|
static void
|
||||||
find_linespec_symbols (struct linespec_state *state,
|
find_linespec_symbols (struct linespec_state *state,
|
||||||
VEC (symtab_ptr) *file_symtabs,
|
VEC (symtab_ptr) *file_symtabs,
|
||||||
const char *name,
|
const char *lookup_name,
|
||||||
VEC (symbolp) **symbols,
|
VEC (symbolp) **symbols,
|
||||||
VEC (bound_minimal_symbol_d) **minsyms)
|
VEC (bound_minimal_symbol_d) **minsyms)
|
||||||
{
|
{
|
||||||
demangle_result_storage demangle_storage;
|
|
||||||
std::string ada_lookup_storage;
|
|
||||||
const char *lookup_name;
|
|
||||||
|
|
||||||
if (state->language->la_language == language_ada)
|
|
||||||
{
|
|
||||||
/* In Ada, the symbol lookups are performed using the encoded
|
|
||||||
name rather than the demangled name. */
|
|
||||||
ada_lookup_storage = ada_name_for_lookup (name);
|
|
||||||
lookup_name = ada_lookup_storage.c_str ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lookup_name = demangle_for_lookup (name,
|
|
||||||
state->language->la_language,
|
|
||||||
demangle_storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string canon = cp_canonicalize_string_no_typedefs (lookup_name);
|
std::string canon = cp_canonicalize_string_no_typedefs (lookup_name);
|
||||||
if (!canon.empty ())
|
if (!canon.empty ())
|
||||||
lookup_name = canon.c_str ();
|
lookup_name = canon.c_str ();
|
||||||
|
@ -4483,7 +4474,8 @@ add_minsym (struct minimal_symbol *minsym, void *d)
|
||||||
restrict results to the given SYMTAB. */
|
restrict results to the given SYMTAB. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
search_minsyms_for_name (struct collect_info *info, const char *name,
|
search_minsyms_for_name (struct collect_info *info,
|
||||||
|
const lookup_name_info &name,
|
||||||
struct program_space *search_pspace,
|
struct program_space *search_pspace,
|
||||||
struct symtab *symtab)
|
struct symtab *symtab)
|
||||||
{
|
{
|
||||||
|
@ -4525,8 +4517,7 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
|
||||||
{
|
{
|
||||||
set_current_program_space (SYMTAB_PSPACE (symtab));
|
set_current_program_space (SYMTAB_PSPACE (symtab));
|
||||||
local.objfile = SYMTAB_OBJFILE(symtab);
|
local.objfile = SYMTAB_OBJFILE(symtab);
|
||||||
iterate_over_minimal_symbols (local.objfile, name, add_minsym,
|
iterate_over_minimal_symbols (local.objfile, name, add_minsym, &local);
|
||||||
&local);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4568,20 +4559,24 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_matching_symbols_to_info (const char *name,
|
add_matching_symbols_to_info (const char *name,
|
||||||
|
symbol_name_match_type name_match_type,
|
||||||
struct collect_info *info,
|
struct collect_info *info,
|
||||||
struct program_space *pspace)
|
struct program_space *pspace)
|
||||||
{
|
{
|
||||||
int ix;
|
int ix;
|
||||||
struct symtab *elt;
|
struct symtab *elt;
|
||||||
|
|
||||||
|
lookup_name_info lookup_name (name, name_match_type);
|
||||||
|
|
||||||
for (ix = 0; VEC_iterate (symtab_ptr, info->file_symtabs, ix, elt); ++ix)
|
for (ix = 0; VEC_iterate (symtab_ptr, info->file_symtabs, ix, elt); ++ix)
|
||||||
{
|
{
|
||||||
if (elt == NULL)
|
if (elt == NULL)
|
||||||
{
|
{
|
||||||
iterate_over_all_matching_symtabs (info->state, name, VAR_DOMAIN,
|
iterate_over_all_matching_symtabs (info->state, lookup_name,
|
||||||
|
VAR_DOMAIN,
|
||||||
pspace, true, [&] (symbol *sym)
|
pspace, true, [&] (symbol *sym)
|
||||||
{ return info->add_symbol (sym); });
|
{ return info->add_symbol (sym); });
|
||||||
search_minsyms_for_name (info, name, pspace, NULL);
|
search_minsyms_for_name (info, lookup_name, pspace, NULL);
|
||||||
}
|
}
|
||||||
else if (pspace == NULL || pspace == SYMTAB_PSPACE (elt))
|
else if (pspace == NULL || pspace == SYMTAB_PSPACE (elt))
|
||||||
{
|
{
|
||||||
|
@ -4591,7 +4586,8 @@ add_matching_symbols_to_info (const char *name,
|
||||||
been filtered out earlier. */
|
been filtered out earlier. */
|
||||||
gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
|
gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
|
||||||
set_current_program_space (SYMTAB_PSPACE (elt));
|
set_current_program_space (SYMTAB_PSPACE (elt));
|
||||||
iterate_over_file_blocks (elt, name, VAR_DOMAIN, [&] (symbol *sym)
|
iterate_over_file_blocks (elt, lookup_name, VAR_DOMAIN,
|
||||||
|
[&] (symbol *sym)
|
||||||
{ return info->add_symbol (sym); });
|
{ return info->add_symbol (sym); });
|
||||||
|
|
||||||
/* If no new symbols were found in this iteration and this symtab
|
/* If no new symbols were found in this iteration and this symtab
|
||||||
|
@ -4600,7 +4596,7 @@ add_matching_symbols_to_info (const char *name,
|
||||||
this case. */
|
this case. */
|
||||||
if (prev_len == VEC_length (symbolp, info->result.symbols)
|
if (prev_len == VEC_length (symbolp, info->result.symbols)
|
||||||
&& elt->language == language_asm)
|
&& elt->language == language_asm)
|
||||||
search_minsyms_for_name (info, name, pspace, elt);
|
search_minsyms_for_name (info, lookup_name, pspace, elt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -393,7 +393,7 @@ extern const struct language_defn m2_language_defn =
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_get_symbol_name_matcher */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&default_varobj_ops,
|
&default_varobj_ops,
|
||||||
|
|
363
gdb/minsyms.c
363
gdb/minsyms.c
|
@ -51,6 +51,7 @@
|
||||||
#include "language.h"
|
#include "language.h"
|
||||||
#include "cli/cli-utils.h"
|
#include "cli/cli-utils.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
/* See minsyms.h. */
|
/* See minsyms.h. */
|
||||||
|
|
||||||
|
@ -131,15 +132,139 @@ add_minsym_to_hash_table (struct minimal_symbol *sym,
|
||||||
TABLE. */
|
TABLE. */
|
||||||
static void
|
static void
|
||||||
add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
|
add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
|
||||||
struct minimal_symbol **table)
|
struct objfile *objfile)
|
||||||
{
|
{
|
||||||
if (sym->demangled_hash_next == NULL)
|
if (sym->demangled_hash_next == NULL)
|
||||||
{
|
{
|
||||||
unsigned int hash = msymbol_hash_iw (MSYMBOL_SEARCH_NAME (sym))
|
unsigned int hash = search_name_hash (MSYMBOL_LANGUAGE (sym),
|
||||||
% MINIMAL_SYMBOL_HASH_SIZE;
|
MSYMBOL_SEARCH_NAME (sym));
|
||||||
|
|
||||||
sym->demangled_hash_next = table[hash];
|
auto &vec = objfile->per_bfd->demangled_hash_languages;
|
||||||
table[hash] = sym;
|
auto it = std::lower_bound (vec.begin (), vec.end (),
|
||||||
|
MSYMBOL_LANGUAGE (sym));
|
||||||
|
if (it == vec.end () || *it != MSYMBOL_LANGUAGE (sym))
|
||||||
|
vec.insert (it, MSYMBOL_LANGUAGE (sym));
|
||||||
|
|
||||||
|
struct minimal_symbol **table
|
||||||
|
= objfile->per_bfd->msymbol_demangled_hash;
|
||||||
|
unsigned int hash_index = hash % MINIMAL_SYMBOL_HASH_SIZE;
|
||||||
|
sym->demangled_hash_next = table[hash_index];
|
||||||
|
table[hash_index] = sym;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Worker object for lookup_minimal_symbol. Stores temporary results
|
||||||
|
while walking the symbol tables. */
|
||||||
|
|
||||||
|
struct found_minimal_symbols
|
||||||
|
{
|
||||||
|
/* External symbols are best. */
|
||||||
|
bound_minimal_symbol external_symbol {};
|
||||||
|
|
||||||
|
/* File-local symbols are next best. */
|
||||||
|
bound_minimal_symbol file_symbol {};
|
||||||
|
|
||||||
|
/* Symbols for shared library trampolines are next best. */
|
||||||
|
bound_minimal_symbol trampoline_symbol {};
|
||||||
|
|
||||||
|
/* Called when a symbol name matches. Check if the minsym is a
|
||||||
|
better type than what we had already found, and record it in one
|
||||||
|
of the members fields if so. Returns true if we collected the
|
||||||
|
real symbol, in which case we can stop searching. */
|
||||||
|
bool maybe_collect (const char *sfile, objfile *objf,
|
||||||
|
minimal_symbol *msymbol);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* See declaration above. */
|
||||||
|
|
||||||
|
bool
|
||||||
|
found_minimal_symbols::maybe_collect (const char *sfile,
|
||||||
|
struct objfile *objfile,
|
||||||
|
minimal_symbol *msymbol)
|
||||||
|
{
|
||||||
|
switch (MSYMBOL_TYPE (msymbol))
|
||||||
|
{
|
||||||
|
case mst_file_text:
|
||||||
|
case mst_file_data:
|
||||||
|
case mst_file_bss:
|
||||||
|
if (sfile == NULL
|
||||||
|
|| filename_cmp (msymbol->filename, sfile) == 0)
|
||||||
|
{
|
||||||
|
file_symbol.minsym = msymbol;
|
||||||
|
file_symbol.objfile = objfile;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mst_solib_trampoline:
|
||||||
|
|
||||||
|
/* If a trampoline symbol is found, we prefer to keep
|
||||||
|
looking for the *real* symbol. If the actual symbol
|
||||||
|
is not found, then we'll use the trampoline
|
||||||
|
entry. */
|
||||||
|
if (trampoline_symbol.minsym == NULL)
|
||||||
|
{
|
||||||
|
trampoline_symbol.minsym = msymbol;
|
||||||
|
trampoline_symbol.objfile = objfile;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mst_unknown:
|
||||||
|
default:
|
||||||
|
external_symbol.minsym = msymbol;
|
||||||
|
external_symbol.objfile = objfile;
|
||||||
|
/* We have the real symbol. No use looking further. */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep looking. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk the mangled name hash table, and pass each symbol whose name
|
||||||
|
matches LOOKUP_NAME according to NAMECMP to FOUND. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
lookup_minimal_symbol_mangled (const char *lookup_name,
|
||||||
|
const char *sfile,
|
||||||
|
struct objfile *objfile,
|
||||||
|
struct minimal_symbol **table,
|
||||||
|
unsigned int hash,
|
||||||
|
int (*namecmp) (const char *, const char *),
|
||||||
|
found_minimal_symbols &found)
|
||||||
|
{
|
||||||
|
for (minimal_symbol *msymbol = table[hash];
|
||||||
|
msymbol != NULL;
|
||||||
|
msymbol = msymbol->hash_next)
|
||||||
|
{
|
||||||
|
const char *symbol_name = MSYMBOL_LINKAGE_NAME (msymbol);
|
||||||
|
|
||||||
|
if (namecmp (symbol_name, lookup_name) == 0
|
||||||
|
&& found.maybe_collect (sfile, objfile, msymbol))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk the demangled name hash table, and pass each symbol whose name
|
||||||
|
matches LOOKUP_NAME according to MATCHER to FOUND. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
lookup_minimal_symbol_demangled (const lookup_name_info &lookup_name,
|
||||||
|
const char *sfile,
|
||||||
|
struct objfile *objfile,
|
||||||
|
struct minimal_symbol **table,
|
||||||
|
unsigned int hash,
|
||||||
|
symbol_name_matcher_ftype *matcher,
|
||||||
|
found_minimal_symbols &found)
|
||||||
|
{
|
||||||
|
for (minimal_symbol *msymbol = table[hash];
|
||||||
|
msymbol != NULL;
|
||||||
|
msymbol = msymbol->demangled_hash_next)
|
||||||
|
{
|
||||||
|
const char *symbol_name = MSYMBOL_SEARCH_NAME (msymbol);
|
||||||
|
|
||||||
|
if (matcher (symbol_name, lookup_name, NULL)
|
||||||
|
&& found.maybe_collect (sfile, objfile, msymbol))
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,32 +293,22 @@ lookup_minimal_symbol (const char *name, const char *sfile,
|
||||||
struct objfile *objf)
|
struct objfile *objf)
|
||||||
{
|
{
|
||||||
struct objfile *objfile;
|
struct objfile *objfile;
|
||||||
struct bound_minimal_symbol found_symbol = { NULL, NULL };
|
found_minimal_symbols found;
|
||||||
struct bound_minimal_symbol found_file_symbol = { NULL, NULL };
|
|
||||||
struct bound_minimal_symbol trampoline_symbol = { NULL, NULL };
|
|
||||||
|
|
||||||
unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
|
unsigned int mangled_hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
|
||||||
unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
|
|
||||||
|
|
||||||
const char *modified_name = name;
|
auto *mangled_cmp
|
||||||
|
= (case_sensitivity == case_sensitive_on
|
||||||
|
? strcmp
|
||||||
|
: strcasecmp);
|
||||||
|
|
||||||
if (sfile != NULL)
|
if (sfile != NULL)
|
||||||
sfile = lbasename (sfile);
|
sfile = lbasename (sfile);
|
||||||
|
|
||||||
/* For C++, canonicalize the input name. */
|
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
|
||||||
std::string modified_name_storage;
|
|
||||||
if (current_language->la_language == language_cplus)
|
|
||||||
{
|
|
||||||
std::string cname = cp_canonicalize_string (name);
|
|
||||||
if (!cname.empty ())
|
|
||||||
{
|
|
||||||
std::swap (modified_name_storage, cname);
|
|
||||||
modified_name = modified_name_storage.c_str ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (objfile = object_files;
|
for (objfile = object_files;
|
||||||
objfile != NULL && found_symbol.minsym == NULL;
|
objfile != NULL && found.external_symbol.minsym == NULL;
|
||||||
objfile = objfile->next)
|
objfile = objfile->next)
|
||||||
{
|
{
|
||||||
struct minimal_symbol *msymbol;
|
struct minimal_symbol *msymbol;
|
||||||
|
@ -201,131 +316,95 @@ lookup_minimal_symbol (const char *name, const char *sfile,
|
||||||
if (objf == NULL || objf == objfile
|
if (objf == NULL || objf == objfile
|
||||||
|| objf == objfile->separate_debug_objfile_backlink)
|
|| objf == objfile->separate_debug_objfile_backlink)
|
||||||
{
|
{
|
||||||
|
if (symbol_lookup_debug)
|
||||||
|
{
|
||||||
|
fprintf_unfiltered (gdb_stdlog,
|
||||||
|
"lookup_minimal_symbol (%s, %s, %s)\n",
|
||||||
|
name, sfile != NULL ? sfile : "NULL",
|
||||||
|
objfile_debug_name (objfile));
|
||||||
|
}
|
||||||
|
|
||||||
/* Do two passes: the first over the ordinary hash table,
|
/* Do two passes: the first over the ordinary hash table,
|
||||||
and the second over the demangled hash table. */
|
and the second over the demangled hash table. */
|
||||||
int pass;
|
lookup_minimal_symbol_mangled (name, sfile, objfile,
|
||||||
|
objfile->per_bfd->msymbol_hash,
|
||||||
|
mangled_hash, mangled_cmp, found);
|
||||||
|
|
||||||
if (symbol_lookup_debug)
|
/* If not found, try the demangled hash table. */
|
||||||
{
|
if (found.external_symbol.minsym == NULL)
|
||||||
fprintf_unfiltered (gdb_stdlog,
|
|
||||||
"lookup_minimal_symbol (%s, %s, %s)\n",
|
|
||||||
name, sfile != NULL ? sfile : "NULL",
|
|
||||||
objfile_debug_name (objfile));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (pass = 1; pass <= 2 && found_symbol.minsym == NULL; pass++)
|
|
||||||
{
|
{
|
||||||
/* Select hash list according to pass. */
|
/* Once for each language in the demangled hash names
|
||||||
if (pass == 1)
|
table (usually just zero or one languages). */
|
||||||
msymbol = objfile->per_bfd->msymbol_hash[hash];
|
for (auto lang : objfile->per_bfd->demangled_hash_languages)
|
||||||
else
|
|
||||||
msymbol = objfile->per_bfd->msymbol_demangled_hash[dem_hash];
|
|
||||||
|
|
||||||
while (msymbol != NULL && found_symbol.minsym == NULL)
|
|
||||||
{
|
{
|
||||||
int match;
|
unsigned int hash
|
||||||
|
= (lookup_name.search_name_hash (lang)
|
||||||
|
% MINIMAL_SYMBOL_HASH_SIZE);
|
||||||
|
|
||||||
if (pass == 1)
|
symbol_name_matcher_ftype *match
|
||||||
{
|
= language_get_symbol_name_matcher (language_def (lang),
|
||||||
int (*cmp) (const char *, const char *);
|
lookup_name);
|
||||||
|
struct minimal_symbol **msymbol_demangled_hash
|
||||||
|
= objfile->per_bfd->msymbol_demangled_hash;
|
||||||
|
|
||||||
cmp = (case_sensitivity == case_sensitive_on
|
lookup_minimal_symbol_demangled (lookup_name, sfile, objfile,
|
||||||
? strcmp : strcasecmp);
|
msymbol_demangled_hash,
|
||||||
match = cmp (MSYMBOL_LINKAGE_NAME (msymbol),
|
hash, match, found);
|
||||||
modified_name) == 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* The function respects CASE_SENSITIVITY. */
|
|
||||||
match = MSYMBOL_MATCHES_SEARCH_NAME (msymbol,
|
|
||||||
modified_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match)
|
if (found.external_symbol.minsym != NULL)
|
||||||
{
|
break;
|
||||||
switch (MSYMBOL_TYPE (msymbol))
|
|
||||||
{
|
|
||||||
case mst_file_text:
|
|
||||||
case mst_file_data:
|
|
||||||
case mst_file_bss:
|
|
||||||
if (sfile == NULL
|
|
||||||
|| filename_cmp (msymbol->filename, sfile) == 0)
|
|
||||||
{
|
|
||||||
found_file_symbol.minsym = msymbol;
|
|
||||||
found_file_symbol.objfile = objfile;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case mst_solib_trampoline:
|
|
||||||
|
|
||||||
/* If a trampoline symbol is found, we prefer to
|
|
||||||
keep looking for the *real* symbol. If the
|
|
||||||
actual symbol is not found, then we'll use the
|
|
||||||
trampoline entry. */
|
|
||||||
if (trampoline_symbol.minsym == NULL)
|
|
||||||
{
|
|
||||||
trampoline_symbol.minsym = msymbol;
|
|
||||||
trampoline_symbol.objfile = objfile;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case mst_unknown:
|
|
||||||
default:
|
|
||||||
found_symbol.minsym = msymbol;
|
|
||||||
found_symbol.objfile = objfile;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the next symbol on the hash chain. */
|
|
||||||
if (pass == 1)
|
|
||||||
msymbol = msymbol->hash_next;
|
|
||||||
else
|
|
||||||
msymbol = msymbol->demangled_hash_next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* External symbols are best. */
|
/* External symbols are best. */
|
||||||
if (found_symbol.minsym != NULL)
|
if (found.external_symbol.minsym != NULL)
|
||||||
{
|
{
|
||||||
if (symbol_lookup_debug)
|
if (symbol_lookup_debug)
|
||||||
{
|
{
|
||||||
|
minimal_symbol *minsym = found.external_symbol.minsym;
|
||||||
|
|
||||||
fprintf_unfiltered (gdb_stdlog,
|
fprintf_unfiltered (gdb_stdlog,
|
||||||
"lookup_minimal_symbol (...) = %s"
|
"lookup_minimal_symbol (...) = %s (external)\n",
|
||||||
" (external)\n",
|
host_address_to_string (minsym));
|
||||||
host_address_to_string (found_symbol.minsym));
|
|
||||||
}
|
}
|
||||||
return found_symbol;
|
return found.external_symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* File-local symbols are next best. */
|
/* File-local symbols are next best. */
|
||||||
if (found_file_symbol.minsym != NULL)
|
if (found.file_symbol.minsym != NULL)
|
||||||
{
|
{
|
||||||
if (symbol_lookup_debug)
|
if (symbol_lookup_debug)
|
||||||
{
|
{
|
||||||
|
minimal_symbol *minsym = found.file_symbol.minsym;
|
||||||
|
|
||||||
fprintf_unfiltered (gdb_stdlog,
|
fprintf_unfiltered (gdb_stdlog,
|
||||||
"lookup_minimal_symbol (...) = %s"
|
"lookup_minimal_symbol (...) = %s (file-local)\n",
|
||||||
" (file-local)\n",
|
host_address_to_string (minsym));
|
||||||
host_address_to_string
|
|
||||||
(found_file_symbol.minsym));
|
|
||||||
}
|
}
|
||||||
return found_file_symbol;
|
return found.file_symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Symbols for shared library trampolines are next best. */
|
/* Symbols for shared library trampolines are next best. */
|
||||||
if (symbol_lookup_debug)
|
if (found.trampoline_symbol.minsym != NULL)
|
||||||
{
|
{
|
||||||
fprintf_unfiltered (gdb_stdlog,
|
if (symbol_lookup_debug)
|
||||||
"lookup_minimal_symbol (...) = %s%s\n",
|
{
|
||||||
trampoline_symbol.minsym != NULL
|
minimal_symbol *minsym = found.trampoline_symbol.minsym;
|
||||||
? host_address_to_string (trampoline_symbol.minsym)
|
|
||||||
: "NULL",
|
fprintf_unfiltered (gdb_stdlog,
|
||||||
trampoline_symbol.minsym != NULL
|
"lookup_minimal_symbol (...) = %s (trampoline)\n",
|
||||||
? " (trampoline)" : "");
|
host_address_to_string (minsym));
|
||||||
|
}
|
||||||
|
|
||||||
|
return found.trampoline_symbol;
|
||||||
}
|
}
|
||||||
return trampoline_symbol;
|
|
||||||
|
/* Not found. */
|
||||||
|
if (symbol_lookup_debug)
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "lookup_minimal_symbol (...) = NULL\n");
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See minsyms.h. */
|
/* See minsyms.h. */
|
||||||
|
@ -354,34 +433,47 @@ find_minimal_symbol_address (const char *name, CORE_ADDR *addr,
|
||||||
/* See minsyms.h. */
|
/* See minsyms.h. */
|
||||||
|
|
||||||
void
|
void
|
||||||
iterate_over_minimal_symbols (struct objfile *objf, const char *name,
|
iterate_over_minimal_symbols (struct objfile *objf,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
void (*callback) (struct minimal_symbol *,
|
void (*callback) (struct minimal_symbol *,
|
||||||
void *),
|
void *),
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
unsigned int hash;
|
|
||||||
struct minimal_symbol *iter;
|
|
||||||
int (*cmp) (const char *, const char *);
|
|
||||||
|
|
||||||
/* The first pass is over the ordinary hash table. */
|
/* The first pass is over the ordinary hash table. */
|
||||||
hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
|
|
||||||
iter = objf->per_bfd->msymbol_hash[hash];
|
|
||||||
cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp);
|
|
||||||
while (iter)
|
|
||||||
{
|
{
|
||||||
if (cmp (MSYMBOL_LINKAGE_NAME (iter), name) == 0)
|
const char *name = lookup_name.name ().c_str ();
|
||||||
(*callback) (iter, user_data);
|
unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
|
||||||
iter = iter->hash_next;
|
auto *mangled_cmp
|
||||||
|
= (case_sensitivity == case_sensitive_on
|
||||||
|
? strcmp
|
||||||
|
: strcasecmp);
|
||||||
|
|
||||||
|
for (minimal_symbol *iter = objf->per_bfd->msymbol_hash[hash];
|
||||||
|
iter != NULL;
|
||||||
|
iter = iter->hash_next)
|
||||||
|
{
|
||||||
|
if (mangled_cmp (MSYMBOL_LINKAGE_NAME (iter), name) == 0)
|
||||||
|
(*callback) (iter, user_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The second pass is over the demangled table. */
|
/* The second pass is over the demangled table. Once for each
|
||||||
hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
|
language in the demangled hash names table (usually just zero or
|
||||||
iter = objf->per_bfd->msymbol_demangled_hash[hash];
|
one). */
|
||||||
while (iter)
|
for (auto lang : objf->per_bfd->demangled_hash_languages)
|
||||||
{
|
{
|
||||||
if (MSYMBOL_MATCHES_SEARCH_NAME (iter, name))
|
const language_defn *lang_def = language_def (lang);
|
||||||
(*callback) (iter, user_data);
|
symbol_name_matcher_ftype *name_match
|
||||||
iter = iter->demangled_hash_next;
|
= language_get_symbol_name_matcher (lang_def, lookup_name);
|
||||||
|
|
||||||
|
unsigned int hash
|
||||||
|
= lookup_name.search_name_hash (lang) % MINIMAL_SYMBOL_HASH_SIZE;
|
||||||
|
for (minimal_symbol *iter = objf->per_bfd->msymbol_demangled_hash[hash];
|
||||||
|
iter != NULL;
|
||||||
|
iter = iter->demangled_hash_next)
|
||||||
|
if (name_match (MSYMBOL_SEARCH_NAME (iter), lookup_name, NULL))
|
||||||
|
(*callback) (iter, user_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1187,8 +1279,7 @@ build_minimal_symbol_hash_tables (struct objfile *objfile)
|
||||||
|
|
||||||
msym->demangled_hash_next = 0;
|
msym->demangled_hash_next = 0;
|
||||||
if (MSYMBOL_SEARCH_NAME (msym) != MSYMBOL_LINKAGE_NAME (msym))
|
if (MSYMBOL_SEARCH_NAME (msym) != MSYMBOL_LINKAGE_NAME (msym))
|
||||||
add_minsym_to_demangled_hash_table (msym,
|
add_minsym_to_demangled_hash_table (msym, objfile);
|
||||||
objfile->per_bfd->msymbol_demangled_hash);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -264,7 +264,7 @@ struct bound_minimal_symbol lookup_minimal_symbol_by_pc (CORE_ADDR);
|
||||||
USER_DATA as arguments. */
|
USER_DATA as arguments. */
|
||||||
|
|
||||||
void iterate_over_minimal_symbols (struct objfile *objf,
|
void iterate_over_minimal_symbols (struct objfile *objf,
|
||||||
const char *name,
|
const lookup_name_info &name,
|
||||||
void (*callback) (struct minimal_symbol *,
|
void (*callback) (struct minimal_symbol *,
|
||||||
void *),
|
void *),
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
|
@ -405,7 +405,7 @@ extern const struct language_defn objc_language_defn = {
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_get_symbol_name_matcher */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&default_varobj_ops,
|
&default_varobj_ops,
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "progspace.h"
|
#include "progspace.h"
|
||||||
#include "registry.h"
|
#include "registry.h"
|
||||||
#include "gdb_bfd.h"
|
#include "gdb_bfd.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
struct bcache;
|
struct bcache;
|
||||||
struct htab;
|
struct htab;
|
||||||
|
@ -266,6 +267,12 @@ struct objfile_per_bfd_storage
|
||||||
demangled names. */
|
demangled names. */
|
||||||
|
|
||||||
minimal_symbol *msymbol_demangled_hash[MINIMAL_SYMBOL_HASH_SIZE] {};
|
minimal_symbol *msymbol_demangled_hash[MINIMAL_SYMBOL_HASH_SIZE] {};
|
||||||
|
|
||||||
|
/* All the different languages of symbols found in the demangled
|
||||||
|
hash table. A flat/vector-based map is more efficient than a map
|
||||||
|
or hash table here, since this will only usually contain zero or
|
||||||
|
one entries. */
|
||||||
|
std::vector<enum language> demangled_hash_languages;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Master structure for keeping track of each file from which
|
/* Master structure for keeping track of each file from which
|
||||||
|
|
|
@ -1081,7 +1081,7 @@ extern const struct language_defn opencl_language_defn =
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_get_symbol_name_matcher */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&default_varobj_ops,
|
&default_varobj_ops,
|
||||||
|
|
|
@ -454,7 +454,7 @@ extern const struct language_defn pascal_language_defn =
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
c_watch_location_expression,
|
c_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_compare_symbol_for_completion */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&default_varobj_ops,
|
&default_varobj_ops,
|
||||||
|
|
|
@ -46,7 +46,7 @@ static struct partial_symbol *match_partial_symbol (struct objfile *,
|
||||||
struct partial_symtab *,
|
struct partial_symtab *,
|
||||||
int,
|
int,
|
||||||
const char *, domain_enum,
|
const char *, domain_enum,
|
||||||
symbol_compare_ftype *,
|
symbol_name_match_type,
|
||||||
symbol_compare_ftype *);
|
symbol_compare_ftype *);
|
||||||
|
|
||||||
static struct partial_symbol *lookup_partial_symbol (struct objfile *,
|
static struct partial_symbol *lookup_partial_symbol (struct objfile *,
|
||||||
|
@ -510,6 +510,8 @@ psym_lookup_symbol (struct objfile *objfile,
|
||||||
const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
|
const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
|
||||||
struct compunit_symtab *stab_best = NULL;
|
struct compunit_symtab *stab_best = NULL;
|
||||||
|
|
||||||
|
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
|
||||||
|
|
||||||
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
|
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
|
||||||
{
|
{
|
||||||
if (!ps->readin && lookup_partial_symbol (objfile, ps, name,
|
if (!ps->readin && lookup_partial_symbol (objfile, ps, name,
|
||||||
|
@ -532,10 +534,10 @@ psym_lookup_symbol (struct objfile *objfile,
|
||||||
information (but NAME might contain it). */
|
information (but NAME might contain it). */
|
||||||
|
|
||||||
if (sym != NULL
|
if (sym != NULL
|
||||||
&& SYMBOL_MATCHES_SEARCH_NAME (sym, name))
|
&& SYMBOL_MATCHES_SEARCH_NAME (sym, lookup_name))
|
||||||
return stab;
|
return stab;
|
||||||
if (with_opaque != NULL
|
if (with_opaque != NULL
|
||||||
&& SYMBOL_MATCHES_SEARCH_NAME (with_opaque, name))
|
&& SYMBOL_MATCHES_SEARCH_NAME (with_opaque, lookup_name))
|
||||||
stab_best = stab;
|
stab_best = stab;
|
||||||
|
|
||||||
/* Keep looking through other psymtabs. */
|
/* Keep looking through other psymtabs. */
|
||||||
|
@ -545,6 +547,18 @@ psym_lookup_symbol (struct objfile *objfile,
|
||||||
return stab_best;
|
return stab_best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true if PSYM matches LOOKUP_NAME. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
psymbol_name_matches (partial_symbol *psym,
|
||||||
|
const lookup_name_info &lookup_name)
|
||||||
|
{
|
||||||
|
const language_defn *lang = language_def (SYMBOL_LANGUAGE (psym));
|
||||||
|
symbol_name_matcher_ftype *name_match
|
||||||
|
= language_get_symbol_name_matcher (lang, lookup_name);
|
||||||
|
return name_match (SYMBOL_SEARCH_NAME (psym), lookup_name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Look in PST for a symbol in DOMAIN whose name matches NAME. Search
|
/* Look in PST for a symbol in DOMAIN whose name matches NAME. Search
|
||||||
the global block of PST if GLOBAL, and otherwise the static block.
|
the global block of PST if GLOBAL, and otherwise the static block.
|
||||||
MATCH is the comparison operation that returns true iff MATCH (s,
|
MATCH is the comparison operation that returns true iff MATCH (s,
|
||||||
|
@ -557,7 +571,7 @@ static struct partial_symbol *
|
||||||
match_partial_symbol (struct objfile *objfile,
|
match_partial_symbol (struct objfile *objfile,
|
||||||
struct partial_symtab *pst, int global,
|
struct partial_symtab *pst, int global,
|
||||||
const char *name, domain_enum domain,
|
const char *name, domain_enum domain,
|
||||||
symbol_compare_ftype *match,
|
symbol_name_match_type match_type,
|
||||||
symbol_compare_ftype *ordered_compare)
|
symbol_compare_ftype *ordered_compare)
|
||||||
{
|
{
|
||||||
struct partial_symbol **start, **psym;
|
struct partial_symbol **start, **psym;
|
||||||
|
@ -566,7 +580,10 @@ match_partial_symbol (struct objfile *objfile,
|
||||||
int do_linear_search = 1;
|
int do_linear_search = 1;
|
||||||
|
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
lookup_name_info lookup_name (name, match_type);
|
||||||
|
|
||||||
start = (global ?
|
start = (global ?
|
||||||
&objfile->global_psymbols[pst->globals_offset] :
|
&objfile->global_psymbols[pst->globals_offset] :
|
||||||
&objfile->static_psymbols[pst->statics_offset]);
|
&objfile->static_psymbols[pst->statics_offset]);
|
||||||
|
@ -588,7 +605,12 @@ match_partial_symbol (struct objfile *objfile,
|
||||||
{
|
{
|
||||||
center = bottom + (top - bottom) / 2;
|
center = bottom + (top - bottom) / 2;
|
||||||
gdb_assert (center < top);
|
gdb_assert (center < top);
|
||||||
if (ordered_compare (SYMBOL_SEARCH_NAME (*center), name) >= 0)
|
|
||||||
|
enum language lang = SYMBOL_LANGUAGE (*center);
|
||||||
|
const char *lang_ln
|
||||||
|
= lookup_name.language_lookup_name (lang).c_str ();
|
||||||
|
|
||||||
|
if (ordered_compare (SYMBOL_SEARCH_NAME (*center), lang_ln) >= 0)
|
||||||
top = center;
|
top = center;
|
||||||
else
|
else
|
||||||
bottom = center + 1;
|
bottom = center + 1;
|
||||||
|
@ -596,7 +618,7 @@ match_partial_symbol (struct objfile *objfile,
|
||||||
gdb_assert (top == bottom);
|
gdb_assert (top == bottom);
|
||||||
|
|
||||||
while (top <= real_top
|
while (top <= real_top
|
||||||
&& match (SYMBOL_SEARCH_NAME (*top), name) == 0)
|
&& psymbol_name_matches (*top, lookup_name))
|
||||||
{
|
{
|
||||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
|
if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
|
||||||
SYMBOL_DOMAIN (*top), domain))
|
SYMBOL_DOMAIN (*top), domain))
|
||||||
|
@ -614,7 +636,7 @@ match_partial_symbol (struct objfile *objfile,
|
||||||
{
|
{
|
||||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
|
if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
|
||||||
SYMBOL_DOMAIN (*psym), domain)
|
SYMBOL_DOMAIN (*psym), domain)
|
||||||
&& match (SYMBOL_SEARCH_NAME (*psym), name) == 0)
|
&& psymbol_name_matches (*psym, lookup_name))
|
||||||
return *psym;
|
return *psym;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -669,6 +691,9 @@ lookup_partial_symbol (struct objfile *objfile,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
gdb::unique_xmalloc_ptr<char> search_name = psymtab_search_name (name);
|
gdb::unique_xmalloc_ptr<char> search_name = psymtab_search_name (name);
|
||||||
|
|
||||||
|
lookup_name_info lookup_name (search_name.get (), symbol_name_match_type::FULL);
|
||||||
|
|
||||||
start = (global ?
|
start = (global ?
|
||||||
&objfile->global_psymbols[pst->globals_offset] :
|
&objfile->global_psymbols[pst->globals_offset] :
|
||||||
&objfile->static_psymbols[pst->statics_offset]);
|
&objfile->static_psymbols[pst->statics_offset]);
|
||||||
|
@ -708,15 +733,13 @@ lookup_partial_symbol (struct objfile *objfile,
|
||||||
|
|
||||||
/* For `case_sensitivity == case_sensitive_off' strcmp_iw_ordered will
|
/* For `case_sensitivity == case_sensitive_off' strcmp_iw_ordered will
|
||||||
search more exactly than what matches SYMBOL_MATCHES_SEARCH_NAME. */
|
search more exactly than what matches SYMBOL_MATCHES_SEARCH_NAME. */
|
||||||
while (top >= start && SYMBOL_MATCHES_SEARCH_NAME (*top,
|
while (top >= start && SYMBOL_MATCHES_SEARCH_NAME (*top, lookup_name))
|
||||||
search_name.get ()))
|
|
||||||
top--;
|
top--;
|
||||||
|
|
||||||
/* Fixup to have a symbol which matches SYMBOL_MATCHES_SEARCH_NAME. */
|
/* Fixup to have a symbol which matches SYMBOL_MATCHES_SEARCH_NAME. */
|
||||||
top++;
|
top++;
|
||||||
|
|
||||||
while (top <= real_top
|
while (top <= real_top && SYMBOL_MATCHES_SEARCH_NAME (*top, lookup_name))
|
||||||
&& SYMBOL_MATCHES_SEARCH_NAME (*top, search_name.get ()))
|
|
||||||
{
|
{
|
||||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
|
if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
|
||||||
SYMBOL_DOMAIN (*top), domain))
|
SYMBOL_DOMAIN (*top), domain))
|
||||||
|
@ -734,7 +757,7 @@ lookup_partial_symbol (struct objfile *objfile,
|
||||||
{
|
{
|
||||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
|
if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
|
||||||
SYMBOL_DOMAIN (*psym), domain)
|
SYMBOL_DOMAIN (*psym), domain)
|
||||||
&& SYMBOL_MATCHES_SEARCH_NAME (*psym, search_name.get ()))
|
&& SYMBOL_MATCHES_SEARCH_NAME (*psym, lookup_name))
|
||||||
return *psym;
|
return *psym;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1213,13 +1236,16 @@ static int
|
||||||
map_block (const char *name, domain_enum domain, struct objfile *objfile,
|
map_block (const char *name, domain_enum domain, struct objfile *objfile,
|
||||||
struct block *block,
|
struct block *block,
|
||||||
int (*callback) (struct block *, struct symbol *, void *),
|
int (*callback) (struct block *, struct symbol *, void *),
|
||||||
void *data, symbol_compare_ftype *match)
|
void *data, symbol_name_match_type match)
|
||||||
{
|
{
|
||||||
struct block_iterator iter;
|
struct block_iterator iter;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
|
||||||
for (sym = block_iter_match_first (block, name, match, &iter);
|
lookup_name_info lookup_name (name, match);
|
||||||
sym != NULL; sym = block_iter_match_next (name, match, &iter))
|
|
||||||
|
for (sym = block_iter_match_first (block, lookup_name, &iter);
|
||||||
|
sym != NULL;
|
||||||
|
sym = block_iter_match_next (lookup_name, &iter))
|
||||||
{
|
{
|
||||||
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
||||||
SYMBOL_DOMAIN (sym), domain))
|
SYMBOL_DOMAIN (sym), domain))
|
||||||
|
@ -1242,7 +1268,7 @@ psym_map_matching_symbols (struct objfile *objfile,
|
||||||
int (*callback) (struct block *,
|
int (*callback) (struct block *,
|
||||||
struct symbol *, void *),
|
struct symbol *, void *),
|
||||||
void *data,
|
void *data,
|
||||||
symbol_compare_ftype *match,
|
symbol_name_match_type match,
|
||||||
symbol_compare_ftype *ordered_compare)
|
symbol_compare_ftype *ordered_compare)
|
||||||
{
|
{
|
||||||
const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
|
const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
|
||||||
|
@ -1277,7 +1303,8 @@ psym_map_matching_symbols (struct objfile *objfile,
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
recursively_search_psymtabs
|
recursively_search_psymtabs
|
||||||
(struct partial_symtab *ps, struct objfile *objfile, enum search_domain kind,
|
(struct partial_symtab *ps, struct objfile *objfile, enum search_domain domain,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
gdb::function_view<expand_symtabs_symbol_matcher_ftype> sym_matcher)
|
gdb::function_view<expand_symtabs_symbol_matcher_ftype> sym_matcher)
|
||||||
{
|
{
|
||||||
int keep_going = 1;
|
int keep_going = 1;
|
||||||
|
@ -1298,7 +1325,8 @@ recursively_search_psymtabs
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = recursively_search_psymtabs (ps->dependencies[i],
|
r = recursively_search_psymtabs (ps->dependencies[i],
|
||||||
objfile, kind, sym_matcher);
|
objfile, domain, lookup_name,
|
||||||
|
sym_matcher);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
{
|
{
|
||||||
ps->searched_flag = PST_SEARCHED_AND_FOUND;
|
ps->searched_flag = PST_SEARCHED_AND_FOUND;
|
||||||
|
@ -1332,15 +1360,16 @@ recursively_search_psymtabs
|
||||||
{
|
{
|
||||||
QUIT;
|
QUIT;
|
||||||
|
|
||||||
if ((kind == ALL_DOMAIN
|
if ((domain == ALL_DOMAIN
|
||||||
|| (kind == VARIABLES_DOMAIN
|
|| (domain == VARIABLES_DOMAIN
|
||||||
&& PSYMBOL_CLASS (*psym) != LOC_TYPEDEF
|
&& PSYMBOL_CLASS (*psym) != LOC_TYPEDEF
|
||||||
&& PSYMBOL_CLASS (*psym) != LOC_BLOCK)
|
&& PSYMBOL_CLASS (*psym) != LOC_BLOCK)
|
||||||
|| (kind == FUNCTIONS_DOMAIN
|
|| (domain == FUNCTIONS_DOMAIN
|
||||||
&& PSYMBOL_CLASS (*psym) == LOC_BLOCK)
|
&& PSYMBOL_CLASS (*psym) == LOC_BLOCK)
|
||||||
|| (kind == TYPES_DOMAIN
|
|| (domain == TYPES_DOMAIN
|
||||||
&& PSYMBOL_CLASS (*psym) == LOC_TYPEDEF))
|
&& PSYMBOL_CLASS (*psym) == LOC_TYPEDEF))
|
||||||
&& sym_matcher (SYMBOL_SEARCH_NAME (*psym)))
|
&& psymbol_name_matches (*psym, lookup_name)
|
||||||
|
&& (sym_matcher == NULL || sym_matcher (SYMBOL_SEARCH_NAME (*psym))))
|
||||||
{
|
{
|
||||||
/* Found a match, so notify our caller. */
|
/* Found a match, so notify our caller. */
|
||||||
result = PST_SEARCHED_AND_FOUND;
|
result = PST_SEARCHED_AND_FOUND;
|
||||||
|
@ -1361,9 +1390,10 @@ static void
|
||||||
psym_expand_symtabs_matching
|
psym_expand_symtabs_matching
|
||||||
(struct objfile *objfile,
|
(struct objfile *objfile,
|
||||||
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
|
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
||||||
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
||||||
enum search_domain kind)
|
enum search_domain domain)
|
||||||
{
|
{
|
||||||
struct partial_symtab *ps;
|
struct partial_symtab *ps;
|
||||||
|
|
||||||
|
@ -1405,7 +1435,8 @@ psym_expand_symtabs_matching
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recursively_search_psymtabs (ps, objfile, kind, symbol_matcher))
|
if (recursively_search_psymtabs (ps, objfile, domain,
|
||||||
|
lookup_name, symbol_matcher))
|
||||||
{
|
{
|
||||||
struct compunit_symtab *symtab =
|
struct compunit_symtab *symtab =
|
||||||
psymtab_to_symtab (objfile, ps);
|
psymtab_to_symtab (objfile, ps);
|
||||||
|
|
|
@ -2250,7 +2250,7 @@ extern const struct language_defn rust_language_defn =
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
rust_watch_location_expression,
|
rust_watch_location_expression,
|
||||||
NULL, /* la_get_symbol_name_cmp */
|
NULL, /* la_get_symbol_name_matcher */
|
||||||
iterate_over_symbols,
|
iterate_over_symbols,
|
||||||
default_search_name_hash,
|
default_search_name_hash,
|
||||||
&default_varobj_ops,
|
&default_varobj_ops,
|
||||||
|
|
|
@ -260,7 +260,7 @@ debug_qf_map_matching_symbols (struct objfile *objfile,
|
||||||
int (*callback) (struct block *,
|
int (*callback) (struct block *,
|
||||||
struct symbol *, void *),
|
struct symbol *, void *),
|
||||||
void *data,
|
void *data,
|
||||||
symbol_compare_ftype *match,
|
symbol_name_match_type match,
|
||||||
symbol_compare_ftype *ordered_compare)
|
symbol_compare_ftype *ordered_compare)
|
||||||
{
|
{
|
||||||
const struct debug_sym_fns_data *debug_data
|
const struct debug_sym_fns_data *debug_data
|
||||||
|
@ -273,7 +273,7 @@ debug_qf_map_matching_symbols (struct objfile *objfile,
|
||||||
domain_name (domain), global,
|
domain_name (domain), global,
|
||||||
host_address_to_string (callback),
|
host_address_to_string (callback),
|
||||||
host_address_to_string (data),
|
host_address_to_string (data),
|
||||||
host_address_to_string (match),
|
plongest ((LONGEST) match),
|
||||||
host_address_to_string (ordered_compare));
|
host_address_to_string (ordered_compare));
|
||||||
|
|
||||||
debug_data->real_sf->qf->map_matching_symbols (objfile, name,
|
debug_data->real_sf->qf->map_matching_symbols (objfile, name,
|
||||||
|
@ -287,6 +287,7 @@ static void
|
||||||
debug_qf_expand_symtabs_matching
|
debug_qf_expand_symtabs_matching
|
||||||
(struct objfile *objfile,
|
(struct objfile *objfile,
|
||||||
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
|
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
||||||
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
||||||
enum search_domain kind)
|
enum search_domain kind)
|
||||||
|
@ -305,6 +306,7 @@ debug_qf_expand_symtabs_matching
|
||||||
|
|
||||||
debug_data->real_sf->qf->expand_symtabs_matching (objfile,
|
debug_data->real_sf->qf->expand_symtabs_matching (objfile,
|
||||||
file_matcher,
|
file_matcher,
|
||||||
|
lookup_name,
|
||||||
symbol_matcher,
|
symbol_matcher,
|
||||||
expansion_notify,
|
expansion_notify,
|
||||||
kind);
|
kind);
|
||||||
|
|
|
@ -3773,6 +3773,7 @@ symfile_free_objfile (struct objfile *objfile)
|
||||||
void
|
void
|
||||||
expand_symtabs_matching
|
expand_symtabs_matching
|
||||||
(gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
|
(gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
||||||
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
||||||
enum search_domain kind)
|
enum search_domain kind)
|
||||||
|
@ -3783,6 +3784,7 @@ expand_symtabs_matching
|
||||||
{
|
{
|
||||||
if (objfile->sf)
|
if (objfile->sf)
|
||||||
objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
|
objfile->sf->qf->expand_symtabs_matching (objfile, file_matcher,
|
||||||
|
lookup_name,
|
||||||
symbol_matcher,
|
symbol_matcher,
|
||||||
expansion_notify, kind);
|
expansion_notify, kind);
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,7 +231,7 @@ struct quick_symbol_functions
|
||||||
int (*callback) (struct block *,
|
int (*callback) (struct block *,
|
||||||
struct symbol *, void *),
|
struct symbol *, void *),
|
||||||
void *data,
|
void *data,
|
||||||
symbol_compare_ftype *match,
|
symbol_name_match_type match,
|
||||||
symbol_compare_ftype *ordered_compare);
|
symbol_compare_ftype *ordered_compare);
|
||||||
|
|
||||||
/* Expand all symbol tables in OBJFILE matching some criteria.
|
/* Expand all symbol tables in OBJFILE matching some criteria.
|
||||||
|
@ -255,6 +255,7 @@ struct quick_symbol_functions
|
||||||
void (*expand_symtabs_matching)
|
void (*expand_symtabs_matching)
|
||||||
(struct objfile *objfile,
|
(struct objfile *objfile,
|
||||||
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
|
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
||||||
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
||||||
enum search_domain kind);
|
enum search_domain kind);
|
||||||
|
@ -526,6 +527,7 @@ extern scoped_restore_tmpl<int> increment_reading_symtab (void);
|
||||||
|
|
||||||
void expand_symtabs_matching
|
void expand_symtabs_matching
|
||||||
(gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
|
(gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
|
||||||
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
|
||||||
enum search_domain kind);
|
enum search_domain kind);
|
||||||
|
|
|
@ -949,6 +949,7 @@ maintenance_expand_symtabs (const char *args, int from_tty)
|
||||||
return (!basenames
|
return (!basenames
|
||||||
&& (regexp == NULL || re_exec (filename)));
|
&& (regexp == NULL || re_exec (filename)));
|
||||||
},
|
},
|
||||||
|
lookup_name_info::match_any (),
|
||||||
[] (const char *symname)
|
[] (const char *symname)
|
||||||
{
|
{
|
||||||
/* Since we're not searching on symbols, just return true. */
|
/* Since we're not searching on symbols, just return true. */
|
||||||
|
|
196
gdb/symtab.c
196
gdb/symtab.c
|
@ -946,6 +946,19 @@ symbol_search_name (const struct general_symbol_info *gsymbol)
|
||||||
else
|
else
|
||||||
return symbol_natural_name (gsymbol);
|
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
|
/* 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)
|
else if (slot_name != NULL && name != NULL)
|
||||||
{
|
{
|
||||||
/* It's important that we use the same comparison that was done the
|
/* It's important that we use the same comparison that was done
|
||||||
first time through. If the slot records a found symbol, then this
|
the first time through. If the slot records a found symbol,
|
||||||
means using strcmp_iw on SYMBOL_SEARCH_NAME. See dictionary.c.
|
then this means using the symbol name comparison function of
|
||||||
It also means using symbol_matches_domain for found symbols.
|
the symbol's language with SYMBOL_SEARCH_NAME. See
|
||||||
See block.c.
|
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.
|
If the slot records a not-found symbol, then require a precise match.
|
||||||
We could still be lax with whitespace like strcmp_iw though. */
|
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
|
else
|
||||||
{
|
{
|
||||||
struct symbol *sym = slot->value.found.symbol;
|
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;
|
return 0;
|
||||||
|
|
||||||
if (!symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
if (!symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
||||||
slot_domain, domain))
|
slot_domain, domain))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1743,6 +1759,30 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
|
||||||
return sym;
|
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
|
/* Compute the demangled form of NAME as used by the various symbol
|
||||||
lookup functions. The result can either be the input NAME
|
lookup functions. The result can either be the input NAME
|
||||||
directly, or a pointer to a buffer owned by the STORAGE object.
|
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. */
|
search continues. */
|
||||||
|
|
||||||
void
|
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,
|
const domain_enum domain,
|
||||||
gdb::function_view<symbol_found_callback_ftype> callback)
|
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,
|
return file_matches (filename, files, nfiles,
|
||||||
basenames);
|
basenames);
|
||||||
},
|
},
|
||||||
|
lookup_name_info::match_any (),
|
||||||
[&] (const char *symname)
|
[&] (const char *symname)
|
||||||
{
|
{
|
||||||
return (!preg || preg->exec (symname,
|
return (!preg || preg->exec (symname,
|
||||||
|
@ -4587,13 +4629,33 @@ rbreak_command (const char *regexp, int from_tty)
|
||||||
information. */
|
information. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compare_symbol_name (const char *name, const char *sym_text, int sym_text_len)
|
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)
|
||||||
{
|
{
|
||||||
int (*ncmp) (const char *, const char *, size_t);
|
const language_defn *lang;
|
||||||
|
|
||||||
ncmp = (case_sensitivity == case_sensitive_on ? strncmp : strncasecmp);
|
/* 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);
|
||||||
|
|
||||||
if (ncmp (name, sym_text, sym_text_len) != 0)
|
symbol_name_matcher_ftype *name_match
|
||||||
|
= language_get_symbol_name_matcher (lang, lookup_name);
|
||||||
|
|
||||||
|
/* Clip symbols that cannot match. */
|
||||||
|
if (!name_match (name, lookup_name, &match_res.match))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (sym_text[sym_text_len] == '(')
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test to see if the symbol specified by SYMNAME (which is already
|
/* See symtab.h. */
|
||||||
demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
|
|
||||||
characters. If so, add it to the current completion list. */
|
|
||||||
|
|
||||||
static void
|
void
|
||||||
completion_list_add_name (completion_tracker &tracker,
|
completion_list_add_name (completion_tracker &tracker,
|
||||||
|
language symbol_language,
|
||||||
const char *symname,
|
const char *symname,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
const char *sym_text, int sym_text_len,
|
const char *sym_text, int sym_text_len,
|
||||||
const char *text, const char *word)
|
const char *text, const char *word)
|
||||||
{
|
{
|
||||||
|
completion_match_result &match_res
|
||||||
|
= tracker.reset_completion_match_result ();
|
||||||
|
|
||||||
/* Clip symbols that cannot match. */
|
/* 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;
|
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
|
/* 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. */
|
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
|
static void
|
||||||
completion_list_add_symbol (completion_tracker &tracker,
|
completion_list_add_symbol (completion_tracker &tracker,
|
||||||
symbol *sym,
|
symbol *sym,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
const char *sym_text, int sym_text_len,
|
const char *sym_text, int sym_text_len,
|
||||||
const char *text, const char *word)
|
const char *text, const char *word)
|
||||||
{
|
{
|
||||||
completion_list_add_name (tracker, SYMBOL_NATURAL_NAME (sym),
|
completion_list_add_name (tracker, SYMBOL_LANGUAGE (sym),
|
||||||
sym_text, sym_text_len, text, word);
|
SYMBOL_NATURAL_NAME (sym),
|
||||||
|
lookup_name, sym_text, sym_text_len, text, word);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* completion_list_add_name wrapper for struct minimal_symbol. */
|
/* completion_list_add_name wrapper for struct minimal_symbol. */
|
||||||
|
@ -4674,19 +4750,23 @@ completion_list_add_symbol (completion_tracker &tracker,
|
||||||
static void
|
static void
|
||||||
completion_list_add_msymbol (completion_tracker &tracker,
|
completion_list_add_msymbol (completion_tracker &tracker,
|
||||||
minimal_symbol *sym,
|
minimal_symbol *sym,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
const char *sym_text, int sym_text_len,
|
const char *sym_text, int sym_text_len,
|
||||||
const char *text, const char *word)
|
const char *text, const char *word)
|
||||||
{
|
{
|
||||||
completion_list_add_name (tracker, MSYMBOL_NATURAL_NAME (sym),
|
completion_list_add_name (tracker, MSYMBOL_LANGUAGE (sym),
|
||||||
sym_text, sym_text_len, text, word);
|
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
|
/* ObjC: In case we are completing on a selector, look as the msymbol
|
||||||
again and feed all the selectors into the mill. */
|
again and feed all the selectors into the mill. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
completion_list_objc_symbol (completion_tracker &tracker,
|
completion_list_objc_symbol (completion_tracker &tracker,
|
||||||
struct minimal_symbol *msymbol,
|
struct minimal_symbol *msymbol,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
const char *sym_text, int sym_text_len,
|
const char *sym_text, int sym_text_len,
|
||||||
const char *text, const char *word)
|
const char *text, const char *word)
|
||||||
{
|
{
|
||||||
|
@ -4704,7 +4784,9 @@ completion_list_objc_symbol (completion_tracker &tracker,
|
||||||
|
|
||||||
if (sym_text[0] == '[')
|
if (sym_text[0] == '[')
|
||||||
/* Complete on shortened method method. */
|
/* 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);
|
sym_text, sym_text_len, text, word);
|
||||||
|
|
||||||
while ((strlen (method) + 1) >= tmplen)
|
while ((strlen (method) + 1) >= tmplen)
|
||||||
|
@ -4726,10 +4808,12 @@ completion_list_objc_symbol (completion_tracker &tracker,
|
||||||
memcpy (tmp, method, (category - method));
|
memcpy (tmp, method, (category - method));
|
||||||
tmp[category - method] = ' ';
|
tmp[category - method] = ' ';
|
||||||
memcpy (tmp + (category - method) + 1, selector, strlen (selector) + 1);
|
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);
|
sym_text, sym_text_len, text, word);
|
||||||
if (sym_text[0] == '[')
|
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);
|
sym_text, sym_text_len, text, word);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4741,7 +4825,8 @@ completion_list_objc_symbol (completion_tracker &tracker,
|
||||||
if (tmp2 != NULL)
|
if (tmp2 != NULL)
|
||||||
*tmp2 = '\0';
|
*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);
|
sym_text, sym_text_len, text, word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4795,6 +4880,7 @@ language_search_unquoted_string (const char *text, const char *p)
|
||||||
static void
|
static void
|
||||||
completion_list_add_fields (completion_tracker &tracker,
|
completion_list_add_fields (completion_tracker &tracker,
|
||||||
struct symbol *sym,
|
struct symbol *sym,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
const char *sym_text, int sym_text_len,
|
const char *sym_text, int sym_text_len,
|
||||||
const char *text, const char *word)
|
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)
|
if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
|
||||||
for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
|
for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
|
||||||
if (TYPE_FIELD_NAME (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);
|
sym_text, sym_text_len, text, word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4817,6 +4905,7 @@ completion_list_add_fields (completion_tracker &tracker,
|
||||||
static void
|
static void
|
||||||
add_symtab_completions (struct compunit_symtab *cust,
|
add_symtab_completions (struct compunit_symtab *cust,
|
||||||
completion_tracker &tracker,
|
completion_tracker &tracker,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
const char *sym_text, int sym_text_len,
|
const char *sym_text, int sym_text_len,
|
||||||
const char *text, const char *word,
|
const char *text, const char *word,
|
||||||
enum type_code code)
|
enum type_code code)
|
||||||
|
@ -4839,6 +4928,7 @@ add_symtab_completions (struct compunit_symtab *cust,
|
||||||
|| (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
|
|| (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
|
||||||
&& TYPE_CODE (SYMBOL_TYPE (sym)) == code))
|
&& 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,
|
sym_text, sym_text_len,
|
||||||
text, word);
|
text, word);
|
||||||
}
|
}
|
||||||
|
@ -4847,8 +4937,8 @@ add_symtab_completions (struct compunit_symtab *cust,
|
||||||
|
|
||||||
void
|
void
|
||||||
default_collect_symbol_completion_matches_break_on
|
default_collect_symbol_completion_matches_break_on
|
||||||
(completion_tracker &tracker,
|
(completion_tracker &tracker, complete_symbol_mode mode,
|
||||||
complete_symbol_mode mode,
|
symbol_name_match_type name_match_type,
|
||||||
const char *text, const char *word,
|
const char *text, const char *word,
|
||||||
const char *break_on, enum type_code code)
|
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] == '(');
|
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
|
/* At this point scan through the misc symbol vectors and add each
|
||||||
symbol you find to the list. Eventually we want to ignore
|
symbol you find to the list. Eventually we want to ignore
|
||||||
anything that isn't a text symbol (everything else will be
|
anything that isn't a text symbol (everything else will be
|
||||||
|
@ -4950,34 +5043,30 @@ default_collect_symbol_completion_matches_break_on
|
||||||
{
|
{
|
||||||
QUIT;
|
QUIT;
|
||||||
|
|
||||||
completion_list_add_msymbol (tracker,
|
completion_list_add_msymbol (tracker, msymbol, lookup_name,
|
||||||
msymbol, sym_text, sym_text_len,
|
sym_text, sym_text_len,
|
||||||
text, word);
|
text, word);
|
||||||
|
|
||||||
completion_list_objc_symbol (tracker,
|
completion_list_objc_symbol (tracker, msymbol, lookup_name,
|
||||||
msymbol, sym_text, sym_text_len,
|
sym_text, sym_text_len, text,
|
||||||
text, word);
|
word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add completions for all currently loaded symbol tables. */
|
/* Add completions for all currently loaded symbol tables. */
|
||||||
ALL_COMPUNITS (objfile, cust)
|
ALL_COMPUNITS (objfile, cust)
|
||||||
add_symtab_completions (cust, tracker,
|
add_symtab_completions (cust, tracker, lookup_name,
|
||||||
sym_text, sym_text_len, text, word, code);
|
sym_text, sym_text_len, text, word, code);
|
||||||
|
|
||||||
/* Look through the partial symtabs for all symbols which begin by
|
/* Look through the partial symtabs for all symbols which begin by
|
||||||
matching SYM_TEXT. Expand all CUs that you find to the list. */
|
matching SYM_TEXT. Expand all CUs that you find to the list. */
|
||||||
expand_symtabs_matching (NULL,
|
expand_symtabs_matching (NULL,
|
||||||
[&] (const char *name) /* symbol matcher */
|
lookup_name,
|
||||||
{
|
NULL,
|
||||||
return compare_symbol_name (name,
|
|
||||||
sym_text,
|
|
||||||
sym_text_len);
|
|
||||||
},
|
|
||||||
[&] (compunit_symtab *symtab) /* expansion notify */
|
[&] (compunit_symtab *symtab) /* expansion notify */
|
||||||
{
|
{
|
||||||
add_symtab_completions (symtab,
|
add_symtab_completions (symtab,
|
||||||
tracker,
|
tracker, lookup_name,
|
||||||
sym_text, sym_text_len,
|
sym_text, sym_text_len,
|
||||||
text, word, code);
|
text, word, code);
|
||||||
},
|
},
|
||||||
|
@ -5000,16 +5089,16 @@ default_collect_symbol_completion_matches_break_on
|
||||||
{
|
{
|
||||||
if (code == TYPE_CODE_UNDEF)
|
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,
|
sym_text, sym_text_len, text,
|
||||||
word);
|
word);
|
||||||
completion_list_add_fields (tracker, sym,
|
completion_list_add_fields (tracker, sym, lookup_name,
|
||||||
sym_text, sym_text_len, text,
|
sym_text, sym_text_len, text,
|
||||||
word);
|
word);
|
||||||
}
|
}
|
||||||
else if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
|
else if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
|
||||||
&& TYPE_CODE (SYMBOL_TYPE (sym)) == code)
|
&& 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,
|
sym_text, sym_text_len, text,
|
||||||
word);
|
word);
|
||||||
}
|
}
|
||||||
|
@ -5028,12 +5117,12 @@ default_collect_symbol_completion_matches_break_on
|
||||||
{
|
{
|
||||||
if (surrounding_static_block != NULL)
|
if (surrounding_static_block != NULL)
|
||||||
ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym)
|
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);
|
sym_text, sym_text_len, text, word);
|
||||||
|
|
||||||
if (surrounding_global_block != NULL)
|
if (surrounding_global_block != NULL)
|
||||||
ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym)
|
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);
|
sym_text, sym_text_len, text, word);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5050,7 +5139,10 @@ default_collect_symbol_completion_matches_break_on
|
||||||
macro_source_file *,
|
macro_source_file *,
|
||||||
int)
|
int)
|
||||||
{
|
{
|
||||||
completion_list_add_name (tracker, macro_name,
|
completion_list_add_name (tracker,
|
||||||
|
language_c,
|
||||||
|
macro_name,
|
||||||
|
lookup_name,
|
||||||
sym_text, sym_text_len,
|
sym_text, sym_text_len,
|
||||||
text, word);
|
text, word);
|
||||||
};
|
};
|
||||||
|
@ -5078,10 +5170,12 @@ default_collect_symbol_completion_matches_break_on
|
||||||
void
|
void
|
||||||
default_collect_symbol_completion_matches (completion_tracker &tracker,
|
default_collect_symbol_completion_matches (completion_tracker &tracker,
|
||||||
complete_symbol_mode mode,
|
complete_symbol_mode mode,
|
||||||
|
symbol_name_match_type name_match_type,
|
||||||
const char *text, const char *word,
|
const char *text, const char *word,
|
||||||
enum type_code code)
|
enum type_code code)
|
||||||
{
|
{
|
||||||
return default_collect_symbol_completion_matches_break_on (tracker, mode,
|
return default_collect_symbol_completion_matches_break_on (tracker, mode,
|
||||||
|
name_match_type,
|
||||||
text, word, "",
|
text, word, "",
|
||||||
code);
|
code);
|
||||||
}
|
}
|
||||||
|
@ -5092,9 +5186,11 @@ default_collect_symbol_completion_matches (completion_tracker &tracker,
|
||||||
void
|
void
|
||||||
collect_symbol_completion_matches (completion_tracker &tracker,
|
collect_symbol_completion_matches (completion_tracker &tracker,
|
||||||
complete_symbol_mode mode,
|
complete_symbol_mode mode,
|
||||||
|
symbol_name_match_type name_match_type,
|
||||||
const char *text, const char *word)
|
const char *text, const char *word)
|
||||||
{
|
{
|
||||||
current_language->la_collect_symbol_completion_matches (tracker, mode,
|
current_language->la_collect_symbol_completion_matches (tracker, mode,
|
||||||
|
name_match_type,
|
||||||
text, word,
|
text, word,
|
||||||
TYPE_CODE_UNDEF);
|
TYPE_CODE_UNDEF);
|
||||||
}
|
}
|
||||||
|
@ -5108,11 +5204,13 @@ collect_symbol_completion_matches_type (completion_tracker &tracker,
|
||||||
enum type_code code)
|
enum type_code code)
|
||||||
{
|
{
|
||||||
complete_symbol_mode mode = complete_symbol_mode::EXPRESSION;
|
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
|
gdb_assert (code == TYPE_CODE_UNION
|
||||||
|| code == TYPE_CODE_STRUCT
|
|| code == TYPE_CODE_STRUCT
|
||||||
|| code == TYPE_CODE_ENUM);
|
|| code == TYPE_CODE_ENUM);
|
||||||
current_language->la_collect_symbol_completion_matches (tracker, mode,
|
current_language->la_collect_symbol_completion_matches (tracker, mode,
|
||||||
|
name_match_type,
|
||||||
text, word, code);
|
text, word, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5122,6 +5220,7 @@ collect_symbol_completion_matches_type (completion_tracker &tracker,
|
||||||
void
|
void
|
||||||
collect_file_symbol_completion_matches (completion_tracker &tracker,
|
collect_file_symbol_completion_matches (completion_tracker &tracker,
|
||||||
complete_symbol_mode mode,
|
complete_symbol_mode mode,
|
||||||
|
symbol_name_match_type name_match_type,
|
||||||
const char *text, const char *word,
|
const char *text, const char *word,
|
||||||
const char *srcfile)
|
const char *srcfile)
|
||||||
{
|
{
|
||||||
|
@ -5178,12 +5277,15 @@ collect_file_symbol_completion_matches (completion_tracker &tracker,
|
||||||
|
|
||||||
sym_text_len = strlen (sym_text);
|
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
|
/* Go through symtabs for SRCFILE and check the externs and statics
|
||||||
for symbols which match. */
|
for symbols which match. */
|
||||||
iterate_over_symtabs (srcfile, [&] (symtab *s)
|
iterate_over_symtabs (srcfile, [&] (symtab *s)
|
||||||
{
|
{
|
||||||
add_symtab_completions (SYMTAB_COMPUNIT (s),
|
add_symtab_completions (SYMTAB_COMPUNIT (s),
|
||||||
tracker,
|
tracker, lookup_name,
|
||||||
sym_text, sym_text_len,
|
sym_text, sym_text_len,
|
||||||
text, word, TYPE_CODE_UNDEF);
|
text, word, TYPE_CODE_UNDEF);
|
||||||
return false;
|
return false;
|
||||||
|
|
300
gdb/symtab.h
300
gdb/symtab.h
|
@ -21,10 +21,12 @@
|
||||||
#define SYMTAB_H 1
|
#define SYMTAB_H 1
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
#include "gdb_vecs.h"
|
#include "gdb_vecs.h"
|
||||||
#include "gdbtypes.h"
|
#include "gdbtypes.h"
|
||||||
#include "common/enum-flags.h"
|
#include "common/enum-flags.h"
|
||||||
#include "common/function-view.h"
|
#include "common/function-view.h"
|
||||||
|
#include "common/gdb_optional.h"
|
||||||
#include "completer.h"
|
#include "completer.h"
|
||||||
|
|
||||||
/* Opaque declarations. */
|
/* Opaque declarations. */
|
||||||
|
@ -43,6 +45,251 @@ struct probe;
|
||||||
struct common_block;
|
struct common_block;
|
||||||
struct obj_section;
|
struct obj_section;
|
||||||
struct cmd_list_element;
|
struct cmd_list_element;
|
||||||
|
struct lookup_name_info;
|
||||||
|
|
||||||
|
/* How to match a lookup name against a symbol search name. */
|
||||||
|
enum class symbol_name_match_type
|
||||||
|
{
|
||||||
|
/* Wild matching. Matches unqualified symbol names in all
|
||||||
|
namespace/module/packages, etc. */
|
||||||
|
WILD,
|
||||||
|
|
||||||
|
/* Full matching. The lookup name indicates a fully-qualified name,
|
||||||
|
and only matches symbol search names in the specified
|
||||||
|
namespace/module/package. */
|
||||||
|
FULL,
|
||||||
|
|
||||||
|
/* Expression matching. The same as FULL matching in most
|
||||||
|
languages. The same as WILD matching in Ada. */
|
||||||
|
EXPRESSION,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Hash the given symbol search name according to LANGUAGE's
|
||||||
|
rules. */
|
||||||
|
extern unsigned int search_name_hash (enum language language,
|
||||||
|
const char *search_name);
|
||||||
|
|
||||||
|
/* Ada-specific bits of a lookup_name_info object. This is lazily
|
||||||
|
constructed on demand. */
|
||||||
|
|
||||||
|
class ada_lookup_name_info final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* Construct. */
|
||||||
|
explicit ada_lookup_name_info (const lookup_name_info &lookup_name);
|
||||||
|
|
||||||
|
/* Compare SYMBOL_SEARCH_NAME with our lookup name, using MATCH_TYPE
|
||||||
|
as name match type. Returns true if there's a match, false
|
||||||
|
otherwise. If non-NULL, store the matching results in MATCH. */
|
||||||
|
bool matches (const char *symbol_search_name,
|
||||||
|
symbol_name_match_type match_type,
|
||||||
|
completion_match *match) const;
|
||||||
|
|
||||||
|
/* The Ada-encoded lookup name. */
|
||||||
|
const std::string &lookup_name () const
|
||||||
|
{ return m_encoded_name; }
|
||||||
|
|
||||||
|
/* Return true if we're supposed to be doing a wild match look
|
||||||
|
up. */
|
||||||
|
bool wild_match_p () const
|
||||||
|
{ return m_wild_match_p; }
|
||||||
|
|
||||||
|
/* Return true if we're looking up a name inside package
|
||||||
|
Standard. */
|
||||||
|
bool standard_p () const
|
||||||
|
{ return m_standard_p; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* The Ada-encoded lookup name. */
|
||||||
|
std::string m_encoded_name;
|
||||||
|
|
||||||
|
/* Whether the user-provided lookup name was Ada encoded. If so,
|
||||||
|
then return encoded names in the 'matches' method's 'completion
|
||||||
|
match result' output. */
|
||||||
|
bool m_encoded_p : 1;
|
||||||
|
|
||||||
|
/* True if really doing wild matching. Even if the user requests
|
||||||
|
wild matching, some cases require full matching. */
|
||||||
|
bool m_wild_match_p : 1;
|
||||||
|
|
||||||
|
/* True if doing a verbatim match. This is true if the decoded
|
||||||
|
version of the symbol name is wrapped in '<'/'>'. This is an
|
||||||
|
escape hatch users can use to look up symbols the Ada encoding
|
||||||
|
does not understand. */
|
||||||
|
bool m_verbatim_p : 1;
|
||||||
|
|
||||||
|
/* True if the user specified a symbol name that is inside package
|
||||||
|
Standard. Symbol names inside package Standard are handled
|
||||||
|
specially. We always do a non-wild match of the symbol name
|
||||||
|
without the "standard__" prefix, and only search static and
|
||||||
|
global symbols. This was primarily introduced in order to allow
|
||||||
|
the user to specifically access the standard exceptions using,
|
||||||
|
for instance, Standard.Constraint_Error when Constraint_Error is
|
||||||
|
ambiguous (due to the user defining its own Constraint_Error
|
||||||
|
entity inside its program). */
|
||||||
|
bool m_standard_p : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Language-specific bits of a lookup_name_info object, for languages
|
||||||
|
that do name searching using demangled names (C++/D/Go). This is
|
||||||
|
lazily constructed on demand. */
|
||||||
|
|
||||||
|
struct demangle_for_lookup_info final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
demangle_for_lookup_info (const lookup_name_info &lookup_name,
|
||||||
|
language lang);
|
||||||
|
|
||||||
|
/* The demangled lookup name. */
|
||||||
|
const std::string &lookup_name () const
|
||||||
|
{ return m_demangled_name; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* The demangled lookup name. */
|
||||||
|
std::string m_demangled_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Object that aggregates all information related to a symbol lookup
|
||||||
|
name. I.e., the name that is matched against the symbol's search
|
||||||
|
name. Caches per-language information so that it doesn't require
|
||||||
|
recomputing it for every symbol comparison, like for example the
|
||||||
|
Ada encoded name and the symbol's name hash for a given language.
|
||||||
|
The object is conceptually immutable once constructed, and thus has
|
||||||
|
no setters. This is to prevent some code path from tweaking some
|
||||||
|
property of the lookup name for some local reason and accidentally
|
||||||
|
altering the results of any continuing search(es).
|
||||||
|
lookup_name_info objects are generally passed around as a const
|
||||||
|
reference to reinforce that. (They're not passed around by value
|
||||||
|
because they're not small.) */
|
||||||
|
class lookup_name_info final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* Create a new object. */
|
||||||
|
lookup_name_info (std::string name,
|
||||||
|
symbol_name_match_type match_type,
|
||||||
|
bool completion_mode = false)
|
||||||
|
: m_match_type (match_type),
|
||||||
|
m_completion_mode (completion_mode),
|
||||||
|
m_name (std::move (name))
|
||||||
|
{}
|
||||||
|
|
||||||
|
/* Getters. See description of each corresponding field. */
|
||||||
|
symbol_name_match_type match_type () const { return m_match_type; }
|
||||||
|
bool completion_mode () const { return m_completion_mode; }
|
||||||
|
const std::string &name () const { return m_name; }
|
||||||
|
|
||||||
|
/* Get the search name hash for searches in language LANG. */
|
||||||
|
unsigned int search_name_hash (language lang) const
|
||||||
|
{
|
||||||
|
/* Only compute each language's hash once. */
|
||||||
|
if (!m_demangled_hashes_p[lang])
|
||||||
|
{
|
||||||
|
m_demangled_hashes[lang]
|
||||||
|
= ::search_name_hash (lang, language_lookup_name (lang).c_str ());
|
||||||
|
m_demangled_hashes_p[lang] = true;
|
||||||
|
}
|
||||||
|
return m_demangled_hashes[lang];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the search name for searches in language LANG. */
|
||||||
|
const std::string &language_lookup_name (language lang) const
|
||||||
|
{
|
||||||
|
switch (lang)
|
||||||
|
{
|
||||||
|
case language_ada:
|
||||||
|
return ada ().lookup_name ();
|
||||||
|
case language_cplus:
|
||||||
|
return cplus ().lookup_name ();
|
||||||
|
case language_d:
|
||||||
|
return d ().lookup_name ();
|
||||||
|
case language_go:
|
||||||
|
return go ().lookup_name ();
|
||||||
|
default:
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the Ada-specific lookup info. */
|
||||||
|
const ada_lookup_name_info &ada () const
|
||||||
|
{
|
||||||
|
maybe_init (m_ada);
|
||||||
|
return *m_ada;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the C++-specific lookup info. */
|
||||||
|
const demangle_for_lookup_info &cplus () const
|
||||||
|
{
|
||||||
|
maybe_init (m_cplus, language_cplus);
|
||||||
|
return *m_cplus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the D-specific lookup info. */
|
||||||
|
const demangle_for_lookup_info &d () const
|
||||||
|
{
|
||||||
|
maybe_init (m_d, language_d);
|
||||||
|
return *m_d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the Go-specific lookup info. */
|
||||||
|
const demangle_for_lookup_info &go () const
|
||||||
|
{
|
||||||
|
maybe_init (m_go, language_go);
|
||||||
|
return *m_go;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a reference to a lookup_name_info object that matches any
|
||||||
|
symbol name. */
|
||||||
|
static const lookup_name_info &match_any ();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* Initialize FIELD, if not initialized yet. */
|
||||||
|
template<typename Field, typename... Args>
|
||||||
|
void maybe_init (Field &field, Args&&... args) const
|
||||||
|
{
|
||||||
|
if (!field)
|
||||||
|
field.emplace (*this, std::forward<Args> (args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The lookup info as passed to the ctor. */
|
||||||
|
symbol_name_match_type m_match_type;
|
||||||
|
bool m_completion_mode;
|
||||||
|
std::string m_name;
|
||||||
|
|
||||||
|
/* Language-specific info. These fields are filled lazily the first
|
||||||
|
time a lookup is done in the corresponding language. They're
|
||||||
|
mutable because lookup_name_info objects are typically passed
|
||||||
|
around by const reference (see intro), and they're conceptually
|
||||||
|
"cache" that can always be reconstructed from the non-mutable
|
||||||
|
fields. */
|
||||||
|
mutable gdb::optional<ada_lookup_name_info> m_ada;
|
||||||
|
mutable gdb::optional<demangle_for_lookup_info> m_cplus;
|
||||||
|
mutable gdb::optional<demangle_for_lookup_info> m_d;
|
||||||
|
mutable gdb::optional<demangle_for_lookup_info> m_go;
|
||||||
|
|
||||||
|
/* The demangled hashes. Stored in an array with one entry for each
|
||||||
|
possible language. The second array records whether we've
|
||||||
|
already computed the each language's hash. (These are separate
|
||||||
|
arrays instead of a single array of optional<unsigned> to avoid
|
||||||
|
alignment padding). */
|
||||||
|
mutable std::array<unsigned int, nr_languages> m_demangled_hashes;
|
||||||
|
mutable std::array<bool, nr_languages> m_demangled_hashes_p {};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Comparison function for completion symbol lookup.
|
||||||
|
|
||||||
|
Returns true if the symbol name matches against LOOKUP_NAME.
|
||||||
|
|
||||||
|
SYMBOL_SEARCH_NAME should be a symbol's "search" name.
|
||||||
|
|
||||||
|
On success and if non-NULL, MATCH is set to point to the symbol
|
||||||
|
name as should be presented to the user as a completion match list
|
||||||
|
element. In most languages, this is the same as the symbol's
|
||||||
|
search name, but in some, like Ada, the display name is dynamically
|
||||||
|
computed within the comparison routine. */
|
||||||
|
typedef bool (symbol_name_matcher_ftype)
|
||||||
|
(const char *symbol_search_name,
|
||||||
|
const lookup_name_info &lookup_name,
|
||||||
|
completion_match *match);
|
||||||
|
|
||||||
/* Some of the structures in this file are space critical.
|
/* Some of the structures in this file are space critical.
|
||||||
The space-critical structures are:
|
The space-critical structures are:
|
||||||
|
@ -269,13 +516,18 @@ extern int demangle;
|
||||||
returns the same value (same pointer) as SYMBOL_LINKAGE_NAME. */
|
returns the same value (same pointer) as SYMBOL_LINKAGE_NAME. */
|
||||||
#define SYMBOL_SEARCH_NAME(symbol) \
|
#define SYMBOL_SEARCH_NAME(symbol) \
|
||||||
(symbol_search_name (&(symbol)->ginfo))
|
(symbol_search_name (&(symbol)->ginfo))
|
||||||
extern const char *symbol_search_name (const struct general_symbol_info *);
|
extern const char *symbol_search_name (const struct general_symbol_info *ginfo);
|
||||||
|
|
||||||
/* Return non-zero if NAME matches the "search" name of SYMBOL.
|
/* Return true if NAME matches the "search" name of SYMBOL, according
|
||||||
Whitespace and trailing parentheses are ignored.
|
to the symbol's language. */
|
||||||
See strcmp_iw for details about its behavior. */
|
#define SYMBOL_MATCHES_SEARCH_NAME(symbol, name) \
|
||||||
#define SYMBOL_MATCHES_SEARCH_NAME(symbol, name) \
|
symbol_matches_search_name (&(symbol)->ginfo, (name))
|
||||||
(strcmp_iw (SYMBOL_SEARCH_NAME (symbol), (name)) == 0)
|
|
||||||
|
/* Helper for SYMBOL_MATCHES_SEARCH_NAME that works with both symbols
|
||||||
|
and psymbols. */
|
||||||
|
extern bool symbol_matches_search_name
|
||||||
|
(const struct general_symbol_info *gsymbol,
|
||||||
|
const lookup_name_info &name);
|
||||||
|
|
||||||
/* Compute the hash of the given symbol search name of a symbol of
|
/* Compute the hash of the given symbol search name of a symbol of
|
||||||
language LANGUAGE. */
|
language LANGUAGE. */
|
||||||
|
@ -427,8 +679,6 @@ struct minimal_symbol
|
||||||
(symbol_set_language (&(symbol)->mginfo, (language), (obstack)))
|
(symbol_set_language (&(symbol)->mginfo, (language), (obstack)))
|
||||||
#define MSYMBOL_SEARCH_NAME(symbol) \
|
#define MSYMBOL_SEARCH_NAME(symbol) \
|
||||||
(symbol_search_name (&(symbol)->mginfo))
|
(symbol_search_name (&(symbol)->mginfo))
|
||||||
#define MSYMBOL_MATCHES_SEARCH_NAME(symbol, name) \
|
|
||||||
(strcmp_iw (MSYMBOL_SEARCH_NAME (symbol), (name)) == 0)
|
|
||||||
#define MSYMBOL_SET_NAMES(symbol,linkage_name,len,copy_name,objfile) \
|
#define MSYMBOL_SET_NAMES(symbol,linkage_name,len,copy_name,objfile) \
|
||||||
symbol_set_names (&(symbol)->mginfo, linkage_name, len, copy_name, objfile)
|
symbol_set_names (&(symbol)->mginfo, linkage_name, len, copy_name, objfile)
|
||||||
|
|
||||||
|
@ -1512,26 +1762,30 @@ enum class complete_symbol_mode
|
||||||
extern void default_collect_symbol_completion_matches_break_on
|
extern void default_collect_symbol_completion_matches_break_on
|
||||||
(completion_tracker &tracker,
|
(completion_tracker &tracker,
|
||||||
complete_symbol_mode mode,
|
complete_symbol_mode mode,
|
||||||
|
symbol_name_match_type name_match_type,
|
||||||
const char *text, const char *word, const char *break_on,
|
const char *text, const char *word, const char *break_on,
|
||||||
enum type_code code);
|
enum type_code code);
|
||||||
extern void default_collect_symbol_completion_matches
|
extern void default_collect_symbol_completion_matches
|
||||||
(completion_tracker &tracker,
|
(completion_tracker &tracker,
|
||||||
complete_symbol_mode,
|
complete_symbol_mode,
|
||||||
|
symbol_name_match_type name_match_type,
|
||||||
const char *,
|
const char *,
|
||||||
const char *,
|
const char *,
|
||||||
enum type_code);
|
enum type_code);
|
||||||
extern void collect_symbol_completion_matches (completion_tracker &tracker,
|
extern void collect_symbol_completion_matches
|
||||||
complete_symbol_mode,
|
(completion_tracker &tracker,
|
||||||
const char *, const char *);
|
complete_symbol_mode mode,
|
||||||
|
symbol_name_match_type name_match_type,
|
||||||
|
const char *, const char *);
|
||||||
extern void collect_symbol_completion_matches_type (completion_tracker &tracker,
|
extern void collect_symbol_completion_matches_type (completion_tracker &tracker,
|
||||||
const char *, const char *,
|
const char *, const char *,
|
||||||
enum type_code);
|
enum type_code);
|
||||||
|
|
||||||
extern void collect_file_symbol_completion_matches (completion_tracker &tracker,
|
extern void collect_file_symbol_completion_matches
|
||||||
complete_symbol_mode,
|
(completion_tracker &tracker,
|
||||||
const char *,
|
complete_symbol_mode,
|
||||||
const char *,
|
symbol_name_match_type name_match_type,
|
||||||
const char *);
|
const char *, const char *, const char *);
|
||||||
|
|
||||||
extern completion_list
|
extern completion_list
|
||||||
make_source_files_completion_list (const char *, const char *);
|
make_source_files_completion_list (const char *, const char *);
|
||||||
|
@ -1680,7 +1934,8 @@ std::vector<CORE_ADDR> find_pcs_for_symtab_line
|
||||||
|
|
||||||
typedef bool (symbol_found_callback_ftype) (symbol *sym);
|
typedef bool (symbol_found_callback_ftype) (symbol *sym);
|
||||||
|
|
||||||
void iterate_over_symbols (const struct block *block, const char *name,
|
void iterate_over_symbols (const struct block *block,
|
||||||
|
const lookup_name_info &name,
|
||||||
const domain_enum domain,
|
const domain_enum domain,
|
||||||
gdb::function_view<symbol_found_callback_ftype> callback);
|
gdb::function_view<symbol_found_callback_ftype> callback);
|
||||||
|
|
||||||
|
@ -1728,4 +1983,15 @@ void initialize_objfile_symbol (struct symbol *);
|
||||||
|
|
||||||
struct template_symbol *allocate_template_symbol (struct objfile *);
|
struct template_symbol *allocate_template_symbol (struct objfile *);
|
||||||
|
|
||||||
|
/* Test to see if the symbol of language SYMBOL_LANGUAGE 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. */
|
||||||
|
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);
|
||||||
|
|
||||||
#endif /* !defined(SYMTAB_H) */
|
#endif /* !defined(SYMTAB_H) */
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2017-11-08 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
* gdb.ada/complete.exp (p <Exported_Capitalized>): New test.
|
||||||
|
(p Exported_Capitalized): New test.
|
||||||
|
(p exported_capitalized): New test.
|
||||||
|
|
||||||
2017-11-07 Pedro Alves <palves@redhat.com>
|
2017-11-07 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* gdb.cp/ena-dis-br-range.exp: Add more tests.
|
* gdb.cp/ena-dis-br-range.exp: Add more tests.
|
||||||
|
|
|
@ -83,6 +83,16 @@ test_gdb_no_completion "exported"
|
||||||
test_gdb_complete "<Exported" \
|
test_gdb_complete "<Exported" \
|
||||||
"p <Exported_Capitalized>"
|
"p <Exported_Capitalized>"
|
||||||
|
|
||||||
|
# While at it, make sure we can print the symbol too, using the '<'
|
||||||
|
# notation.
|
||||||
|
gdb_test "p <Exported_Capitalized>" " = 2"
|
||||||
|
|
||||||
|
# Confirm that we can't print the symbol without the '<' notation.
|
||||||
|
gdb_test "p Exported_Capitalized" \
|
||||||
|
"No definition of \"exported_capitalized\" in current context."
|
||||||
|
gdb_test "p exported_capitalized" \
|
||||||
|
"No definition of \"exported_capitalized\" in current context."
|
||||||
|
|
||||||
# A global symbol, created by the binder, that starts with __gnat...
|
# A global symbol, created by the binder, that starts with __gnat...
|
||||||
test_gdb_complete "__gnat_ada_main_progra" \
|
test_gdb_complete "__gnat_ada_main_progra" \
|
||||||
"p __gnat_ada_main_program_name"
|
"p __gnat_ada_main_program_name"
|
||||||
|
|
16
gdb/utils.c
16
gdb/utils.c
|
@ -2156,21 +2156,9 @@ fprintf_symbol_filtered (struct ui_file *stream, const char *name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modes of operation for strncmp_iw_with_mode. */
|
/* See utils.h. */
|
||||||
|
|
||||||
enum class strncmp_iw_mode
|
int
|
||||||
{
|
|
||||||
/* Work like strncmp, while ignoring whitespace. */
|
|
||||||
NORMAL,
|
|
||||||
|
|
||||||
/* Like NORMAL, but also apply the strcmp_iw hack. I.e.,
|
|
||||||
string1=="FOO(PARAMS)" matches string2=="FOO". */
|
|
||||||
MATCH_PARAMS,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Helper for strncmp_iw and strcmp_iw. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
strncmp_iw_with_mode (const char *string1, const char *string2,
|
strncmp_iw_with_mode (const char *string1, const char *string2,
|
||||||
size_t string2_len, strncmp_iw_mode mode)
|
size_t string2_len, strncmp_iw_mode mode)
|
||||||
{
|
{
|
||||||
|
|
23
gdb/utils.h
23
gdb/utils.h
|
@ -31,6 +31,29 @@ extern void initialize_utils (void);
|
||||||
|
|
||||||
extern int sevenbit_strings;
|
extern int sevenbit_strings;
|
||||||
|
|
||||||
|
/* Modes of operation for strncmp_iw_with_mode. */
|
||||||
|
|
||||||
|
enum class strncmp_iw_mode
|
||||||
|
{
|
||||||
|
/* Do a strcmp() type operation on STRING1 and STRING2, ignoring any
|
||||||
|
differences in whitespace. Returns 0 if they match, non-zero if
|
||||||
|
they don't (slightly different than strcmp()'s range of return
|
||||||
|
values). */
|
||||||
|
NORMAL,
|
||||||
|
|
||||||
|
/* Like NORMAL, but also apply the strcmp_iw hack. I.e.,
|
||||||
|
string1=="FOO(PARAMS)" matches string2=="FOO". */
|
||||||
|
MATCH_PARAMS,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Helper for strcmp_iw and strncmp_iw. Exported so that languages
|
||||||
|
can implement both NORMAL and MATCH_PARAMS variants in a single
|
||||||
|
function and defer part of the work to strncmp_iw_with_mode. */
|
||||||
|
extern int strncmp_iw_with_mode (const char *string1,
|
||||||
|
const char *string2,
|
||||||
|
size_t string2_len,
|
||||||
|
strncmp_iw_mode mode);
|
||||||
|
|
||||||
/* Do a strncmp() type operation on STRING1 and STRING2, ignoring any
|
/* Do a strncmp() type operation on STRING1 and STRING2, ignoring any
|
||||||
differences in whitespace. STRING2_LEN is STRING2's length.
|
differences in whitespace. STRING2_LEN is STRING2's length.
|
||||||
Returns 0 if STRING1 matches STRING2_LEN characters of STRING2,
|
Returns 0 if STRING1 matches STRING2_LEN characters of STRING2,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue