-/* 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. This would be a potential
- performance problem if it were not mitigated by the
- mapped_index::name_components lookup table, which significantly
- reduces the number of times we need to call into this matcher,
- making it a non-issue.
-
- - 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);
- symbol_name_matcher_ftype *name_matcher
- = get_symbol_name_matcher (lang, m_lookup_name);
-
- /* Don't insert the same comparison routine more than once.
- Note that we do this linear walk instead of a seemingly
- 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 (name_matcher != default_symbol_name_matcher
- && (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;
-}
-