
Currently, we have a mess of symbol name hashing/comparison routines. There's msymbol_hash for mangled names, and dict_hash and msymbol_hash_iw for demangled names. Then there's strcmp_iw, strcmp_iw_ordered and Ada's full_match/wild_match, which all have to agree with the hashing routines. That's why dict_hash is really about Ada names. From the inconsistency department, minimal symbol hashing doesn't go via dict_hash, so Ada's wild matching can't ever work with minimal symbols. This patch starts fixing this, by doing two things: #1 - adds a language vector method to let each language decide how to compute a symbol name hash. #2 - makes dictionaries know the language of the symbols they hold, and then use the dictionaries language to decide which hashing method to use. For now, this is just scaffolding, since all languages install the default method. The series will make C++ install its own hashing method later on, and will add per-language symbol name comparison routines too. This patch was originally based on a patch that Keith wrote for the libcc1/C++ WIP support. gdb/ChangeLog: 2017-11-08 Keith Seitz <keiths@redhat.com> Pedro Alves <palves@redhat.com> * ada-lang.c (ada_language_defn): Install default_search_name_hash. * buildsym.c (struct buildsym_compunit): <language>: New field. (finish_block_internal): Pass language when creating dictionaries. (start_buildsym_compunit, start_symtab): New language parameters. Use them. (restart_symtab): Pass down compilation unit's language. * buildsym.h (enum language): Forward declare. (start_symtab): New 'language' parameter. * c-lang.c (c_language_defn, cplus_language_defn) (asm_language_defn, minimal_language_defn): Install default_search_name_hash. * coffread.c (coff_start_symtab): Adjust. * d-lang.c (d_language_defn): Install default_search_name_hash. * dbxread.c (struct symloc): Add 'pst_language' field. (PST_LANGUAGE): Define. (start_psymtab, read_ofile_symtab): Use it. (process_one_symbol): New 'language' parameter. Pass it down. * dictionary.c (struct dictionary) <language>: New field. (DICT_LANGUAGE): Define. (dict_create_hashed, dict_create_hashed_expandable) (dict_create_linear, dict_create_linear_expandable): New parameter 'language'. Set the dictionary's language. (iter_match_first_hashed): Adjust to rename. (insert_symbol_hashed): Assert we don't see mismatching languages. Adjust to rename. (dict_hash): Rename to ... (default_search_name_hash): ... this and make extern. * dictionary.h (struct language_defn): Forward declare. (dict_create_hashed): New parameter 'language'. * dwarf2read.c (dwarf2_start_symtab): Pass down language. * f-lang.c (f_language_defn): Install default_search_name_hash. * go-lang.c (go_language_defn): Install default_search_name_hash. * jit.c (finalize_symtab): Pass compunit's language to dictionary creation. * language.c (unknown_language_defn, auto_language_defn): * language.h (language_defn::la_search_name_hash): New field. (default_search_name_hash): Declare. * m2-lang.c (m2_language_defn): Install default_search_name_hash. * mdebugread.c (new_block): New parameter 'language'. * mdebugread.c (parse_symbol): Pass symbol language to block allocation. (psymtab_to_symtab_1): Pass down language. (new_symtab): Pass compunit's language to block allocation. * objc-lang.c (objc_language_defn): Install default_search_name_hash. * opencl-lang.c (opencl_language_defn): * p-lang.c (pascal_language_defn): Install default_search_name_hash. * rust-lang.c (rust_language_defn): Install default_search_name_hash. * stabsread.h (enum language): Forward declare. (process_one_symbol): Add 'language' parameter. * symtab.c (search_name_hash): New function. * symtab.h (search_name_hash): Declare. * xcoffread.c (read_xcoff_symtab): Pass language to start_symtab.
169 lines
6.1 KiB
C
169 lines
6.1 KiB
C
/* Routines for name->symbol lookups in GDB.
|
|
|
|
Copyright (C) 2003-2017 Free Software Foundation, Inc.
|
|
|
|
Contributed by David Carlton <carlton@bactrian.org> and by Kealia,
|
|
Inc.
|
|
|
|
This file is part of GDB.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#ifndef DICTIONARY_H
|
|
#define DICTIONARY_H
|
|
|
|
#include "symfile.h"
|
|
|
|
/* An opaque type for dictionaries; only dictionary.c should know
|
|
about its innards. */
|
|
|
|
struct dictionary;
|
|
|
|
/* Other types needed for declarations. */
|
|
|
|
struct symbol;
|
|
struct obstack;
|
|
struct pending;
|
|
struct language_defn;
|
|
|
|
/* The creation functions for various implementations of
|
|
dictionaries. */
|
|
|
|
/* Create a dictionary of symbols of language LANGUAGE implemented via
|
|
a fixed-size hashtable. All memory it uses is allocated on
|
|
OBSTACK; the environment is initialized from SYMBOL_LIST. */
|
|
|
|
extern struct dictionary *dict_create_hashed (struct obstack *obstack,
|
|
enum language language,
|
|
const struct pending
|
|
*symbol_list);
|
|
|
|
/* Create a dictionary of symbols of language LANGUAGE, implemented
|
|
via a hashtable that grows as necessary. The dictionary is
|
|
initially empty; to add symbols to it, call dict_add_symbol().
|
|
Call dict_free() when you're done with it. */
|
|
|
|
extern struct dictionary *
|
|
dict_create_hashed_expandable (enum language language);
|
|
|
|
/* Create a dictionary of symbols of language LANGUAGE, implemented
|
|
via a fixed-size array. All memory it uses is allocated on
|
|
OBSTACK; the environment is initialized from the SYMBOL_LIST. The
|
|
symbols are ordered in the same order that they're found in
|
|
SYMBOL_LIST. */
|
|
|
|
extern struct dictionary *dict_create_linear (struct obstack *obstack,
|
|
enum language language,
|
|
const struct pending
|
|
*symbol_list);
|
|
|
|
/* Create a dictionary of symbols of language LANGUAGE, implemented
|
|
via an array that grows as necessary. The dictionary is initially
|
|
empty; to add symbols to it, call dict_add_symbol(). Call
|
|
dict_free() when you're done with it. */
|
|
|
|
extern struct dictionary *
|
|
dict_create_linear_expandable (enum language language);
|
|
|
|
/* The functions providing the interface to dictionaries. Note that
|
|
the most common parts of the interface, namely symbol lookup, are
|
|
only provided via iterator functions. */
|
|
|
|
/* Free the memory used by a dictionary that's not on an obstack. (If
|
|
any.) */
|
|
|
|
extern void dict_free (struct dictionary *dict);
|
|
|
|
/* Add a symbol to an expandable dictionary. */
|
|
|
|
extern void dict_add_symbol (struct dictionary *dict, struct symbol *sym);
|
|
|
|
/* Utility to add a list of symbols to a dictionary. */
|
|
|
|
extern void dict_add_pending (struct dictionary *dict,
|
|
const struct pending *symbol_list);
|
|
|
|
/* Is the dictionary empty? */
|
|
|
|
extern int dict_empty (struct dictionary *dict);
|
|
|
|
/* A type containing data that is used when iterating over all symbols
|
|
in a dictionary. Don't ever look at its innards; this type would
|
|
be opaque if we didn't need to be able to allocate it on the
|
|
stack. */
|
|
|
|
struct dict_iterator
|
|
{
|
|
/* The dictionary that this iterator is associated to. */
|
|
const struct dictionary *dict;
|
|
/* The next two members are data that is used in a way that depends
|
|
on DICT's implementation type. */
|
|
int index;
|
|
struct symbol *current;
|
|
};
|
|
|
|
/* Initialize ITERATOR to point at the first symbol in DICT, and
|
|
return that first symbol, or NULL if DICT is empty. */
|
|
|
|
extern struct symbol *dict_iterator_first (const struct dictionary *dict,
|
|
struct dict_iterator *iterator);
|
|
|
|
/* Advance ITERATOR, and return the next symbol, or NULL if there are
|
|
no more symbols. Don't call this if you've previously received
|
|
NULL from dict_iterator_first or dict_iterator_next on this
|
|
iteration. */
|
|
|
|
extern struct symbol *dict_iterator_next (struct dict_iterator *iterator);
|
|
|
|
/* Initialize ITERATOR to point at the first symbol in DICT whose
|
|
SYMBOL_SEARCH_NAME is NAME, as tested using COMPARE (which must use
|
|
the same conventions as strcmp_iw and be compatible with any
|
|
dictionary hashing function), and return that first symbol, or NULL
|
|
if there are no such symbols. */
|
|
|
|
extern struct symbol *dict_iter_match_first (const struct dictionary *dict,
|
|
const char *name,
|
|
symbol_compare_ftype *compare,
|
|
struct dict_iterator *iterator);
|
|
|
|
/* Advance ITERATOR to point at the next symbol in DICT whose
|
|
SYMBOL_SEARCH_NAME is NAME, as tested using COMPARE (see
|
|
dict_iter_match_first), or NULL if there are no more such symbols.
|
|
Don't call this if you've previously received NULL from
|
|
dict_iterator_match_first or dict_iterator_match_next on this
|
|
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. */
|
|
|
|
extern struct symbol *dict_iter_match_next (const char *name,
|
|
symbol_compare_ftype *compare,
|
|
struct dict_iterator *iterator);
|
|
|
|
/* Return some notion of the size of the dictionary: the number of
|
|
symbols if we have that, the number of hash buckets otherwise. */
|
|
|
|
extern int dict_size (const struct dictionary *dict);
|
|
|
|
/* Macro to loop through all symbols in a dictionary DICT, in no
|
|
particular order. ITER is a struct dict_iterator (NOTE: __not__ a
|
|
struct dict_iterator *), and SYM points to the current symbol.
|
|
|
|
It's implemented as a single loop, so you can terminate the loop
|
|
early by a break if you desire. */
|
|
|
|
#define ALL_DICT_SYMBOLS(dict, iter, sym) \
|
|
for ((sym) = dict_iterator_first ((dict), &(iter)); \
|
|
(sym); \
|
|
(sym) = dict_iterator_next (&(iter)))
|
|
|
|
#endif /* DICTIONARY_H */
|