3 Copyright (C) 2022 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "dwarf2/cooked-index.h"
22 #include "dwarf2/read.h"
23 #include "cp-support.h"
26 #include "split-name.h"
29 /* Hash function for cooked_index_entry. */
32 hash_entry (const void *e)
34 const cooked_index_entry *entry = (const cooked_index_entry *) e;
35 return dwarf5_djb_hash (entry->canonical);
38 /* Equality function for cooked_index_entry. */
41 eq_entry (const void *a, const void *b)
43 const cooked_index_entry *ae = (const cooked_index_entry *) a;
44 const gdb::string_view *sv = (const gdb::string_view *) b;
45 return (strlen (ae->canonical) == sv->length ()
46 && strncasecmp (ae->canonical, sv->data (), sv->length ()) == 0);
49 /* See cooked-index.h. */
52 cooked_index_entry::full_name (struct obstack *storage) const
54 if ((flags & IS_LINKAGE) != 0 || parent_entry == nullptr)
57 const char *sep = nullptr;
58 switch (per_cu->lang ())
75 parent_entry->write_scope (storage, sep);
76 obstack_grow0 (storage, canonical, strlen (canonical));
77 return (const char *) obstack_finish (storage);
80 /* See cooked-index.h. */
83 cooked_index_entry::write_scope (struct obstack *storage,
84 const char *sep) const
86 if (parent_entry != nullptr)
87 parent_entry->write_scope (storage, sep);
88 obstack_grow (storage, canonical, strlen (canonical));
89 obstack_grow (storage, sep, strlen (sep));
92 /* See cooked-index.h. */
94 const cooked_index_entry *
95 cooked_index::add (sect_offset die_offset, enum dwarf_tag tag,
96 cooked_index_flag flags, const char *name,
97 const cooked_index_entry *parent_entry,
98 dwarf2_per_cu_data *per_cu)
100 cooked_index_entry *result = create (die_offset, tag, flags, name,
101 parent_entry, per_cu);
102 m_entries.push_back (result);
104 /* An explicitly-tagged main program should always override the
105 implicit "main" discovery. */
106 if ((flags & IS_MAIN) != 0)
108 else if (per_cu->lang () != language_ada
110 && strcmp (name, "main") == 0)
116 /* See cooked-index.h. */
119 cooked_index::finalize ()
121 m_future = gdb::thread_pool::g_thread_pool->post_task ([this] ()
127 /* See cooked-index.h. */
129 gdb::unique_xmalloc_ptr<char>
130 cooked_index::handle_gnat_encoded_entry (cooked_index_entry *entry,
133 std::string canonical = ada_decode (entry->name, false, false);
134 if (canonical.empty ())
136 std::vector<gdb::string_view> names = split_name (canonical.c_str (),
138 gdb::string_view tail = names.back ();
141 const cooked_index_entry *parent = nullptr;
142 for (const auto &name : names)
144 uint32_t hashval = dwarf5_djb_hash (name);
145 void **slot = htab_find_slot_with_hash (gnat_entries, &name,
147 /* CUs are processed in order, so we only need to check the most
149 cooked_index_entry *last = (cooked_index_entry *) *slot;
150 if (last == nullptr || last->per_cu != entry->per_cu)
152 gdb::unique_xmalloc_ptr<char> new_name
153 = make_unique_xstrndup (name.data (), name.length ());
154 last = create (entry->die_offset, DW_TAG_namespace,
155 0, new_name.get (), parent,
157 last->canonical = last->name;
158 m_names.push_back (std::move (new_name));
165 entry->parent_entry = parent;
166 return make_unique_xstrndup (tail.data (), tail.length ());
169 /* See cooked-index.h. */
172 cooked_index::do_finalize ()
174 auto hash_name_ptr = [] (const void *p)
176 const cooked_index_entry *entry = (const cooked_index_entry *) p;
177 return htab_hash_pointer (entry->name);
180 auto eq_name_ptr = [] (const void *a, const void *b) -> int
182 const cooked_index_entry *ea = (const cooked_index_entry *) a;
183 const cooked_index_entry *eb = (const cooked_index_entry *) b;
184 return ea->name == eb->name;
187 /* We can use pointer equality here because names come from
188 .debug_str, which will normally be unique-ified by the linker.
189 Also, duplicates are relatively harmless -- they just mean a bit
190 of extra memory is used. */
191 htab_up seen_names (htab_create_alloc (10, hash_name_ptr, eq_name_ptr,
192 nullptr, xcalloc, xfree));
194 htab_up gnat_entries (htab_create_alloc (10, hash_entry, eq_entry,
195 nullptr, xcalloc, xfree));
197 for (cooked_index_entry *entry : m_entries)
199 gdb_assert (entry->canonical == nullptr);
200 if ((entry->flags & IS_LINKAGE) != 0)
201 entry->canonical = entry->name;
202 else if (entry->per_cu->lang () == language_ada)
204 gdb::unique_xmalloc_ptr<char> canon_name
205 = handle_gnat_encoded_entry (entry, gnat_entries.get ());
206 if (canon_name == nullptr)
207 entry->canonical = entry->name;
210 entry->canonical = canon_name.get ();
211 m_names.push_back (std::move (canon_name));
214 else if (entry->per_cu->lang () == language_cplus
215 || entry->per_cu->lang () == language_c)
217 void **slot = htab_find_slot (seen_names.get (), entry,
219 if (*slot == nullptr)
221 gdb::unique_xmalloc_ptr<char> canon_name
222 = (entry->per_cu->lang () == language_cplus
223 ? cp_canonicalize_string (entry->name)
224 : c_canonicalize_name (entry->name));
225 if (canon_name == nullptr)
226 entry->canonical = entry->name;
229 entry->canonical = canon_name.get ();
230 m_names.push_back (std::move (canon_name));
235 const cooked_index_entry *other
236 = (const cooked_index_entry *) *slot;
237 entry->canonical = other->canonical;
241 entry->canonical = entry->name;
244 m_names.shrink_to_fit ();
245 m_entries.shrink_to_fit ();
246 std::sort (m_entries.begin (), m_entries.end (),
247 [] (const cooked_index_entry *a, const cooked_index_entry *b)
253 /* See cooked-index.h. */
256 cooked_index::find (gdb::string_view name, bool completing)
260 auto lower = std::lower_bound (m_entries.begin (), m_entries.end (),
262 [=] (const cooked_index_entry *entry,
263 const gdb::string_view &n)
265 int cmp = strncasecmp (entry->canonical, n.data (), n.length ());
266 if (cmp != 0 || completing)
268 return strlen (entry->canonical) < n.length ();
271 auto upper = std::upper_bound (m_entries.begin (), m_entries.end (),
273 [=] (const gdb::string_view &n,
274 const cooked_index_entry *entry)
276 int cmp = strncasecmp (n.data (), entry->canonical, n.length ());
277 if (cmp != 0 || completing)
279 return n.length () < strlen (entry->canonical);
282 return range (lower, upper);
285 cooked_index_vector::cooked_index_vector (vec_type &&vec)
286 : m_vector (std::move (vec))
288 for (auto &idx : m_vector)
292 /* See cooked-index.h. */
295 cooked_index_vector::lookup (CORE_ADDR addr)
297 for (const auto &index : m_vector)
299 dwarf2_per_cu_data *result = index->lookup (addr);
300 if (result != nullptr)
306 /* See cooked-index.h. */
308 std::vector<addrmap *>
309 cooked_index_vector::get_addrmaps ()
311 std::vector<addrmap *> result;
312 for (const auto &index : m_vector)
313 result.push_back (index->m_addrmap);
317 /* See cooked-index.h. */
319 cooked_index_vector::range
320 cooked_index_vector::find (gdb::string_view name, bool completing)
322 std::vector<cooked_index::range> result_range;
323 result_range.reserve (m_vector.size ());
324 for (auto &entry : m_vector)
325 result_range.push_back (entry->find (name, completing));
326 return range (std::move (result_range));
329 /* See cooked-index.h. */
331 const cooked_index_entry *
332 cooked_index_vector::get_main () const
334 const cooked_index_entry *result = nullptr;
336 for (const auto &index : m_vector)
338 const cooked_index_entry *entry = index->get_main ();
339 if (result == nullptr
340 || ((result->flags & IS_MAIN) == 0
342 && (entry->flags & IS_MAIN) != 0))