diff options
Diffstat (limited to 'gdb/dwarf2/cooked-index.c')
-rw-r--r-- | gdb/dwarf2/cooked-index.c | 311 |
1 files changed, 0 insertions, 311 deletions
diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c index 9d5f152..5d205a8 100644 --- a/gdb/dwarf2/cooked-index.c +++ b/gdb/dwarf2/cooked-index.c @@ -18,14 +18,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "dwarf2/cooked-index.h" -#include "dwarf2/index-common.h" #include "dwarf2/read.h" #include "dwarf2/stringify.h" #include "dwarf2/index-cache.h" -#include "cp-support.h" -#include "c-lang.h" -#include "ada-lang.h" -#include "dwarf2/tag.h" #include "event-top.h" #include "exceptions.h" #include "split-name.h" @@ -55,312 +50,6 @@ language_requires_canonicalization (enum language lang) || lang == language_cplus); } -/* Return true if a plain "main" could be the main program for this - language. Languages that are known to use some other mechanism are - excluded here. */ - -static bool -language_may_use_plain_main (enum language lang) -{ - /* No need to handle "unknown" here. */ - return (lang == language_c - || lang == language_objc - || lang == language_cplus - || lang == language_m2 - || lang == language_asm - || lang == language_opencl - || lang == language_minimal); -} - -/* See cooked-index.h. */ - -cooked_index_entry * -cooked_index_shard::create (sect_offset die_offset, - enum dwarf_tag tag, - cooked_index_flag flags, - enum language lang, - const char *name, - cooked_index_entry_ref parent_entry, - dwarf2_per_cu *per_cu) -{ - if (tag == DW_TAG_module || tag == DW_TAG_namespace) - flags &= ~IS_STATIC; - else if (lang == language_cplus - && (tag == DW_TAG_class_type - || tag == DW_TAG_interface_type - || tag == DW_TAG_structure_type - || tag == DW_TAG_union_type - || tag == DW_TAG_enumeration_type - || tag == DW_TAG_enumerator)) - flags &= ~IS_STATIC; - else if (tag_is_type (tag)) - flags |= IS_STATIC; - - return new (&m_storage) cooked_index_entry (die_offset, tag, flags, - lang, name, parent_entry, - per_cu); -} - -/* See cooked-index.h. */ - -cooked_index_entry * -cooked_index_shard::add (sect_offset die_offset, enum dwarf_tag tag, - cooked_index_flag flags, enum language lang, - const char *name, cooked_index_entry_ref parent_entry, - dwarf2_per_cu *per_cu) -{ - cooked_index_entry *result = create (die_offset, tag, flags, lang, name, - parent_entry, per_cu); - m_entries.push_back (result); - - /* An explicitly-tagged main program should always override the - implicit "main" discovery. */ - if ((flags & IS_MAIN) != 0) - m_main = result; - else if ((flags & IS_PARENT_DEFERRED) == 0 - && parent_entry.resolved == nullptr - && m_main == nullptr - && language_may_use_plain_main (lang) - && strcmp (name, "main") == 0) - m_main = result; - - return result; -} - -/* See cooked-index.h. */ - -void -cooked_index_shard::handle_gnat_encoded_entry - (cooked_index_entry *entry, - htab_t gnat_entries, - std::vector<cooked_index_entry *> &new_entries) -{ - /* We decode Ada names in a particular way: operators and wide - characters are left as-is. This is done to make name matching a - bit simpler; and for wide characters, it means the choice of Ada - source charset does not affect the indexer directly. */ - std::string canonical = ada_decode (entry->name, false, false, false); - if (canonical.empty ()) - { - entry->canonical = entry->name; - return; - } - std::vector<std::string_view> names = split_name (canonical.c_str (), - split_style::DOT_STYLE); - std::string_view tail = names.back (); - names.pop_back (); - - const cooked_index_entry *parent = nullptr; - for (const auto &name : names) - { - uint32_t hashval = dwarf5_djb_hash (name); - void **slot = htab_find_slot_with_hash (gnat_entries, &name, - hashval, INSERT); - /* CUs are processed in order, so we only need to check the most - recent entry. */ - cooked_index_entry *last = (cooked_index_entry *) *slot; - if (last == nullptr || last->per_cu != entry->per_cu) - { - const char *new_name = m_names.insert (name); - last = create (entry->die_offset, DW_TAG_module, - IS_SYNTHESIZED, language_ada, new_name, parent, - entry->per_cu); - last->canonical = last->name; - new_entries.push_back (last); - *slot = last; - } - - parent = last; - } - - entry->set_parent (parent); - entry->canonical = m_names.insert (tail); -} - -/* Hash a cooked index entry by name pointer value. - - We can use pointer equality here because names come from .debug_str, which - will normally be unique-ified by the linker. Also, duplicates are relatively - harmless -- they just mean a bit of extra memory is used. */ - -struct cooked_index_entry_name_ptr_hash -{ - using is_avalanching = void; - - std::uint64_t operator () (const cooked_index_entry *entry) const noexcept - { - return ankerl::unordered_dense::hash<const char *> () (entry->name); - } -}; - -/* Compare cooked index entries by name pointer value. */ - -struct cooked_index_entry_name_ptr_eq -{ - bool operator () (const cooked_index_entry *a, - const cooked_index_entry *b) const noexcept - { - return a->name == b->name; - } -}; - -/* See cooked-index.h. */ - -void -cooked_index_shard::finalize (const parent_map_map *parent_maps) -{ - gdb::unordered_set<const cooked_index_entry *, - cooked_index_entry_name_ptr_hash, - cooked_index_entry_name_ptr_eq> seen_names; - - auto hash_entry = [] (const void *e) - { - const cooked_index_entry *entry = (const cooked_index_entry *) e; - return dwarf5_djb_hash (entry->canonical); - }; - - auto eq_entry = [] (const void *a, const void *b) -> int - { - const cooked_index_entry *ae = (const cooked_index_entry *) a; - const std::string_view *sv = (const std::string_view *) b; - return (strlen (ae->canonical) == sv->length () - && strncasecmp (ae->canonical, sv->data (), sv->length ()) == 0); - }; - - htab_up gnat_entries (htab_create_alloc (10, hash_entry, eq_entry, - nullptr, xcalloc, xfree)); - std::vector<cooked_index_entry *> new_gnat_entries; - - for (cooked_index_entry *entry : m_entries) - { - if ((entry->flags & IS_PARENT_DEFERRED) != 0) - { - const cooked_index_entry *new_parent - = parent_maps->find (entry->get_deferred_parent ()); - entry->resolve_parent (new_parent); - } - - /* Note that this code must be kept in sync with - language_requires_canonicalization. */ - gdb_assert (entry->canonical == nullptr); - if ((entry->flags & IS_LINKAGE) != 0) - entry->canonical = entry->name; - else if (entry->lang == language_ada) - { - /* Newer versions of GNAT emit DW_TAG_module and use a - hierarchical structure. In this case, we don't need to - do any extra work. This can be detected by looking for a - GNAT-encoded name. */ - if (strstr (entry->name, "__") == nullptr) - { - entry->canonical = entry->name; - - /* If the entry does not have a parent, then there's - nothing extra to do here -- the entry itself is - sufficient. - - However, if it does have a parent, we have to - synthesize an entry with the full name. This is - unfortunate, but it's necessary due to how some of - the Ada name-lookup code currently works. For - example, without this, ada_get_tsd_type will - fail. - - Eventually it would be good to change the Ada lookup - code, and then remove these entries (and supporting - code in cooked_index_entry::full_name). */ - if (entry->get_parent () != nullptr) - { - const char *fullname - = entry->full_name (&m_storage, FOR_ADA_LINKAGE_NAME); - cooked_index_entry *linkage = create (entry->die_offset, - entry->tag, - (entry->flags - | IS_LINKAGE - | IS_SYNTHESIZED), - language_ada, - fullname, - nullptr, - entry->per_cu); - linkage->canonical = fullname; - new_gnat_entries.push_back (linkage); - } - } - else - handle_gnat_encoded_entry (entry, gnat_entries.get (), - new_gnat_entries); - } - else if (entry->lang == language_cplus || entry->lang == language_c) - { - auto [it, inserted] = seen_names.insert (entry); - - if (inserted) - { - /* No entry with that name was present, compute the canonical - name. */ - gdb::unique_xmalloc_ptr<char> canon_name - = (entry->lang == language_cplus - ? cp_canonicalize_string (entry->name) - : c_canonicalize_name (entry->name)); - if (canon_name == nullptr) - entry->canonical = entry->name; - else - entry->canonical = m_names.insert (std::move (canon_name)); - } - else - { - /* An entry with that name was present, re-use its canonical - name. */ - entry->canonical = (*it)->canonical; - } - } - else - entry->canonical = entry->name; - } - - /* Make sure any new Ada entries end up in the results. This isn't - done when creating these new entries to avoid invalidating the - m_entries iterator used in the foreach above. */ - m_entries.insert (m_entries.end (), new_gnat_entries.begin (), - new_gnat_entries.end ()); - - m_entries.shrink_to_fit (); - std::sort (m_entries.begin (), m_entries.end (), - [] (const cooked_index_entry *a, const cooked_index_entry *b) - { - return *a < *b; - }); -} - -/* See cooked-index.h. */ - -cooked_index_shard::range -cooked_index_shard::find (const std::string &name, bool completing) const -{ - struct comparator - { - cooked_index_entry::comparison_mode mode; - - bool operator() (const cooked_index_entry *entry, - const char *name) const noexcept - { - return cooked_index_entry::compare (entry->canonical, name, mode) < 0; - } - - bool operator() (const char *name, - const cooked_index_entry *entry) const noexcept - { - return cooked_index_entry::compare (entry->canonical, name, mode) > 0; - } - }; - - return std::make_from_tuple<range> - (std::equal_range (m_entries.cbegin (), m_entries.cend (), name.c_str (), - comparator { (completing - ? cooked_index_entry::COMPLETE - : cooked_index_entry::MATCH) })); -} - /* See cooked-index.h. */ void |