#include <set>
#include <forward_list>
-typedef struct symbol *symbolp;
-DEF_VEC_P (symbolp);
-
/* When == 1, print basic high level tracing messages.
When > 1, be more verbose.
This is in contrast to the low level DIE reading of dwarf_die_debug. */
explicit abbrev_table (sect_offset off)
: sect_off (off)
{
- abbrevs =
+ m_abbrevs =
XOBNEWVEC (&abbrev_obstack, struct abbrev_info *, ABBREV_HASH_SIZE);
- memset (abbrevs, 0, ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
+ memset (m_abbrevs, 0, ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
}
DISABLE_COPY_AND_ASSIGN (abbrev_table);
/* Storage for the abbrev table. */
auto_obstack abbrev_obstack;
+private:
+
/* Hash table of abbrevs.
This is an array of size ABBREV_HASH_SIZE allocated in abbrev_obstack.
It could be statically allocated, but the previous code didn't so we
don't either. */
- struct abbrev_info **abbrevs;
+ struct abbrev_info **m_abbrevs;
};
typedef std::unique_ptr<struct abbrev_table> abbrev_table_up;
static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
-static void dwarf2_release_queue (void *dummy);
-
static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
enum language pretend_language);
static void process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile);
+/* Class, the destructor of which frees all allocated queue entries. This
+ will only have work to do if an error was thrown while processing the
+ dwarf. If no error was thrown then the queue entries should have all
+ been processed, and freed, as we went along. */
+
+class dwarf2_queue_guard
+{
+public:
+ dwarf2_queue_guard () = default;
+
+ /* Free any entries remaining on the queue. There should only be
+ entries left if we hit an error while processing the dwarf. */
+ ~dwarf2_queue_guard ()
+ {
+ struct dwarf2_queue_item *item, *last;
+
+ item = dwarf2_queue;
+ while (item)
+ {
+ /* Anything still marked queued is likely to be in an
+ inconsistent state, so discard it. */
+ if (item->per_cu->queued)
+ {
+ if (item->per_cu->cu != NULL)
+ free_one_cached_comp_unit (item->per_cu);
+ item->per_cu->queued = 0;
+ }
+
+ last = item;
+ item = item->next;
+ xfree (last);
+ }
+
+ dwarf2_queue = dwarf2_queue_tail = NULL;
+ }
+};
+
/* The return type of find_file_and_directory. Note, the enclosed
string pointers are only valid while this object is valid. */
locate_sections (obfd, sec, *names);
}
+static void free_dwo_files (htab_t dwo_files, struct objfile *objfile);
+
dwarf2_per_objfile::~dwarf2_per_objfile ()
{
/* Cached DIE trees use xmalloc and the comp_unit_obstack. */
if (line_header_hash)
htab_delete (line_header_hash);
+ for (int ix = 0; ix < n_comp_units; ++ix)
+ VEC_free (dwarf2_per_cu_ptr, all_comp_units[ix]->imported_symtabs);
+
+ for (int ix = 0; ix < n_type_units; ++ix)
+ VEC_free (dwarf2_per_cu_ptr,
+ all_type_units[ix]->per_cu.imported_symtabs);
+ xfree (all_type_units);
+
+ VEC_free (dwarf2_section_info_def, types);
+
+ if (dwo_files != NULL)
+ free_dwo_files (dwo_files, objfile);
+ if (dwp_file != NULL)
+ gdb_bfd_unref (dwp_file->dbfd);
+
+ if (dwz_file != NULL && dwz_file->dwz_bfd)
+ gdb_bfd_unref (dwz_file->dwz_bfd);
+
+ if (index_table != NULL)
+ index_table->~mapped_index ();
+
/* Everything else should be on the objfile obstack. */
}
static void
dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
{
- struct cleanup *back_to;
struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
/* Skip type_unit_groups, reading the type units they contain
if (IS_TYPE_UNIT_GROUP (per_cu))
return;
- back_to = make_cleanup (dwarf2_release_queue, NULL);
+ /* The destructor of dwarf2_queue_guard frees any entries left on
+ the queue. After this point we're guaranteed to leave this function
+ with the dwarf queue empty. */
+ dwarf2_queue_guard q_guard;
if (dwarf2_per_objfile->using_index
? per_cu->v.quick->compunit_symtab == NULL
/* Age the cache, releasing compilation units that have not
been used recently. */
age_cached_comp_units (dwarf2_per_objfile);
-
- do_cleanups (back_to);
}
/* Ensure that the symbols for PER_CU have been read in. OBJFILE is
}
}
-/* Free all allocated queue entries. This function only releases anything if
- an error was thrown; if the queue was processed then it would have been
- freed as we went along. */
-
-static void
-dwarf2_release_queue (void *dummy)
-{
- struct dwarf2_queue_item *item, *last;
-
- item = dwarf2_queue;
- while (item)
- {
- /* Anything still marked queued is likely to be in an
- inconsistent state, so discard it. */
- if (item->per_cu->queued)
- {
- if (item->per_cu->cu != NULL)
- free_one_cached_comp_unit (item->per_cu);
- item->per_cu->queued = 0;
- }
-
- last = item;
- item = item->next;
- xfree (last);
- }
-
- dwarf2_queue = dwarf2_queue_tail = NULL;
-}
-
/* Read in full symbols for PST, and anything it depends on. */
static void
gdb::unique_xmalloc_ptr<char> demangled;
if (mangled != NULL)
{
- /* Use DMGL_RET_DROP for C++ template functions to suppress their return
- type. It is easier for GDB users to search for such functions as
- `name(params)' than `long name(params)'. In such case the minimal
- symbol names do not match the full symbol names but for template
- functions there is never a need to look up their definition from their
- declaration so the only disadvantage remains the minimal symbol
- variant `long name(params)' does not have the proper inferior type.
- */
if (cu->language == language_go)
{
}
else
{
+ /* Use DMGL_RET_DROP for C++ template functions to suppress
+ their return type. It is easier for GDB users to search
+ for such functions as `name(params)' than `long name(params)'.
+ In such case the minimal symbol names do not match the full
+ symbol names but for template functions there is never a need
+ to look up their definition from their declaration so
+ the only disadvantage remains the minimal symbol variant
+ `long name(params)' does not have the proper inferior type. */
demangled.reset (gdb_demangle (mangled,
(DMGL_PARAMS | DMGL_ANSI
| DMGL_RET_DROP)));
try_open_dwop_file (struct dwarf2_per_objfile *dwarf2_per_objfile,
const char *file_name, int is_dwp, int search_cwd)
{
- int desc, flags;
+ int desc;
char *absolute_name;
/* Blech. OPF_TRY_CWD_FIRST also disables searching the path list if
FILE_NAME contains a '/'. So we can't use it. Instead prepend "."
else
search_path = xstrdup (debug_file_directory);
- flags = OPF_RETURN_REALPATH;
+ openp_flags flags = OPF_RETURN_REALPATH;
if (is_dwp)
flags |= OPF_SEARCH_IN_PATH;
desc = openp (search_path, flags, file_name,
unsigned int hash_number;
hash_number = abbrev_number % ABBREV_HASH_SIZE;
- abbrev->next = abbrevs[hash_number];
- abbrevs[hash_number] = abbrev;
+ abbrev->next = m_abbrevs[hash_number];
+ m_abbrevs[hash_number] = abbrev;
}
/* Look up an abbrev in the table.
struct abbrev_info *abbrev;
hash_number = abbrev_number % ABBREV_HASH_SIZE;
- abbrev = abbrevs[hash_number];
+ abbrev = m_abbrevs[hash_number];
while (abbrev)
{
static int
need_gnat_info (struct dwarf2_cu *cu)
{
- /* FIXME: brobecker/2010-10-12: As of now, only the AdaCore version
- of GNAT produces this auxiliary information, without any indication
- that it is produced. Part of enhancing the FSF version of GNAT
- to produce that information will be to put in place an indicator
- that we can use in order to determine whether the descriptive type
- info is available or not. One suggestion that has been made is
- to use a new attribute, attached to the CU die. For now, assume
- that the descriptive type info is not available. */
- return 0;
+ /* Assume that the Ada compiler was GNAT, which always produces
+ the auxiliary information. */
+ return (cu->language == language_ada);
}
/* Return the auxiliary type of the die in question using its
if (attr_form_is_block (attr))
{
if (attr_to_dynamic_prop (attr, die, cu, &prop))
- add_dyn_prop (DYN_PROP_ALLOCATED, prop, type, objfile);
+ add_dyn_prop (DYN_PROP_ALLOCATED, prop, type);
}
else if (attr != NULL)
{
if (attr_form_is_block (attr))
{
if (attr_to_dynamic_prop (attr, die, cu, &prop))
- add_dyn_prop (DYN_PROP_ASSOCIATED, prop, type, objfile);
+ add_dyn_prop (DYN_PROP_ASSOCIATED, prop, type);
}
else if (attr != NULL)
{
/* Read DW_AT_data_location and set in type. */
attr = dwarf2_attr (die, DW_AT_data_location, cu);
if (attr_to_dynamic_prop (attr, die, cu, &prop))
- add_dyn_prop (DYN_PROP_DATA_LOCATION, prop, type, objfile);
+ add_dyn_prop (DYN_PROP_DATA_LOCATION, prop, type);
if (dwarf2_per_objfile->die_type_hash == NULL)
{
cmd_show_list (show_dwarf_cmdlist, from_tty, "");
}
-/* Free data associated with OBJFILE, if necessary. */
-
-static void
-dwarf2_per_objfile_free (struct objfile *objfile, void *d)
-{
- struct dwarf2_per_objfile *data = (struct dwarf2_per_objfile *) d;
- int ix;
-
- for (ix = 0; ix < data->n_comp_units; ++ix)
- VEC_free (dwarf2_per_cu_ptr, data->all_comp_units[ix]->imported_symtabs);
-
- for (ix = 0; ix < data->n_type_units; ++ix)
- VEC_free (dwarf2_per_cu_ptr,
- data->all_type_units[ix]->per_cu.imported_symtabs);
- xfree (data->all_type_units);
-
- VEC_free (dwarf2_section_info_def, data->types);
-
- if (data->dwo_files)
- free_dwo_files (data->dwo_files, objfile);
- if (data->dwp_file)
- gdb_bfd_unref (data->dwp_file->dbfd);
-
- if (data->dwz_file && data->dwz_file->dwz_bfd)
- gdb_bfd_unref (data->dwz_file->dwz_bfd);
-
- if (data->index_table != NULL)
- data->index_table->~mapped_index ();
-}
-
-\f
/* The "save gdb-index" command. */
/* Write SIZE bytes from the buffer pointed to by DATA to FILE, with
{
struct cmd_list_element *c;
- dwarf2_objfile_data_key
- = register_objfile_data_with_cleanup (NULL, dwarf2_per_objfile_free);
+ dwarf2_objfile_data_key = register_objfile_data ();
add_prefix_cmd ("dwarf", class_maintenance, set_dwarf_cmd, _("\
Set DWARF specific variables.\n\