diff options
Diffstat (limited to 'gdb/symtab.h')
-rw-r--r-- | gdb/symtab.h | 300 |
1 files changed, 283 insertions, 17 deletions
diff --git a/gdb/symtab.h b/gdb/symtab.h index d5c929d..5dfe953 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -21,10 +21,12 @@ #define SYMTAB_H 1 #include <vector> +#include <string> #include "gdb_vecs.h" #include "gdbtypes.h" #include "common/enum-flags.h" #include "common/function-view.h" +#include "common/gdb_optional.h" #include "completer.h" /* Opaque declarations. */ @@ -43,6 +45,251 @@ struct probe; struct common_block; struct obj_section; 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. The space-critical structures are: @@ -269,13 +516,18 @@ extern int demangle; returns the same value (same pointer) as SYMBOL_LINKAGE_NAME. */ #define SYMBOL_SEARCH_NAME(symbol) \ (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. - Whitespace and trailing parentheses are ignored. - See strcmp_iw for details about its behavior. */ -#define SYMBOL_MATCHES_SEARCH_NAME(symbol, name) \ - (strcmp_iw (SYMBOL_SEARCH_NAME (symbol), (name)) == 0) +/* Return true if NAME matches the "search" name of SYMBOL, according + to the symbol's language. */ +#define SYMBOL_MATCHES_SEARCH_NAME(symbol, name) \ + symbol_matches_search_name (&(symbol)->ginfo, (name)) + +/* 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 language LANGUAGE. */ @@ -427,8 +679,6 @@ struct minimal_symbol (symbol_set_language (&(symbol)->mginfo, (language), (obstack))) #define MSYMBOL_SEARCH_NAME(symbol) \ (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) \ 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 (completion_tracker &tracker, complete_symbol_mode mode, + symbol_name_match_type name_match_type, const char *text, const char *word, const char *break_on, enum type_code code); extern void default_collect_symbol_completion_matches (completion_tracker &tracker, complete_symbol_mode, + symbol_name_match_type name_match_type, const char *, const char *, enum type_code); -extern void collect_symbol_completion_matches (completion_tracker &tracker, - complete_symbol_mode, - const char *, const char *); +extern void collect_symbol_completion_matches + (completion_tracker &tracker, + 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, const char *, const char *, enum type_code); -extern void collect_file_symbol_completion_matches (completion_tracker &tracker, - complete_symbol_mode, - const char *, - const char *, - const char *); +extern void collect_file_symbol_completion_matches + (completion_tracker &tracker, + complete_symbol_mode, + symbol_name_match_type name_match_type, + const char *, const char *, const char *); extern completion_list 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); -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, 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 *); +/* 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) */ |