static int dwarf2_locexpr_block_index;
static int dwarf2_loclist_block_index;
+/* Size of .debug_loclists section header for 32-bit DWARF format. */
+#define LOCLIST_HEADER_SIZE32 12
+
+/* Size of .debug_loclists section header for 64-bit DWARF format. */
+#define LOCLIST_HEADER_SIZE64 20
+
/* An index into a (C++) symbol name component in a symbol name as
recorded in the mapped_index's symbol table. For each C++ symbol
in the symbol table, we record one entry for the start of each
/* local data types */
+/* The location list section (.debug_loclists) begins with a header,
+ which contains the following information. */
+struct loclist_header
+{
+ /* A 4-byte or 12-byte length containing the length of the
+ set of entries for this compilation unit, not including the
+ length field itself. */
+ unsigned int length;
+
+ /* A 2-byte version identifier. */
+ short version;
+
+ /* A 1-byte unsigned integer containing the size in bytes of an address on
+ the target system. */
+ unsigned char addr_size;
+
+ /* A 1-byte unsigned integer containing the size in bytes of a segment selector
+ on the target system. */
+ unsigned char segment_collector_size;
+
+ /* A 4-byte count of the number of offsets that follow the header. */
+ unsigned int offset_entry_count;
+};
+
/* Type used for delaying computation of method physnames.
See comments for compute_delayed_physnames. */
struct delayed_method_info
whether the DW_AT_ranges attribute came from the skeleton or DWO. */
ULONGEST ranges_base = 0;
+ /* The DW_AT_loclists_base attribute if present. */
+ ULONGEST loclist_base = 0;
+
/* When reading debug info generated by older versions of rustc, we
have to rewrite some union types to be struct types with a
variant part. This rewriting must be done after the CU is fully
and friends. */
static int bits_per_byte = 8;
-/* When reading a variant or variant part, we track a bit more
- information about the field, and store it in an object of this
- type. */
+struct variant_part_builder;
+
+/* When reading a variant, we track a bit more information about the
+ field, and store it in an object of this type. */
struct variant_field
{
- /* If we see a DW_TAG_variant, then this will be the discriminant
- value. */
- ULONGEST discriminant_value;
+ int first_field = -1;
+ int last_field = -1;
+
+ /* A variant can contain other variant parts. */
+ std::vector<variant_part_builder> variant_parts;
+
/* If we see a DW_TAG_variant, then this will be set if this is the
default branch. */
- bool default_branch;
- /* While reading a DW_TAG_variant_part, this will be set if this
- field is the discriminant. */
- bool is_discriminant;
+ bool default_branch = false;
+ /* If we see a DW_AT_discr_value, then this will be the discriminant
+ value. */
+ ULONGEST discriminant_value = 0;
+ /* If we see a DW_AT_discr_list, then this is a pointer to the list
+ data. */
+ struct dwarf_block *discr_list_data = nullptr;
+};
+
+/* This represents a DW_TAG_variant_part. */
+
+struct variant_part_builder
+{
+ /* The offset of the discriminant field. */
+ sect_offset discriminant_offset {};
+
+ /* Variants that are direct children of this variant part. */
+ std::vector<variant_field> variants;
+
+ /* True if we're currently reading a variant. */
+ bool processing_variant = false;
};
struct nextfield
{
int accessibility = 0;
int virtuality = 0;
- /* Extra information to describe a variant or variant part. */
- struct variant_field variant {};
+ /* Variant parts need to find the discriminant, which is a DIE
+ reference. We track the section offset of each field to make
+ this link. */
+ sect_offset offset;
struct field field {};
};
list. */
std::vector<struct decl_field> nested_types_list;
+ /* If non-null, this is the variant part we are currently
+ reading. */
+ variant_part_builder *current_variant_part = nullptr;
+ /* This holds all the top-level variant parts attached to the type
+ we're reading. */
+ std::vector<variant_part_builder> variant_parts;
+
/* Return the total number of fields (including baseclasses). */
int nfields () const
{
static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
struct dwarf2_cu *, dwarf2_psymtab *);
+/* Return the .debug_loclists section to use for cu. */
+static struct dwarf2_section_info *cu_debug_loc_section (struct dwarf2_cu *cu);
+
/* How dwarf2_get_pc_bounds constructed its *LOWPC and *HIGHPC return
values. Keep the items ordered with increasing constraints compliance. */
enum pc_bounds_kind
static void process_enumeration_scope (struct die_info *, struct dwarf2_cu *);
-static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
+static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *,
+ bool * = nullptr);
static enum dwarf_array_dim_ordering read_array_order (struct die_info *,
struct dwarf2_cu *);
/* First try the file name given in the section. If that doesn't
work, try to use the build-id instead. */
- gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename, gnutarget, -1));
+ gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename, gnutarget));
if (dwz_bfd != NULL)
{
if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
if (fd.get () >= 0)
{
/* File successfully retrieved from server. */
- dwz_bfd = gdb_bfd_open (alt_filename.get (), gnutarget, -1);
+ dwz_bfd = gdb_bfd_open (alt_filename.get (), gnutarget);
if (dwz_bfd == nullptr)
warning (_("File \"%s\" from debuginfod cannot be opened as bfd"),
struct mapped_index *index)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
const gdb_byte *iter, *end;
struct addrmap *mutable_map;
CORE_ADDR baseaddr;
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
bfd *abfd = objfile->obfd;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
const CORE_ADDR baseaddr = objfile->text_section_offset ();
auto_obstack temp_obstack;
Returns true if all went well, false otherwise. */
static bool
-read_gdb_index_from_buffer (struct objfile *objfile,
- const char *filename,
+read_gdb_index_from_buffer (const char *filename,
bool deprecated_ok,
gdb::array_view<const gdb_byte> buffer,
struct mapped_index *map,
return 0;
std::unique_ptr<struct mapped_index> map (new struct mapped_index);
- if (!read_gdb_index_from_buffer (objfile, objfile_name (objfile),
+ if (!read_gdb_index_from_buffer (objfile_name (objfile),
use_deprecated_index_sections,
main_index_contents, map.get (), &cu_list,
&cu_list_elements, &types_list,
if (dwz_index_content.empty ())
return 0;
- if (!read_gdb_index_from_buffer (objfile,
- bfd_get_filename (dwz->dwz_bfd.get ()),
+ if (!read_gdb_index_from_buffer (bfd_get_filename (dwz->dwz_bfd.get ()),
1, dwz_index_content, &dwz_map,
&dwz_list, &dwz_list_elements,
&dwz_types_ignore,
}
}
+static void
+dw2_expand_symtabs_matching_symbol
+ (mapped_index_base &index,
+ const lookup_name_info &lookup_name_in,
+ gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
+ enum search_domain kind,
+ gdb::function_view<bool (offset_type)> match_callback);
+
+static void
+dw2_expand_symtabs_matching_one
+ (struct dwarf2_per_cu_data *per_cu,
+ gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+ gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify);
+
static void
dw2_map_matching_symbols
(struct objfile *objfile,
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
+ const block_enum block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
+
if (dwarf2_per_objfile->index_table != nullptr)
{
/* Ada currently doesn't support .gdb_index (see PR24713). We can get
here though if the current language is Ada for a non-Ada objfile
- using GNU index. As Ada does not look for non-Ada symbols this
- function should just return. */
- return;
- }
+ using GNU index. */
+ mapped_index &index = *dwarf2_per_objfile->index_table;
+
+ const char *match_name = name.ada ().lookup_name ().c_str ();
+ auto matcher = [&] (const char *symname)
+ {
+ if (ordered_compare == nullptr)
+ return true;
+ return ordered_compare (symname, match_name) == 0;
+ };
- /* We have -readnow: no .gdb_index, but no partial symtabs either. So,
- inline psym_map_matching_symbols here, assuming all partial symtabs have
- been read in. */
- const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
+ dw2_expand_symtabs_matching_symbol (index, name, matcher, ALL_DOMAIN,
+ [&] (offset_type namei)
+ {
+ struct dw2_symtab_iterator iter;
+ struct dwarf2_per_cu_data *per_cu;
+
+ dw2_symtab_iter_init (&iter, dwarf2_per_objfile, block_kind, domain,
+ match_name);
+ while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
+ dw2_expand_symtabs_matching_one (per_cu, nullptr, nullptr);
+ return true;
+ });
+ }
+ else
+ {
+ /* We have -readnow: no .gdb_index, but no partial symtabs either. So,
+ proceed assuming all symtabs have been read in. */
+ }
for (compunit_symtab *cust : objfile->compunits ())
{
struct name_and_matcher
{
symbol_name_matcher_ftype *matcher;
- const std::string &name;
+ const char *name;
bool operator== (const name_and_matcher &other) const
{
- return matcher == other.matcher && name == other.name;
+ return matcher == other.matcher && strcmp (name, other.name) == 0;
}
};
dw2_expand_symtabs_matching
(struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
- const lookup_name_info &lookup_name,
+ const lookup_name_info *lookup_name,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
enum search_domain kind)
dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
+ if (symbol_matcher == NULL && lookup_name == NULL)
+ {
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+ {
+ QUIT;
+
+ dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+ expansion_notify);
+ }
+ return;
+ }
+
mapped_index &index = *dwarf2_per_objfile->index_table;
- dw2_expand_symtabs_matching_symbol (index, lookup_name,
+ dw2_expand_symtabs_matching_symbol (index, *lookup_name,
symbol_matcher,
kind, [&] (offset_type idx)
{
if (warn_if_readin && data->v.quick->compunit_symtab)
warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
- paddress (get_objfile_arch (objfile), pc));
+ paddress (objfile->arch (), pc));
result
= recursively_find_pc_sect_compunit_symtab (dw2_instantiate_symtab (data,
section->read (objfile);
- map.dwarf5_byte_order = gdbarch_byte_order (get_objfile_arch (objfile));
+ map.dwarf5_byte_order = gdbarch_byte_order (objfile->arch ());
const gdb_byte *addr = section->buffer;
dwarf2_section_info §ion,
bool is_dwz)
{
+ if (!map.augmentation_is_gdb)
+ {
+ for (uint32_t i = 0; i < map.cu_count; ++i)
+ {
+ sect_offset sect_off
+ = (sect_offset) (extract_unsigned_integer
+ (map.cu_table_reordered + i * map.offset_size,
+ map.offset_size,
+ map.dwarf5_byte_order));
+ /* We don't know the length of the CU, because the CU list in a
+ .debug_names index can be incomplete, so we can't use the start of
+ the next CU as end of this CU. We create the CUs here with length 0,
+ and in cutu_reader::cutu_reader we'll fill in the actual length. */
+ dwarf2_per_cu_data *per_cu
+ = create_cu_from_index_list (dwarf2_per_objfile, §ion, is_dwz,
+ sect_off, 0);
+ dwarf2_per_objfile->all_comp_units.push_back (per_cu);
+ }
+ }
+
sect_offset sect_off_prev;
for (uint32_t i = 0; i <= map.cu_count; ++i)
{
ull = read_unsigned_leb128 (abfd, m_addr, &bytes_read);
m_addr += bytes_read;
break;
+ case DW_FORM_ref4:
+ ull = read_4_bytes (abfd, m_addr);
+ m_addr += 4;
+ break;
+ case DW_FORM_ref8:
+ ull = read_8_bytes (abfd, m_addr);
+ m_addr += 8;
+ break;
+ case DW_FORM_ref_sig8:
+ ull = read_8_bytes (abfd, m_addr);
+ m_addr += 8;
+ break;
default:
complaint (_("Unsupported .debug_names form %s [in module %s]"),
dwarf_form_name (attr.form),
}
per_cu = &dwarf2_per_objfile->get_tu (ull)->per_cu;
break;
+ case DW_IDX_die_offset:
+ /* In a per-CU index (as opposed to a per-module index), index
+ entries without CU attribute implicitly refer to the single CU. */
+ if (per_cu == NULL)
+ per_cu = dwarf2_per_objfile->get_cu (0);
+ break;
case DW_IDX_GNU_internal:
if (!m_map.augmentation_is_gdb)
break;
dw2_debug_names_expand_symtabs_matching
(struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
- const lookup_name_info &lookup_name,
+ const lookup_name_info *lookup_name,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
enum search_domain kind)
dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
+ if (symbol_matcher == NULL && lookup_name == NULL)
+ {
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+ {
+ QUIT;
+
+ dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+ expansion_notify);
+ }
+ return;
+ }
+
mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
- dw2_expand_symtabs_matching_symbol (map, lookup_name,
+ dw2_expand_symtabs_matching_symbol (map, *lookup_name,
symbol_matcher,
kind, [&] (offset_type namei)
{
void read_symtab (struct objfile *objfile) override
{
- expand_psymtab (objfile);
+ /* It's an include file, no symbols to read for it.
+ Everything is in the includer symtab. */
+
+ /* The expansion of a dwarf2_include_psymtab is just a trigger for
+ expansion of the includer psymtab. We use the dependencies[0] field to
+ model the includer. But if we go the regular route of calling
+ expand_psymtab here, and having expand_psymtab call expand_dependencies
+ to expand the includer, we'll only use expand_psymtab on the includer
+ (making it a non-toplevel psymtab), while if we expand the includer via
+ another path, we'll use read_symtab (making it a toplevel psymtab).
+ So, don't pretend a dwarf2_include_psymtab is an actual toplevel
+ psymtab, and trigger read_symtab on the includer here directly. */
+ includer ()->read_symtab (objfile);
}
void expand_psymtab (struct objfile *objfile) override
{
- if (m_readin)
- return;
- /* It's an include file, no symbols to read for it.
- Everything is in the parent symtab. */
- expand_dependencies (objfile);
- m_readin = true;
+ /* This is not called by read_symtab, and should not be called by any
+ expand_dependencies. */
+ gdb_assert (false);
}
bool readin_p () const override
{
- return m_readin;
+ return includer ()->readin_p ();
}
struct compunit_symtab *get_compunit_symtab () const override
}
private:
-
- bool m_readin = false;
+ partial_symtab *includer () const
+ {
+ /* An include psymtab has exactly one dependency: the psymtab that
+ includes it. */
+ gdb_assert (this->number_of_dependencies == 1);
+ return this->dependencies[0];
+ }
};
/* Allocate a new partial symtab for file named NAME and mark this new
rcuh_kind::COMPILE);
gdb_assert (this_cu->sect_off == cu->header.sect_off);
- gdb_assert (this_cu->length == cu->header.get_length ());
+ if (this_cu->length == 0)
+ this_cu->length = cu->header.get_length ();
+ else
+ gdb_assert (this_cu->length == cu->header.get_length ());
this_cu->dwarf_version = cu->header.version;
}
}
struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
dwarf2_psymtab *pst;
- pst = new dwarf2_psymtab (name, objfile, 0);
+ pst = new dwarf2_psymtab (name, objfile, per_cu);
pst->psymtabs_addrmap_supported = true;
/* This is the glue that links PST into GDB's symbol API. */
- pst->per_cu_data = per_cu;
per_cu->v.psymtab = pst;
return pst;
{
struct dwarf2_cu *cu = reader->cu;
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
struct dwarf2_per_cu_data *per_cu = cu->per_cu;
CORE_ADDR baseaddr;
CORE_ADDR best_lowpc = 0, best_highpc = 0;
addrmap_create_mutable (&temp_obstack));
for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
- process_psymtab_comp_unit (per_cu, false, language_minimal);
+ {
+ if (per_cu->v.psymtab != NULL)
+ /* In case a forward DW_TAG_imported_unit has read the CU already. */
+ continue;
+ process_psymtab_comp_unit (per_cu, false, language_minimal);
+ }
/* This has to wait until we read the CUs, we need the list of DWOs. */
process_skeletonless_type_units (dwarf2_per_objfile);
case DW_TAG_variable:
case DW_TAG_typedef:
case DW_TAG_union_type:
- if (!pdi->is_declaration)
+ if (!pdi->is_declaration
+ || (pdi->tag == DW_TAG_variable && pdi->is_external))
{
add_partial_symbol (pdi, cu);
}
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR addr = 0;
const char *actual_name = NULL;
CORE_ADDR baseaddr;
if (actual_name == NULL)
actual_name = pdi->name;
+ partial_symbol psymbol;
+ memset (&psymbol, 0, sizeof (psymbol));
+ psymbol.ginfo.set_language (cu->language, &objfile->objfile_obstack);
+ psymbol.ginfo.section = -1;
+
+ /* The code below indicates that the psymbol should be installed by
+ setting this. */
+ gdb::optional<psymbol_placement> where;
+
switch (pdi->tag)
{
case DW_TAG_inlined_subroutine:
But in Ada and Fortran, we want to be able to access nested
procedures globally. So all Ada and Fortran subprograms are
stored in the global scope. */
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_BLOCK,
- SECT_OFF_TEXT (objfile),
- psymbol_placement::GLOBAL,
- addr,
- cu->language, objfile);
+ where = psymbol_placement::GLOBAL;
}
else
- {
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_BLOCK,
- SECT_OFF_TEXT (objfile),
- psymbol_placement::STATIC,
- addr, cu->language, objfile);
- }
+ where = psymbol_placement::STATIC;
+
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_BLOCK;
+ psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+ psymbol.ginfo.value.address = addr;
if (pdi->main_subprogram && actual_name != NULL)
set_objfile_main_name (objfile, actual_name, cu->language);
break;
case DW_TAG_constant:
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC,
- -1, (pdi->is_external
- ? psymbol_placement::GLOBAL
- : psymbol_placement::STATIC),
- 0, cu->language, objfile);
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_STATIC;
+ where = (pdi->is_external
+ ? psymbol_placement::GLOBAL
+ : psymbol_placement::STATIC);
break;
case DW_TAG_variable:
if (pdi->d.locdesc)
table building. */
if (pdi->d.locdesc || pdi->has_type)
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_STATIC,
- SECT_OFF_TEXT (objfile),
- psymbol_placement::GLOBAL,
- addr, cu->language, objfile);
+ {
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_STATIC;
+ psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+ psymbol.ginfo.value.address = addr;
+ where = psymbol_placement::GLOBAL;
+ }
}
else
{
if (!has_loc && !pdi->has_const_value)
return;
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_STATIC,
- SECT_OFF_TEXT (objfile),
- psymbol_placement::STATIC,
- has_loc ? addr : 0,
- cu->language, objfile);
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_STATIC;
+ psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+ if (has_loc)
+ psymbol.ginfo.value.address = addr;
+ where = psymbol_placement::STATIC;
}
break;
case DW_TAG_typedef:
case DW_TAG_base_type:
case DW_TAG_subrange_type:
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::STATIC,
- 0, cu->language, objfile);
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_TYPEDEF;
+ where = psymbol_placement::STATIC;
break;
case DW_TAG_imported_declaration:
case DW_TAG_namespace:
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::GLOBAL,
- 0, cu->language, objfile);
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_TYPEDEF;
+ where = psymbol_placement::GLOBAL;
break;
case DW_TAG_module:
/* With Fortran 77 there might be a "BLOCK DATA" module
available without any name. If so, we skip the module as it
doesn't bring any value. */
if (actual_name != nullptr)
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- MODULE_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::GLOBAL,
- 0, cu->language, objfile);
+ {
+ psymbol.domain = MODULE_DOMAIN;
+ psymbol.aclass = LOC_TYPEDEF;
+ where = psymbol_placement::GLOBAL;
+ }
break;
case DW_TAG_class_type:
case DW_TAG_interface_type:
/* NOTE: carlton/2003-10-07: See comment in new_symbol about
static vs. global. */
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- STRUCT_DOMAIN, LOC_TYPEDEF, -1,
- cu->language == language_cplus
- ? psymbol_placement::GLOBAL
- : psymbol_placement::STATIC,
- 0, cu->language, objfile);
-
+ psymbol.domain = STRUCT_DOMAIN;
+ psymbol.aclass = LOC_TYPEDEF;
+ where = (cu->language == language_cplus
+ ? psymbol_placement::GLOBAL
+ : psymbol_placement::STATIC);
break;
case DW_TAG_enumerator:
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_CONST, -1,
- cu->language == language_cplus
- ? psymbol_placement::GLOBAL
- : psymbol_placement::STATIC,
- 0, cu->language, objfile);
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_CONST;
+ where = (cu->language == language_cplus
+ ? psymbol_placement::GLOBAL
+ : psymbol_placement::STATIC);
break;
default:
break;
}
+
+ if (where.has_value ())
+ {
+ if (built_actual_name != nullptr)
+ actual_name = objfile->intern (actual_name);
+ if (pdi->linkage_name == nullptr || cu->language == language_ada)
+ psymbol.ginfo.set_linkage_name (actual_name);
+ else
+ {
+ psymbol.ginfo.set_demangled_name (actual_name,
+ &objfile->objfile_obstack);
+ psymbol.ginfo.set_linkage_name (pdi->linkage_name);
+ }
+ add_psymbol_to_list (psymbol, *where, objfile);
+ }
}
/* Read a partial die corresponding to a namespace; also, add a symbol
if (set_addrmap)
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR baseaddr;
CORE_ADDR this_highpc;
CORE_ADDR this_lowpc;
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
case DW_FORM_rnglistx:
+ case DW_FORM_loclistx:
info_ptr = safe_skip_leb128 (info_ptr, buffer_end);
break;
case DW_FORM_indirect:
void
dwarf2_psymtab::expand_psymtab (struct objfile *objfile)
{
- if (readin)
- return;
+ gdb_assert (!readin);
expand_dependencies (objfile);
saved_package_name);
struct symbol *sym;
- sym = allocate_symbol (objfile);
+ sym = new (&objfile->objfile_obstack) symbol;
sym->set_language (language_go, &objfile->objfile_obstack);
sym->compute_and_set_names (saved_package_name, false, objfile->per_bfd);
/* This is not VAR_DOMAIN because we want a way to ensure a lookup of,
return obconcat (obstack, p1, "::", p2, (char *) NULL);
}
-/* A helper that allocates a struct discriminant_info to attach to a
- union type. */
+/* A helper that allocates a variant part to attach to a Rust enum
+ type. OBSTACK is where the results should be allocated. TYPE is
+ the type we're processing. DISCRIMINANT_INDEX is the index of the
+ discriminant. It must be the index of one of the fields of TYPE.
+ DEFAULT_INDEX is the index of the default field; or -1 if there is
+ no default. RANGES is indexed by "effective" field number (the
+ field index, but omitting the discriminant and default fields) and
+ must hold the discriminant values used by the variants. Note that
+ RANGES must have a lifetime at least as long as OBSTACK -- either
+ already allocated on it, or static. */
-static struct discriminant_info *
-alloc_discriminant_info (struct type *type, int discriminant_index,
- int default_index)
-{
- gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
- gdb_assert (discriminant_index == -1
- || (discriminant_index >= 0
- && discriminant_index < TYPE_NFIELDS (type)));
+static void
+alloc_rust_variant (struct obstack *obstack, struct type *type,
+ int discriminant_index, int default_index,
+ gdb::array_view<discriminant_range> ranges)
+{
+ /* When DISCRIMINANT_INDEX == -1, we have a univariant enum. Those
+ must be handled by the caller. */
+ gdb_assert (discriminant_index >= 0
+ && discriminant_index < type->num_fields ());
gdb_assert (default_index == -1
- || (default_index >= 0 && default_index < TYPE_NFIELDS (type)));
+ || (default_index >= 0 && default_index < type->num_fields ()));
- TYPE_FLAG_DISCRIMINATED_UNION (type) = 1;
+ /* We have one variant for each non-discriminant field. */
+ int n_variants = type->num_fields () - 1;
- struct discriminant_info *disc
- = ((struct discriminant_info *)
- TYPE_ZALLOC (type,
- offsetof (struct discriminant_info, discriminants)
- + TYPE_NFIELDS (type) * sizeof (disc->discriminants[0])));
- disc->default_index = default_index;
- disc->discriminant_index = discriminant_index;
+ variant *variants = new (obstack) variant[n_variants];
+ int var_idx = 0;
+ int range_idx = 0;
+ for (int i = 0; i < type->num_fields (); ++i)
+ {
+ if (i == discriminant_index)
+ continue;
- struct dynamic_prop prop;
- prop.kind = PROP_UNDEFINED;
- prop.data.baton = disc;
+ variants[var_idx].first_field = i;
+ variants[var_idx].last_field = i + 1;
+
+ /* The default field does not need a range, but other fields do.
+ We skipped the discriminant above. */
+ if (i != default_index)
+ {
+ variants[var_idx].discriminants = ranges.slice (range_idx, 1);
+ ++range_idx;
+ }
+
+ ++var_idx;
+ }
+
+ gdb_assert (range_idx == ranges.size ());
+ gdb_assert (var_idx == n_variants);
- add_dyn_prop (DYN_PROP_DISCRIMINATED, prop, type);
+ variant_part *part = new (obstack) variant_part;
+ part->discriminant_index = discriminant_index;
+ part->is_unsigned = TYPE_UNSIGNED (TYPE_FIELD_TYPE (type,
+ discriminant_index));
+ part->variants = gdb::array_view<variant> (variants, n_variants);
- return disc;
+ void *storage = obstack_alloc (obstack, sizeof (gdb::array_view<variant_part>));
+ gdb::array_view<variant_part> *prop_value
+ = new (storage) gdb::array_view<variant_part> (part, 1);
+
+ struct dynamic_prop prop;
+ prop.kind = PROP_VARIANT_PARTS;
+ prop.data.variant_parts = prop_value;
+
+ type->add_dyn_prop (DYN_PROP_VARIANT_PARTS, prop);
}
/* Some versions of rustc emitted enums in an unusual way.
static void
quirk_rust_enum (struct type *type, struct objfile *objfile)
{
- gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
+ gdb_assert (type->code () == TYPE_CODE_UNION);
/* We don't need to deal with empty enums. */
- if (TYPE_NFIELDS (type) == 0)
+ if (type->num_fields () == 0)
return;
#define RUST_ENUM_PREFIX "RUST$ENCODED$ENUM$"
- if (TYPE_NFIELDS (type) == 1
+ if (type->num_fields () == 1
&& startswith (TYPE_FIELD_NAME (type, 0), RUST_ENUM_PREFIX))
{
const char *name = TYPE_FIELD_NAME (type, 0) + strlen (RUST_ENUM_PREFIX);
unsigned long index = strtoul (name, &tail, 10);
name = tail;
if (*name != '$'
- || index >= TYPE_NFIELDS (field_type)
+ || index >= field_type->num_fields ()
|| (TYPE_FIELD_LOC_KIND (field_type, index)
!= FIELD_LOC_KIND_BITPOS))
{
field_type = TYPE_FIELD_TYPE (field_type, index);
}
- /* Make a union to hold the variants. */
- struct type *union_type = alloc_type (objfile);
- TYPE_CODE (union_type) = TYPE_CODE_UNION;
- TYPE_NFIELDS (union_type) = 3;
- TYPE_FIELDS (union_type)
- = (struct field *) TYPE_ZALLOC (type, 3 * sizeof (struct field));
- TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
- set_type_align (union_type, TYPE_RAW_ALIGN (type));
-
- /* Put the discriminant must at index 0. */
- TYPE_FIELD_TYPE (union_type, 0) = field_type;
- TYPE_FIELD_ARTIFICIAL (union_type, 0) = 1;
- TYPE_FIELD_NAME (union_type, 0) = "<<discriminant>>";
- SET_FIELD_BITPOS (TYPE_FIELD (union_type, 0), bit_offset);
+ /* Smash this type to be a structure type. We have to do this
+ because the type has already been recorded. */
+ type->set_code (TYPE_CODE_STRUCT);
+ type->set_num_fields (3);
+ /* Save the field we care about. */
+ struct field saved_field = type->field (0);
+ type->set_fields
+ ((struct field *) TYPE_ZALLOC (type, 3 * sizeof (struct field)));
+
+ /* Put the discriminant at index 0. */
+ TYPE_FIELD_TYPE (type, 0) = field_type;
+ TYPE_FIELD_ARTIFICIAL (type, 0) = 1;
+ TYPE_FIELD_NAME (type, 0) = "<<discriminant>>";
+ SET_FIELD_BITPOS (type->field (0), bit_offset);
/* The order of fields doesn't really matter, so put the real
field at index 1 and the data-less field at index 2. */
- struct discriminant_info *disc
- = alloc_discriminant_info (union_type, 0, 1);
- TYPE_FIELD (union_type, 1) = TYPE_FIELD (type, 0);
- TYPE_FIELD_NAME (union_type, 1)
- = rust_last_path_segment (TYPE_NAME (TYPE_FIELD_TYPE (union_type, 1)));
- TYPE_NAME (TYPE_FIELD_TYPE (union_type, 1))
- = rust_fully_qualify (&objfile->objfile_obstack, TYPE_NAME (type),
- TYPE_FIELD_NAME (union_type, 1));
+ type->field (1) = saved_field;
+ TYPE_FIELD_NAME (type, 1)
+ = rust_last_path_segment (TYPE_FIELD_TYPE (type, 1)->name ());
+ TYPE_FIELD_TYPE (type, 1)->set_name
+ (rust_fully_qualify (&objfile->objfile_obstack, type->name (),
+ TYPE_FIELD_NAME (type, 1)));
const char *dataless_name
- = rust_fully_qualify (&objfile->objfile_obstack, TYPE_NAME (type),
+ = rust_fully_qualify (&objfile->objfile_obstack, type->name (),
name);
struct type *dataless_type = init_type (objfile, TYPE_CODE_VOID, 0,
dataless_name);
- TYPE_FIELD_TYPE (union_type, 2) = dataless_type;
+ TYPE_FIELD_TYPE (type, 2) = dataless_type;
/* NAME points into the original discriminant name, which
already has the correct lifetime. */
- TYPE_FIELD_NAME (union_type, 2) = name;
- SET_FIELD_BITPOS (TYPE_FIELD (union_type, 2), 0);
- disc->discriminants[2] = 0;
+ TYPE_FIELD_NAME (type, 2) = name;
+ SET_FIELD_BITPOS (type->field (2), 0);
- /* Smash this type to be a structure type. We have to do this
- because the type has already been recorded. */
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
- TYPE_NFIELDS (type) = 1;
- TYPE_FIELDS (type)
- = (struct field *) TYPE_ZALLOC (type, sizeof (struct field));
-
- /* Install the variant part. */
- TYPE_FIELD_TYPE (type, 0) = union_type;
- SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
- TYPE_FIELD_NAME (type, 0) = "<<variants>>";
+ /* Indicate that this is a variant type. */
+ static discriminant_range ranges[1] = { { 0, 0 } };
+ alloc_rust_variant (&objfile->objfile_obstack, type, 0, 1, ranges);
}
/* A union with a single anonymous field is probably an old-style
univariant enum. */
- else if (TYPE_NFIELDS (type) == 1 && streq (TYPE_FIELD_NAME (type, 0), ""))
+ else if (type->num_fields () == 1 && streq (TYPE_FIELD_NAME (type, 0), ""))
{
/* Smash this type to be a structure type. We have to do this
because the type has already been recorded. */
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ type->set_code (TYPE_CODE_STRUCT);
- /* Make a union to hold the variants. */
- struct type *union_type = alloc_type (objfile);
- TYPE_CODE (union_type) = TYPE_CODE_UNION;
- TYPE_NFIELDS (union_type) = TYPE_NFIELDS (type);
- TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
- set_type_align (union_type, TYPE_RAW_ALIGN (type));
- TYPE_FIELDS (union_type) = TYPE_FIELDS (type);
-
- struct type *field_type = TYPE_FIELD_TYPE (union_type, 0);
+ struct type *field_type = TYPE_FIELD_TYPE (type, 0);
const char *variant_name
- = rust_last_path_segment (TYPE_NAME (field_type));
- TYPE_FIELD_NAME (union_type, 0) = variant_name;
- TYPE_NAME (field_type)
- = rust_fully_qualify (&objfile->objfile_obstack,
- TYPE_NAME (type), variant_name);
-
- /* Install the union in the outer struct type. */
- TYPE_NFIELDS (type) = 1;
- TYPE_FIELDS (type)
- = (struct field *) TYPE_ZALLOC (union_type, sizeof (struct field));
- TYPE_FIELD_TYPE (type, 0) = union_type;
- TYPE_FIELD_NAME (type, 0) = "<<variants>>";
- SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
-
- alloc_discriminant_info (union_type, -1, 0);
+ = rust_last_path_segment (field_type->name ());
+ TYPE_FIELD_NAME (type, 0) = variant_name;
+ field_type->set_name
+ (rust_fully_qualify (&objfile->objfile_obstack,
+ type->name (), variant_name));
}
else
{
struct type *disr_type = nullptr;
- for (int i = 0; i < TYPE_NFIELDS (type); ++i)
+ for (int i = 0; i < type->num_fields (); ++i)
{
disr_type = TYPE_FIELD_TYPE (type, i);
- if (TYPE_CODE (disr_type) != TYPE_CODE_STRUCT)
+ if (disr_type->code () != TYPE_CODE_STRUCT)
{
/* All fields of a true enum will be structs. */
return;
}
- else if (TYPE_NFIELDS (disr_type) == 0)
+ else if (disr_type->num_fields () == 0)
{
/* Could be data-less variant, so keep going. */
disr_type = nullptr;
/* Smash this type to be a structure type. We have to do this
because the type has already been recorded. */
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
-
- /* Make a union to hold the variants. */
- struct field *disr_field = &TYPE_FIELD (disr_type, 0);
- struct type *union_type = alloc_type (objfile);
- TYPE_CODE (union_type) = TYPE_CODE_UNION;
- TYPE_NFIELDS (union_type) = 1 + TYPE_NFIELDS (type);
- TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
- set_type_align (union_type, TYPE_RAW_ALIGN (type));
- TYPE_FIELDS (union_type)
- = (struct field *) TYPE_ZALLOC (union_type,
- (TYPE_NFIELDS (union_type)
- * sizeof (struct field)));
-
- memcpy (TYPE_FIELDS (union_type) + 1, TYPE_FIELDS (type),
- TYPE_NFIELDS (type) * sizeof (struct field));
+ type->set_code (TYPE_CODE_STRUCT);
+
+ /* Make space for the discriminant field. */
+ struct field *disr_field = &disr_type->field (0);
+ field *new_fields
+ = (struct field *) TYPE_ZALLOC (type, ((type->num_fields () + 1)
+ * sizeof (struct field)));
+ memcpy (new_fields + 1, type->fields (),
+ type->num_fields () * sizeof (struct field));
+ type->set_fields (new_fields);
+ type->set_num_fields (type->num_fields () + 1);
/* Install the discriminant at index 0 in the union. */
- TYPE_FIELD (union_type, 0) = *disr_field;
- TYPE_FIELD_ARTIFICIAL (union_type, 0) = 1;
- TYPE_FIELD_NAME (union_type, 0) = "<<discriminant>>";
-
- /* Install the union in the outer struct type. */
- TYPE_FIELD_TYPE (type, 0) = union_type;
- TYPE_FIELD_NAME (type, 0) = "<<variants>>";
- TYPE_NFIELDS (type) = 1;
-
- /* Set the size and offset of the union type. */
- SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
+ type->field (0) = *disr_field;
+ TYPE_FIELD_ARTIFICIAL (type, 0) = 1;
+ TYPE_FIELD_NAME (type, 0) = "<<discriminant>>";
/* We need a way to find the correct discriminant given a
variant name. For convenience we build a map here. */
struct type *enum_type = FIELD_TYPE (*disr_field);
std::unordered_map<std::string, ULONGEST> discriminant_map;
- for (int i = 0; i < TYPE_NFIELDS (enum_type); ++i)
+ for (int i = 0; i < enum_type->num_fields (); ++i)
{
if (TYPE_FIELD_LOC_KIND (enum_type, i) == FIELD_LOC_KIND_ENUMVAL)
{
}
}
- int n_fields = TYPE_NFIELDS (union_type);
- struct discriminant_info *disc
- = alloc_discriminant_info (union_type, 0, -1);
+ int n_fields = type->num_fields ();
+ /* We don't need a range entry for the discriminant, but we do
+ need one for every other field, as there is no default
+ variant. */
+ discriminant_range *ranges = XOBNEWVEC (&objfile->objfile_obstack,
+ discriminant_range,
+ n_fields - 1);
/* Skip the discriminant here. */
for (int i = 1; i < n_fields; ++i)
{
That name can be used to look up the correct
discriminant. */
const char *variant_name
- = rust_last_path_segment (TYPE_NAME (TYPE_FIELD_TYPE (union_type,
- i)));
+ = rust_last_path_segment (TYPE_FIELD_TYPE (type, i)->name ());
auto iter = discriminant_map.find (variant_name);
if (iter != discriminant_map.end ())
- disc->discriminants[i] = iter->second;
+ {
+ ranges[i].low = iter->second;
+ ranges[i].high = iter->second;
+ }
/* Remove the discriminant field, if it exists. */
- struct type *sub_type = TYPE_FIELD_TYPE (union_type, i);
- if (TYPE_NFIELDS (sub_type) > 0)
+ struct type *sub_type = TYPE_FIELD_TYPE (type, i);
+ if (sub_type->num_fields () > 0)
{
- --TYPE_NFIELDS (sub_type);
- ++TYPE_FIELDS (sub_type);
+ sub_type->set_num_fields (sub_type->num_fields () - 1);
+ sub_type->set_fields (sub_type->fields () + 1);
}
- TYPE_FIELD_NAME (union_type, i) = variant_name;
- TYPE_NAME (sub_type)
- = rust_fully_qualify (&objfile->objfile_obstack,
- TYPE_NAME (type), variant_name);
+ TYPE_FIELD_NAME (type, i) = variant_name;
+ sub_type->set_name
+ (rust_fully_qualify (&objfile->objfile_obstack,
+ type->name (), variant_name));
}
+
+ /* Indicate that this is a variant type. */
+ alloc_rust_variant (&objfile->objfile_obstack, type, 0, 1,
+ gdb::array_view<discriminant_range> (ranges,
+ n_fields - 1));
}
}
struct dwarf2_cu *cu = per_cu->cu;
struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR lowpc, highpc;
struct compunit_symtab *cust;
CORE_ADDR baseaddr;
if (linkage_name == NULL)
linkage_name = dwarf2_string_attr (die, DW_AT_MIPS_linkage_name, cu);
+ /* rustc emits invalid values for DW_AT_linkage_name. Ignore these.
+ See https://github.com/rust-lang/rust/issues/32925. */
+ if (cu->language == language_rust && linkage_name != NULL
+ && strchr (linkage_name, '{') != NULL)
+ linkage_name = NULL;
+
return linkage_name;
}
marks unnamed (and thus unused) parameters as
artificial; there is no way to differentiate
the two cases. */
- if (TYPE_NFIELDS (type) > 0
+ if (type->num_fields () > 0
&& TYPE_FIELD_ARTIFICIAL (type, 0)
- && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_PTR
+ && TYPE_FIELD_TYPE (type, 0)->code () == TYPE_CODE_PTR
&& TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type,
0))))
buf.puts (" const");
if (!die_needs_namespace (die, cu))
return dwarf2_compute_name (name, die, cu, 1);
- mangled = dw2_linkage_name (die, cu);
-
- /* rustc emits invalid values for DW_AT_linkage_name. Ignore these.
- See https://github.com/rust-lang/rust/issues/32925. */
- if (cu->language == language_rust && mangled != NULL
- && strchr (mangled, '{') != NULL)
- mangled = NULL;
+ if (cu->language != language_rust)
+ mangled = dw2_linkage_name (die, cu);
/* DW_AT_linkage_name is missing in some cases - depend on what GDB
has computed. */
sect_offset sect_off = attr->get_ref_die_offset ();
type = get_die_type_at_offset (sect_off, cu->per_cu);
- if (type != NULL && TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
+ if (type != NULL && type->code () == TYPE_CODE_NAMESPACE)
{
/* This declaration is a global namespace alias. Add
a symbol for it whose type is the aliased namespace. */
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR lowpc = ((CORE_ADDR) -1);
CORE_ADDR highpc = ((CORE_ADDR) 0);
struct attribute *attr;
COMPUNIT_DIRNAME (cust),
compunit_language (cust),
0, cust));
+ list_in_scope = get_builder ()->get_file_symbols ();
}
return;
}
COMPUNIT_DIRNAME (cust),
compunit_language (cust),
0, cust));
+ list_in_scope = get_builder ()->get_file_symbols ();
auto &file_names = line_header->file_names ();
for (i = 0; i < file_names.size (); ++i)
dwo_sections->loc.s.section = sectp;
dwo_sections->loc.size = bfd_section_size (sectp);
}
+ else if (section_is_p (sectp->name, &names->loclists_dwo))
+ {
+ dwo_sections->loclists.s.section = sectp;
+ dwo_sections->loclists.size = bfd_section_size (sectp);
+ }
else if (section_is_p (sectp->name, &names->macinfo_dwo))
{
dwo_sections->macinfo.s.section = sectp;
read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
struct context_stack *newobj;
CORE_ADDR lowpc;
CORE_ADDR highpc;
if (child_die->tag == DW_TAG_template_type_param
|| child_die->tag == DW_TAG_template_value_param)
{
- templ_func = allocate_template_symbol (objfile);
+ templ_func = new (&objfile->objfile_obstack) template_symbol;
templ_func->subclass = SYMBOL_TEMPLATE;
break;
}
read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR lowpc, highpc;
struct die_info *child_die;
CORE_ADDR baseaddr;
for (child_die = die->child;
child_die != NULL && child_die->tag;
child_die = child_die->sibling)
- process_die (child_die, cu);
+ {
+ /* We might already be processing this DIE. This can happen
+ in an unusual circumstance -- where a subroutine A
+ appears lexically in another subroutine B, but A actually
+ inlines B. The recursion is broken here, rather than in
+ inherit_abstract_dies, because it seems better to simply
+ drop concrete children here. */
+ if (!child_die->in_process)
+ process_die (child_die, cu);
+ }
return;
case PC_BOUNDS_INVALID:
return;
read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR pc, baseaddr;
struct attribute *attr;
struct call_site *call_site, call_site_local;
func_type = get_die_type (func_die, cu);
if (func_type != NULL)
{
- gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC);
+ gdb_assert (func_type->code () == TYPE_CODE_FUNC);
/* Enlist this call site to the function. */
call_site->tail_call_next = TYPE_TAIL_CALL_LIST (func_type);
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- storage = new (&objfile->objfile_obstack) rust_vtable_symbol ();
- initialize_objfile_symbol (storage);
+ storage = new (&objfile->objfile_obstack) rust_vtable_symbol;
storage->concrete_type = containing_type;
storage->subclass = SYMBOL_RUST_VTABLE;
}
dwarf2_psymtab *ranges_pst)
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
const CORE_ADDR baseaddr = objfile->text_section_offset ();
int low_set = 0;
CORE_ADDR low = 0;
CORE_ADDR baseaddr, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
struct attribute *attr;
struct attribute *attr_high;
return 0;
}
+/* Look for DW_AT_data_member_location and store the results in FIELD. */
+
+static void
+handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
+ struct field *field)
+{
+ struct attribute *attr;
+
+ attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
+ if (attr != NULL)
+ {
+ if (attr->form_is_constant ())
+ {
+ LONGEST offset = attr->constant_value (0);
+ SET_FIELD_BITPOS (*field, offset * bits_per_byte);
+ }
+ else if (attr->form_is_section_offset ())
+ dwarf2_complex_location_expr_complaint ();
+ else if (attr->form_is_block ())
+ {
+ bool handled;
+ CORE_ADDR offset = decode_locdesc (DW_BLOCK (attr), cu, &handled);
+ if (handled)
+ SET_FIELD_BITPOS (*field, offset * bits_per_byte);
+ else
+ {
+ struct objfile *objfile
+ = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct dwarf2_locexpr_baton *dlbaton
+ = XOBNEW (&objfile->objfile_obstack,
+ struct dwarf2_locexpr_baton);
+ dlbaton->data = DW_BLOCK (attr)->data;
+ dlbaton->size = DW_BLOCK (attr)->size;
+ /* When using this baton, we want to compute the address
+ of the field, not the value. This is why
+ is_reference is set to false here. */
+ dlbaton->is_reference = false;
+ dlbaton->per_cu = cu->per_cu;
+
+ SET_FIELD_DWARF_BLOCK (*field, dlbaton);
+ }
+ }
+ else
+ dwarf2_complex_location_expr_complaint ();
+ }
+}
+
/* Add an aggregate field to the field list. */
static void
struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
struct nextfield *new_field;
struct attribute *attr;
struct field *fp;
new_field = &fip->fields.back ();
}
+ new_field->offset = die->sect_off;
+
attr = dwarf2_attr (die, DW_AT_accessibility, cu);
if (attr != nullptr)
new_field->accessibility = DW_UNSND (attr);
if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
{
- LONGEST offset;
-
/* Data member other than a C++ static data member. */
/* Get type of field. */
}
/* Get bit offset of field. */
- if (handle_data_member_location (die, cu, &offset))
- SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
+ handle_data_member_location (die, cu, fp);
attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
if (attr != nullptr)
{
}
else if (die->tag == DW_TAG_inheritance)
{
- LONGEST offset;
-
/* C++ base class field. */
- if (handle_data_member_location (die, cu, &offset))
- SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
+ handle_data_member_location (die, cu, fp);
FIELD_BITSIZE (*fp) = 0;
FIELD_TYPE (*fp) = die_type (die, cu);
- FIELD_NAME (*fp) = TYPE_NAME (fp->type);
- }
- else if (die->tag == DW_TAG_variant_part)
- {
- /* process_structure_scope will treat this DIE as a union. */
- process_structure_scope (die, cu);
-
- /* The variant part is relative to the start of the enclosing
- structure. */
- SET_FIELD_BITPOS (*fp, 0);
- fp->type = get_die_type (die, cu);
- fp->artificial = 1;
- fp->name = "<<variant>>";
-
- /* Normally a DW_TAG_variant_part won't have a size, but our
- representation requires one, so set it to the maximum of the
- child sizes, being sure to account for the offset at which
- each child is seen. */
- if (TYPE_LENGTH (fp->type) == 0)
- {
- unsigned max = 0;
- for (int i = 0; i < TYPE_NFIELDS (fp->type); ++i)
- {
- unsigned len = ((TYPE_FIELD_BITPOS (fp->type, i) + 7) / 8
- + TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i)));
- if (len > max)
- max = len;
- }
- TYPE_LENGTH (fp->type) = max;
- }
+ FIELD_NAME (*fp) = fp->type->name ();
}
else
gdb_assert_not_reached ("missing case in dwarf2_add_field");
fip->nested_types_list.push_back (fp);
}
+/* A convenience typedef that's used when finding the discriminant
+ field for a variant part. */
+typedef std::unordered_map<sect_offset, int, gdb::hash_enum<sect_offset>>
+ offset_map_type;
+
+/* Compute the discriminant range for a given variant. OBSTACK is
+ where the results will be stored. VARIANT is the variant to
+ process. IS_UNSIGNED indicates whether the discriminant is signed
+ or unsigned. */
+
+static const gdb::array_view<discriminant_range>
+convert_variant_range (struct obstack *obstack, const variant_field &variant,
+ bool is_unsigned)
+{
+ std::vector<discriminant_range> ranges;
+
+ if (variant.default_branch)
+ return {};
+
+ if (variant.discr_list_data == nullptr)
+ {
+ discriminant_range r
+ = {variant.discriminant_value, variant.discriminant_value};
+ ranges.push_back (r);
+ }
+ else
+ {
+ gdb::array_view<const gdb_byte> data (variant.discr_list_data->data,
+ variant.discr_list_data->size);
+ while (!data.empty ())
+ {
+ if (data[0] != DW_DSC_range && data[0] != DW_DSC_label)
+ {
+ complaint (_("invalid discriminant marker: %d"), data[0]);
+ break;
+ }
+ bool is_range = data[0] == DW_DSC_range;
+ data = data.slice (1);
+
+ ULONGEST low, high;
+ unsigned int bytes_read;
+
+ if (data.empty ())
+ {
+ complaint (_("DW_AT_discr_list missing low value"));
+ break;
+ }
+ if (is_unsigned)
+ low = read_unsigned_leb128 (nullptr, data.data (), &bytes_read);
+ else
+ low = (ULONGEST) read_signed_leb128 (nullptr, data.data (),
+ &bytes_read);
+ data = data.slice (bytes_read);
+
+ if (is_range)
+ {
+ if (data.empty ())
+ {
+ complaint (_("DW_AT_discr_list missing high value"));
+ break;
+ }
+ if (is_unsigned)
+ high = read_unsigned_leb128 (nullptr, data.data (),
+ &bytes_read);
+ else
+ high = (LONGEST) read_signed_leb128 (nullptr, data.data (),
+ &bytes_read);
+ data = data.slice (bytes_read);
+ }
+ else
+ high = low;
+
+ ranges.push_back ({ low, high });
+ }
+ }
+
+ discriminant_range *result = XOBNEWVEC (obstack, discriminant_range,
+ ranges.size ());
+ std::copy (ranges.begin (), ranges.end (), result);
+ return gdb::array_view<discriminant_range> (result, ranges.size ());
+}
+
+static const gdb::array_view<variant_part> create_variant_parts
+ (struct obstack *obstack,
+ const offset_map_type &offset_map,
+ struct field_info *fi,
+ const std::vector<variant_part_builder> &variant_parts);
+
+/* Fill in a "struct variant" for a given variant field. RESULT is
+ the variant to fill in. OBSTACK is where any needed allocations
+ will be done. OFFSET_MAP holds the mapping from section offsets to
+ fields for the type. FI describes the fields of the type we're
+ processing. FIELD is the variant field we're converting. */
+
+static void
+create_one_variant (variant &result, struct obstack *obstack,
+ const offset_map_type &offset_map,
+ struct field_info *fi, const variant_field &field)
+{
+ result.discriminants = convert_variant_range (obstack, field, false);
+ result.first_field = field.first_field + fi->baseclasses.size ();
+ result.last_field = field.last_field + fi->baseclasses.size ();
+ result.parts = create_variant_parts (obstack, offset_map, fi,
+ field.variant_parts);
+}
+
+/* Fill in a "struct variant_part" for a given variant part. RESULT
+ is the variant part to fill in. OBSTACK is where any needed
+ allocations will be done. OFFSET_MAP holds the mapping from
+ section offsets to fields for the type. FI describes the fields of
+ the type we're processing. BUILDER is the variant part to be
+ converted. */
+
+static void
+create_one_variant_part (variant_part &result,
+ struct obstack *obstack,
+ const offset_map_type &offset_map,
+ struct field_info *fi,
+ const variant_part_builder &builder)
+{
+ auto iter = offset_map.find (builder.discriminant_offset);
+ if (iter == offset_map.end ())
+ {
+ result.discriminant_index = -1;
+ /* Doesn't matter. */
+ result.is_unsigned = false;
+ }
+ else
+ {
+ result.discriminant_index = iter->second;
+ result.is_unsigned
+ = TYPE_UNSIGNED (FIELD_TYPE
+ (fi->fields[result.discriminant_index].field));
+ }
+
+ size_t n = builder.variants.size ();
+ variant *output = new (obstack) variant[n];
+ for (size_t i = 0; i < n; ++i)
+ create_one_variant (output[i], obstack, offset_map, fi,
+ builder.variants[i]);
+
+ result.variants = gdb::array_view<variant> (output, n);
+}
+
+/* Create a vector of variant parts that can be attached to a type.
+ OBSTACK is where any needed allocations will be done. OFFSET_MAP
+ holds the mapping from section offsets to fields for the type. FI
+ describes the fields of the type we're processing. VARIANT_PARTS
+ is the vector to convert. */
+
+static const gdb::array_view<variant_part>
+create_variant_parts (struct obstack *obstack,
+ const offset_map_type &offset_map,
+ struct field_info *fi,
+ const std::vector<variant_part_builder> &variant_parts)
+{
+ if (variant_parts.empty ())
+ return {};
+
+ size_t n = variant_parts.size ();
+ variant_part *result = new (obstack) variant_part[n];
+ for (size_t i = 0; i < n; ++i)
+ create_one_variant_part (result[i], obstack, offset_map, fi,
+ variant_parts[i]);
+
+ return gdb::array_view<variant_part> (result, n);
+}
+
+/* Compute the variant part vector for FIP, attaching it to TYPE when
+ done. */
+
+static void
+add_variant_property (struct field_info *fip, struct type *type,
+ struct dwarf2_cu *cu)
+{
+ /* Map section offsets of fields to their field index. Note the
+ field index here does not take the number of baseclasses into
+ account. */
+ offset_map_type offset_map;
+ for (int i = 0; i < fip->fields.size (); ++i)
+ offset_map[fip->fields[i].offset] = i;
+
+ struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ gdb::array_view<variant_part> parts
+ = create_variant_parts (&objfile->objfile_obstack, offset_map, fip,
+ fip->variant_parts);
+
+ struct dynamic_prop prop;
+ prop.kind = PROP_VARIANT_PARTS;
+ prop.data.variant_parts
+ = ((gdb::array_view<variant_part> *)
+ obstack_copy (&objfile->objfile_obstack, &parts, sizeof (parts)));
+
+ type->add_dyn_prop (DYN_PROP_VARIANT_PARTS, prop);
+}
+
/* Create the vector of fields, and attach it to the type. */
static void
/* Record the field count, allocate space for the array of fields,
and create blank accessibility bitfields if necessary. */
- TYPE_NFIELDS (type) = nfields;
- TYPE_FIELDS (type) = (struct field *)
- TYPE_ZALLOC (type, sizeof (struct field) * nfields);
+ type->set_num_fields (nfields);
+ type->set_fields
+ ((struct field *) TYPE_ZALLOC (type, sizeof (struct field) * nfields));
if (fip->non_public_fields && cu->language != language_ada)
{
TYPE_N_BASECLASSES (type) = fip->baseclasses.size ();
}
- if (TYPE_FLAG_DISCRIMINATED_UNION (type))
- {
- struct discriminant_info *di = alloc_discriminant_info (type, -1, -1);
-
- for (int index = 0; index < nfields; ++index)
- {
- struct nextfield &field = fip->fields[index];
-
- if (field.variant.is_discriminant)
- di->discriminant_index = index;
- else if (field.variant.default_branch)
- di->default_index = index;
- else
- di->discriminants[index] = field.variant.discriminant_value;
- }
- }
+ if (!fip->variant_parts.empty ())
+ add_variant_property (fip, type, cu);
/* Copy the saved-up fields into the field vector. */
for (int i = 0; i < nfields; ++i)
= ((i < fip->baseclasses.size ()) ? fip->baseclasses[i]
: fip->fields[i - fip->baseclasses.size ()]);
- TYPE_FIELD (type, i) = field.field;
+ type->field (i) = field.field;
switch (field.accessibility)
{
case DW_ACCESS_private:
fnp->type = alloc_type (objfile);
this_type = read_type_die (die, cu);
- if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
+ if (this_type && this_type->code () == TYPE_CODE_FUNC)
{
- int nparams = TYPE_NFIELDS (this_type);
+ int nparams = this_type->num_fields ();
/* TYPE is the domain of this method, and THIS_TYPE is the type
of the method itself (TYPE_CODE_METHOD). */
smash_to_method_type (fnp->type, type,
TYPE_TARGET_TYPE (this_type),
- TYPE_FIELDS (this_type),
- TYPE_NFIELDS (this_type),
+ this_type->fields (),
+ this_type->num_fields (),
TYPE_VARARGS (this_type));
/* Handle static member functions.
/* If there is no `this' field and no DW_AT_containing_type,
we cannot actually find a base class context for the
vtable! */
- if (TYPE_NFIELDS (this_type) == 0
+ if (this_type->num_fields () == 0
|| !TYPE_FIELD_ARTIFICIAL (this_type, 0))
{
complaint (_("cannot determine context for virtual member "
struct type *pfn_type, *self_type, *new_type;
/* Check for a structure with no name and two children. */
- if (TYPE_CODE (type) != TYPE_CODE_STRUCT || TYPE_NFIELDS (type) != 2)
+ if (type->code () != TYPE_CODE_STRUCT || type->num_fields () != 2)
return;
/* Check for __pfn and __delta members. */
/* Find the type of the method. */
pfn_type = TYPE_FIELD_TYPE (type, 0);
if (pfn_type == NULL
- || TYPE_CODE (pfn_type) != TYPE_CODE_PTR
- || TYPE_CODE (TYPE_TARGET_TYPE (pfn_type)) != TYPE_CODE_FUNC)
+ || pfn_type->code () != TYPE_CODE_PTR
+ || TYPE_TARGET_TYPE (pfn_type)->code () != TYPE_CODE_FUNC)
return;
/* Look for the "this" argument. */
pfn_type = TYPE_TARGET_TYPE (pfn_type);
- if (TYPE_NFIELDS (pfn_type) == 0
+ if (pfn_type->num_fields () == 0
/* || TYPE_FIELD_TYPE (pfn_type, 0) == NULL */
- || TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR)
+ || TYPE_FIELD_TYPE (pfn_type, 0)->code () != TYPE_CODE_PTR)
return;
self_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
new_type = alloc_type (objfile);
smash_to_method_type (new_type, self_type, TYPE_TARGET_TYPE (pfn_type),
- TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
+ pfn_type->fields (), pfn_type->num_fields (),
TYPE_VARARGS (pfn_type));
smash_to_methodptr_type (type, new_type);
}
if (get_die_type (die, cu) != NULL)
return get_die_type (die, cu);
- TYPE_NAME (type) = full_name;
+ type->set_name (full_name);
}
else
{
/* The name is already allocated along with this objfile, so
we don't need to duplicate it for the type. */
- TYPE_NAME (type) = name;
+ type->set_name (name);
}
}
if (die->tag == DW_TAG_structure_type)
{
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ type->set_code (TYPE_CODE_STRUCT);
}
else if (die->tag == DW_TAG_union_type)
{
- TYPE_CODE (type) = TYPE_CODE_UNION;
- }
- else if (die->tag == DW_TAG_variant_part)
- {
- TYPE_CODE (type) = TYPE_CODE_UNION;
- TYPE_FLAG_DISCRIMINATED_UNION (type) = 1;
+ type->set_code (TYPE_CODE_UNION);
}
else
{
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ type->set_code (TYPE_CODE_STRUCT);
}
if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
TYPE_LENGTH (type) = DW_UNSND (attr);
else
{
- /* For the moment, dynamic type sizes are not supported
- by GDB's struct type. The actual size is determined
- on-demand when resolving the type of a given object,
- so set the type's length to zero for now. Otherwise,
- we record an expression as the length, and that expression
- could lead to a very large value, which could eventually
- lead to us trying to allocate that much memory when creating
- a value of that type. */
+ struct dynamic_prop prop;
+ if (attr_to_dynamic_prop (attr, die, cu, &prop,
+ cu->per_cu->addr_type ()))
+ type->add_dyn_prop (DYN_PROP_BYTE_SIZE, prop);
TYPE_LENGTH (type) = 0;
}
}
return type;
}
+static void handle_struct_member_die
+ (struct die_info *child_die,
+ struct type *type,
+ struct field_info *fi,
+ std::vector<struct symbol *> *template_args,
+ struct dwarf2_cu *cu);
+
+/* A helper for handle_struct_member_die that handles
+ DW_TAG_variant_part. */
+
+static void
+handle_variant_part (struct die_info *die, struct type *type,
+ struct field_info *fi,
+ std::vector<struct symbol *> *template_args,
+ struct dwarf2_cu *cu)
+{
+ variant_part_builder *new_part;
+ if (fi->current_variant_part == nullptr)
+ {
+ fi->variant_parts.emplace_back ();
+ new_part = &fi->variant_parts.back ();
+ }
+ else if (!fi->current_variant_part->processing_variant)
+ {
+ complaint (_("nested DW_TAG_variant_part seen "
+ "- DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ return;
+ }
+ else
+ {
+ variant_field ¤t = fi->current_variant_part->variants.back ();
+ current.variant_parts.emplace_back ();
+ new_part = ¤t.variant_parts.back ();
+ }
+
+ /* When we recurse, we want callees to add to this new variant
+ part. */
+ scoped_restore save_current_variant_part
+ = make_scoped_restore (&fi->current_variant_part, new_part);
+
+ struct attribute *discr = dwarf2_attr (die, DW_AT_discr, cu);
+ if (discr == NULL)
+ {
+ /* It's a univariant form, an extension we support. */
+ }
+ else if (discr->form_is_ref ())
+ {
+ struct dwarf2_cu *target_cu = cu;
+ struct die_info *target_die = follow_die_ref (die, discr, &target_cu);
+
+ new_part->discriminant_offset = target_die->sect_off;
+ }
+ else
+ {
+ complaint (_("DW_AT_discr does not have DIE reference form"
+ " - DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ }
+
+ for (die_info *child_die = die->child;
+ child_die != NULL;
+ child_die = child_die->sibling)
+ handle_struct_member_die (child_die, type, fi, template_args, cu);
+}
+
+/* A helper for handle_struct_member_die that handles
+ DW_TAG_variant. */
+
+static void
+handle_variant (struct die_info *die, struct type *type,
+ struct field_info *fi,
+ std::vector<struct symbol *> *template_args,
+ struct dwarf2_cu *cu)
+{
+ if (fi->current_variant_part == nullptr)
+ {
+ complaint (_("saw DW_TAG_variant outside DW_TAG_variant_part "
+ "- DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ return;
+ }
+ if (fi->current_variant_part->processing_variant)
+ {
+ complaint (_("nested DW_TAG_variant seen "
+ "- DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ return;
+ }
+
+ scoped_restore save_processing_variant
+ = make_scoped_restore (&fi->current_variant_part->processing_variant,
+ true);
+
+ fi->current_variant_part->variants.emplace_back ();
+ variant_field &variant = fi->current_variant_part->variants.back ();
+ variant.first_field = fi->fields.size ();
+
+ /* In a variant we want to get the discriminant and also add a
+ field for our sole member child. */
+ struct attribute *discr = dwarf2_attr (die, DW_AT_discr_value, cu);
+ if (discr == nullptr)
+ {
+ discr = dwarf2_attr (die, DW_AT_discr_list, cu);
+ if (discr == nullptr || DW_BLOCK (discr)->size == 0)
+ variant.default_branch = true;
+ else
+ variant.discr_list_data = DW_BLOCK (discr);
+ }
+ else
+ variant.discriminant_value = DW_UNSND (discr);
+
+ for (die_info *variant_child = die->child;
+ variant_child != NULL;
+ variant_child = variant_child->sibling)
+ handle_struct_member_die (variant_child, type, fi, template_args, cu);
+
+ variant.last_field = fi->fields.size ();
+}
+
/* A helper for process_structure_scope that handles a single member
DIE. */
struct dwarf2_cu *cu)
{
if (child_die->tag == DW_TAG_member
- || child_die->tag == DW_TAG_variable
- || child_die->tag == DW_TAG_variant_part)
+ || child_die->tag == DW_TAG_variable)
{
/* NOTE: carlton/2002-11-05: A C++ static data member
should be a DW_TAG_member that is a declaration, but
if (arg != NULL)
template_args->push_back (arg);
}
+ else if (child_die->tag == DW_TAG_variant_part)
+ handle_variant_part (child_die, type, fi, template_args, cu);
else if (child_die->tag == DW_TAG_variant)
- {
- /* In a variant we want to get the discriminant and also add a
- field for our sole member child. */
- struct attribute *discr = dwarf2_attr (child_die, DW_AT_discr_value, cu);
-
- for (die_info *variant_child = child_die->child;
- variant_child != NULL;
- variant_child = variant_child->sibling)
- {
- if (variant_child->tag == DW_TAG_member)
- {
- handle_struct_member_die (variant_child, type, fi,
- template_args, cu);
- /* Only handle the one. */
- break;
- }
- }
-
- /* We don't handle this but we might as well report it if we see
- it. */
- if (dwarf2_attr (child_die, DW_AT_discr_list, cu) != nullptr)
- complaint (_("DW_AT_discr_list is not supported yet"
- " - DIE at %s [in module %s]"),
- sect_offset_str (child_die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
-
- /* The first field was just added, so we can stash the
- discriminant there. */
- gdb_assert (!fi->fields.empty ());
- if (discr == NULL)
- fi->fields.back ().variant.default_branch = true;
- else
- fi->fields.back ().variant.discriminant_value = DW_UNSND (discr);
- }
+ handle_variant (child_die, type, fi, template_args, cu);
}
/* Finish creating a structure or union type, including filling in
if (type == NULL)
type = read_structure_type (die, cu);
- /* When reading a DW_TAG_variant_part, we need to notice when we
- read the discriminant member, so we can record it later in the
- discriminant_info. */
- bool is_variant_part = TYPE_FLAG_DISCRIMINATED_UNION (type);
- sect_offset discr_offset {};
bool has_template_parameters = false;
-
- if (is_variant_part)
- {
- struct attribute *discr = dwarf2_attr (die, DW_AT_discr, cu);
- if (discr == NULL)
- {
- /* Maybe it's a univariant form, an extension we support.
- In this case arrange not to check the offset. */
- is_variant_part = false;
- }
- else if (discr->form_is_ref ())
- {
- struct dwarf2_cu *target_cu = cu;
- struct die_info *target_die = follow_die_ref (die, discr, &target_cu);
-
- discr_offset = target_die->sect_off;
- }
- else
- {
- complaint (_("DW_AT_discr does not have DIE reference form"
- " - DIE at %s [in module %s]"),
- sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
- is_variant_part = false;
- }
- }
-
if (die->child != NULL && ! die_is_declaration (die, cu))
{
struct field_info fi;
while (child_die && child_die->tag)
{
handle_struct_member_die (child_die, type, &fi, &template_args, cu);
-
- if (is_variant_part && discr_offset == child_die->sect_off)
- fi.fields.back ().variant.is_discriminant = true;
-
child_die = child_die->sibling;
}
int i;
/* Our own class provides vtbl ptr. */
- for (i = TYPE_NFIELDS (t) - 1;
+ for (i = t->num_fields () - 1;
i >= TYPE_N_BASECLASSES (t);
--i)
{
if (i < TYPE_N_BASECLASSES (t))
complaint (_("virtual function table pointer "
"not found when defining class '%s'"),
- TYPE_NAME (type) ? TYPE_NAME (type) : "");
+ type->name () ? type->name () : "");
}
else
{
int i;
- for (i = TYPE_NFIELDS (type) - 1;
+ for (i = type->num_fields () - 1;
i >= TYPE_N_BASECLASSES (type);
--i)
{
these DIEs are identified by the fact that they have no byte_size
attribute, and a declaration attribute. */
if (dwarf2_attr (die, DW_AT_byte_size, cu) != NULL
- || !die_is_declaration (die, cu))
+ || !die_is_declaration (die, cu)
+ || dwarf2_attr (die, DW_AT_signature, cu) != NULL)
{
struct symbol *sym = new_symbol (die, type, cu);
}
}
-/* Assuming DIE is an enumeration type, and TYPE is its associated type,
- update TYPE using some information only available in DIE's children. */
+/* Assuming DIE is an enumeration type, and TYPE is its associated
+ type, update TYPE using some information only available in DIE's
+ children. In particular, the fields are computed. */
static void
update_enumeration_type_from_children (struct die_info *die,
int flag_enum = 1;
auto_obstack obstack;
+ std::vector<struct field> fields;
for (child_die = die->child;
child_die != NULL && child_die->tag;
flag_enum = 0;
}
- /* If we already know that the enum type is neither unsigned, nor
- a flag type, no need to look at the rest of the enumerates. */
- if (!unsigned_enum && !flag_enum)
- break;
+ fields.emplace_back ();
+ struct field &field = fields.back ();
+ FIELD_NAME (field) = dwarf2_physname (name, child_die, cu);
+ SET_FIELD_ENUMVAL (field, value);
+ }
+
+ if (!fields.empty ())
+ {
+ type->set_num_fields (fields.size ());
+ type->set_fields
+ ((struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * fields.size ()));
+ memcpy (type->fields (), fields.data (),
+ sizeof (struct field) * fields.size ());
}
if (unsigned_enum)
type = alloc_type (objfile);
- TYPE_CODE (type) = TYPE_CODE_ENUM;
+ type->set_code (TYPE_CODE_ENUM);
name = dwarf2_full_name (NULL, die, cu);
if (name != NULL)
- TYPE_NAME (type) = name;
+ type->set_name (name);
attr = dwarf2_attr (die, DW_AT_type, cu);
if (attr != NULL)
if (die_is_declaration (die, cu))
TYPE_STUB (type) = 1;
- /* Finish the creation of this type by using the enum's children.
- We must call this even when the underlying type has been provided
- so that we can determine if we're looking at a "flag" enum. */
- update_enumeration_type_from_children (die, type, cu);
-
/* If this type has an underlying type that is not a stub, then we
may use its attributes. We always use the "unsigned" attribute
in this situation, because ordinarily we guess whether the type
TYPE_DECLARED_CLASS (type) = dwarf2_flag_true_p (die, DW_AT_enum_class, cu);
- return set_die_type (die, type, cu);
+ set_die_type (die, type, cu);
+
+ /* Finish the creation of this type by using the enum's children.
+ Note that, as usual, this must come after set_die_type to avoid
+ infinite recursion when trying to compute the names of the
+ enumerators. */
+ update_enumeration_type_from_children (die, type, cu);
+
+ return type;
}
/* Given a pointer to a die which begins an enumeration, process all
if (die->child != NULL)
{
struct die_info *child_die;
- struct symbol *sym;
- std::vector<struct field> fields;
const char *name;
child_die = die->child;
{
name = dwarf2_name (child_die, cu);
if (name)
- {
- sym = new_symbol (child_die, this_type, cu);
-
- fields.emplace_back ();
- struct field &field = fields.back ();
-
- FIELD_NAME (field) = sym->linkage_name ();
- FIELD_TYPE (field) = NULL;
- SET_FIELD_ENUMVAL (field, SYMBOL_VALUE (sym));
- FIELD_BITSIZE (field) = 0;
- }
+ new_symbol (child_die, this_type, cu);
}
child_die = child_die->sibling;
}
-
- if (!fields.empty ())
- {
- TYPE_NFIELDS (this_type) = fields.size ();
- TYPE_FIELDS (this_type) = (struct field *)
- TYPE_ALLOC (this_type, sizeof (struct field) * fields.size ());
- memcpy (TYPE_FIELDS (this_type), fields.data (),
- sizeof (struct field) * fields.size ());
- }
}
/* If we are reading an enum from a .debug_types unit, and the enum
name = dwarf2_name (die, cu);
if (name)
- TYPE_NAME (type) = name;
+ type->set_name (name);
maybe_set_alignment (cu, die, type);
struct dwarf2_locexpr_baton *baton;
gdb_byte *ptr;
unsigned int cu_off;
- enum bfd_endian byte_order = gdbarch_byte_order (get_objfile_arch (objfile));
+ enum bfd_endian byte_order = gdbarch_byte_order (objfile->arch ());
LONGEST offset = 0;
gdb_assert (common_loc && member_loc);
std::vector<const char *> excludes;
add_using_directive (using_directives (cu),
- previous_prefix, TYPE_NAME (type), NULL,
+ previous_prefix, type->name (), NULL,
NULL, excludes, 0, &objfile->objfile_obstack);
}
}
read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct gdbarch *gdbarch
- = get_objfile_arch (cu->per_cu->dwarf2_per_objfile->objfile);
+ = cu->per_cu->dwarf2_per_objfile->objfile->arch ();
struct comp_unit_head *cu_header = &cu->header;
struct type *type;
struct attribute *attr_byte_size;
if (type)
return type;
- if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_METHOD)
+ if (check_typedef (to_type)->code () == TYPE_CODE_METHOD)
type = lookup_methodptr_type (to_type);
- else if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_FUNC)
+ else if (check_typedef (to_type)->code () == TYPE_CODE_FUNC)
{
struct type *new_type
= alloc_type (cu->per_cu->dwarf2_per_objfile->objfile);
smash_to_method_type (new_type, domain, TYPE_TARGET_TYPE (to_type),
- TYPE_FIELDS (to_type), TYPE_NFIELDS (to_type),
+ to_type->fields (), to_type->num_fields (),
TYPE_VARARGS (to_type));
type = lookup_methodptr_type (new_type);
}
base_type = copy_type (base_type);
inner_array = base_type;
- while (TYPE_CODE (TYPE_TARGET_TYPE (inner_array)) == TYPE_CODE_ARRAY)
+ while (TYPE_TARGET_TYPE (inner_array)->code () == TYPE_CODE_ARRAY)
{
TYPE_TARGET_TYPE (inner_array) =
copy_type (TYPE_TARGET_TYPE (inner_array));
/* In case the const qualifier is applied to an array type, the element type
is so qualified, not the array type (section 6.7.3 of C99). */
- if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
+ if (base_type->code () == TYPE_CODE_ARRAY)
return add_array_cv_type (die, cu, base_type, 1, 0);
cv_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
/* In case the volatile qualifier is applied to an array type, the
element type is so qualified, not the array type (section 6.7.3
of C99). */
- if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
+ if (base_type->code () == TYPE_CODE_ARRAY)
return add_array_cv_type (die, cu, base_type, 0, 1);
cv_type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
struct type *type, *range_type, *index_type, *char_type;
struct attribute *attr;
struct dynamic_prop prop;
}
/* Allocate storage for parameters and fill them in. */
- TYPE_NFIELDS (ftype) = nparams;
- TYPE_FIELDS (ftype) = (struct field *)
- TYPE_ZALLOC (ftype, nparams * sizeof (struct field));
+ ftype->set_num_fields (nparams);
+ ftype->set_fields
+ ((struct field *) TYPE_ZALLOC (ftype, nparams * sizeof (struct field)));
/* TYPE_FIELD_TYPE must never be NULL. Pre-fill the array to ensure it
even if we error out during the parameters reading below. */
dwarf2_init_float_type (struct objfile *objfile, int bits, const char *name,
const char *name_hint, enum bfd_endian byte_order)
{
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
const struct floatformat **format;
struct type *type;
int bits, const char *name_hint,
enum bfd_endian byte_order)
{
- gdbarch *gdbarch = get_objfile_arch (objfile);
+ gdbarch *gdbarch = objfile->arch ();
struct type *tt = nullptr;
/* Try to find a suitable floating point builtin type of size BITS.
if (tt != nullptr && TYPE_LENGTH (tt) * TARGET_CHAR_BIT != bits)
tt = nullptr;
- const char *name = (tt == nullptr) ? nullptr : TYPE_NAME (tt);
+ const char *name = (tt == nullptr) ? nullptr : tt->name ();
return dwarf2_init_float_type (objfile, bits, name, name_hint, byte_order);
}
if (!name)
complaint (_("DW_AT_name missing from DW_TAG_base_type"));
- arch = get_objfile_arch (objfile);
+ arch = objfile->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (arch);
attr = dwarf2_attr (die, DW_AT_endianity, cu);
case DW_ATE_complex_float:
type = dwarf2_init_complex_target_type (cu, objfile, bits / 2, name,
byte_order);
- if (TYPE_CODE (type) == TYPE_CODE_ERROR)
+ if (type->code () == TYPE_CODE_ERROR)
{
if (name == nullptr)
{
struct obstack *obstack
= &cu->per_cu->dwarf2_per_objfile->objfile->objfile_obstack;
- name = obconcat (obstack, "_Complex ", TYPE_NAME (type),
+ name = obconcat (obstack, "_Complex ", type->name (),
nullptr);
}
type = init_type (objfile, TYPE_CODE_ERROR, bits, name);
GCC produces an empty range DIE.
FIXME: muller/2010-05-28: Possible references to object for low bound,
high bound or count are not yet handled by this code. */
- if (TYPE_CODE (index_type) == TYPE_CODE_VOID)
+ if (index_type->code () == TYPE_CODE_VOID)
index_type = cu->per_cu->addr_sized_int_type (false);
return index_type;
name = dwarf2_name (die, cu);
if (name)
- TYPE_NAME (range_type) = name;
+ range_type->set_name (name);
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
type = init_type (cu->per_cu->dwarf2_per_objfile->objfile, TYPE_CODE_VOID,0,
NULL);
- TYPE_NAME (type) = dwarf2_name (die, cu);
+ type->set_name (dwarf2_name (die, cu));
/* In Ada, an unspecified type is typically used when the description
of the type is deferred to a different unit. When encountering
if (attr != nullptr)
cu->str_offsets_base = DW_UNSND (attr);
+ attr = die->attr (DW_AT_loclists_base);
+ if (attr != nullptr)
+ cu->loclist_base = DW_UNSND (attr);
+
auto maybe_addr_base = die->addr_base ();
if (maybe_addr_base.has_value ())
cu->addr_base = *maybe_addr_base;
/* Note that both forms of linkage name might appear. We
assume they will be the same, and we only store the last
one we see. */
- linkage_name = DW_STRING (&attr);
+ linkage_name = attr.value_as_string ();
+ /* rustc emits invalid values for DW_AT_linkage_name. Ignore these.
+ See https://github.com/rust-lang/rust/issues/32925. */
+ if (cu->language == language_rust && linkage_name != NULL
+ && strchr (linkage_name, '{') != NULL)
+ linkage_name = NULL;
break;
case DW_AT_low_pc:
has_low_pc_attr = 1;
if (lowpc == 0 && !dwarf2_per_objfile->has_section_at_zero)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
complaint (_("DW_AT_low_pc %s is zero "
"for DIE at %s [in module %s]"),
else if (lowpc >= highpc)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
complaint (_("DW_AT_low_pc %s is not < DW_AT_high_pc %s "
"for DIE at %s [in module %s]"),
}
}
+/* Return true if a DIE with TAG may have the DW_AT_const_value
+ attribute. */
+
+static bool
+can_have_DW_AT_const_value_p (enum dwarf_tag tag)
+{
+ switch (tag)
+ {
+ case DW_TAG_constant:
+ case DW_TAG_enumerator:
+ case DW_TAG_formal_parameter:
+ case DW_TAG_template_value_param:
+ case DW_TAG_variable:
+ return true;
+ }
+
+ return false;
+}
+
void
partial_die_info::fixup (struct dwarf2_cu *cu)
{
}
}
+ if (!has_const_value && has_specification
+ && can_have_DW_AT_const_value_p (tag))
+ {
+ struct partial_die_info *spec_die;
+
+ auto res = find_partial_die (spec_offset, spec_is_dwz, cu);
+ spec_die = res.pdi;
+ cu = res.cu;
+
+ spec_die->fixup (cu);
+
+ if (spec_die->has_const_value)
+ {
+ /* Copy DW_AT_const_value attribute if it is set. */
+ has_const_value = spec_die->has_const_value;
+ }
+ }
+
/* Set default names for some unnamed DIEs. */
if (name == NULL && tag == DW_TAG_namespace)
fixup_called = 1;
}
+/* Read the .debug_loclists header contents from the given SECTION in the
+ HEADER. */
+static void
+read_loclist_header (struct loclist_header *header,
+ struct dwarf2_section_info *section)
+{
+ unsigned int bytes_read;
+ bfd *abfd = section->get_bfd_owner ();
+ const gdb_byte *info_ptr = section->buffer;
+ header->length = read_initial_length (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ header->version = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ header->addr_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ header->segment_collector_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ header->offset_entry_count = read_4_bytes (abfd, info_ptr);
+}
+
+/* Return the DW_AT_loclists_base value for the CU. */
+static ULONGEST
+lookup_loclist_base (struct dwarf2_cu *cu)
+{
+ /* For the .dwo unit, the loclist_base points to the first offset following
+ the header. The header consists of the following entities-
+ 1. Unit Length (4 bytes for 32 bit DWARF format, and 12 bytes for the 64
+ bit format)
+ 2. version (2 bytes)
+ 3. address size (1 byte)
+ 4. segment selector size (1 byte)
+ 5. offset entry count (4 bytes)
+ These sizes are derived as per the DWARFv5 standard. */
+ if (cu->dwo_unit != nullptr)
+ {
+ if (cu->header.initial_length_size == 4)
+ return LOCLIST_HEADER_SIZE32;
+ return LOCLIST_HEADER_SIZE64;
+ }
+ return cu->loclist_base;
+}
+
+/* Given a DW_FORM_loclistx value LOCLIST_INDEX, fetch the offset from the
+ array of offsets in the .debug_loclists section. */
+static CORE_ADDR
+read_loclist_index (struct dwarf2_cu *cu, ULONGEST loclist_index)
+{
+ struct dwarf2_per_objfile *dwarf2_per_objfile
+ = cu->per_cu->dwarf2_per_objfile;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ bfd *abfd = objfile->obfd;
+ ULONGEST loclist_base = lookup_loclist_base (cu);
+ struct dwarf2_section_info *section = cu_debug_loc_section (cu);
+
+ section->read (objfile);
+ if (section->buffer == NULL)
+ complaint (_("DW_FORM_loclistx used without .debug_loclists "
+ "section [in module %s]"), objfile_name (objfile));
+ struct loclist_header header;
+ read_loclist_header (&header, section);
+ if (loclist_index >= header.offset_entry_count)
+ complaint (_("DW_FORM_loclistx pointing outside of "
+ ".debug_loclists offset array [in module %s]"),
+ objfile_name (objfile));
+ if (loclist_base + loclist_index * cu->header.offset_size
+ >= section->size)
+ complaint (_("DW_FORM_loclistx pointing outside of "
+ ".debug_loclists section [in module %s]"),
+ objfile_name (objfile));
+ const gdb_byte *info_ptr
+ = section->buffer + loclist_base + loclist_index * cu->header.offset_size;
+
+ if (cu->header.offset_size == 4)
+ return bfd_get_32 (abfd, info_ptr) + loclist_base;
+ else
+ return bfd_get_64 (abfd, info_ptr) + loclist_base;
+}
+
/* Process the attributes that had to be skipped in the first round. These
attributes are the ones that need str_offsets_base or addr_base attributes.
They could not have been processed in the first round, because at the time
case DW_FORM_GNU_addr_index:
DW_ADDR (attr) = read_addr_index (cu, DW_UNSND (attr));
break;
+ case DW_FORM_loclistx:
+ DW_UNSND (attr) = read_loclist_index (cu, DW_UNSND (attr));
+ break;
case DW_FORM_strx:
case DW_FORM_strx1:
case DW_FORM_strx2:
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
bfd *abfd = reader->abfd;
struct comp_unit_head *cu_header = &cu->header;
unsigned int bytes_read;
info_ptr += bytes_read;
break;
case DW_FORM_addr:
- DW_ADDR (attr) = cu->header.read_address (abfd, info_ptr, &bytes_read);
- DW_ADDR (attr) = gdbarch_adjust_dwarf2_addr (gdbarch, DW_ADDR (attr));
- info_ptr += bytes_read;
+ {
+ struct gdbarch *gdbarch = objfile->arch ();
+ DW_ADDR (attr) = cu->header.read_address (abfd, info_ptr, &bytes_read);
+ DW_ADDR (attr) = gdbarch_adjust_dwarf2_addr (gdbarch, DW_ADDR (attr));
+ info_ptr += bytes_read;
+ }
break;
case DW_FORM_block2:
blk = dwarf_alloc_block (cu);
DW_UNSND (attr) = cu->header.read_offset (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
break;
+ case DW_FORM_loclistx:
+ {
+ *need_reprocess = true;
+ DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ }
+ break;
case DW_FORM_string:
DW_STRING (attr) = read_direct_string (abfd, info_ptr, &bytes_read);
DW_STRING_IS_CANONICAL (attr) = 0;
if (attr != NULL)
{
- if (attr->form == DW_FORM_strp || attr->form == DW_FORM_line_strp
- || attr->form == DW_FORM_string
- || attr->form == DW_FORM_strx
- || attr->form == DW_FORM_strx1
- || attr->form == DW_FORM_strx2
- || attr->form == DW_FORM_strx3
- || attr->form == DW_FORM_strx4
- || attr->form == DW_FORM_GNU_str_index
- || attr->form == DW_FORM_GNU_strp_alt)
- str = DW_STRING (attr);
- else
+ str = attr->value_as_string ();
+ if (str == nullptr)
complaint (_("string type expected for attribute %s for "
"DIE at %s in module %s"),
dwarf_attr_name (name), sect_offset_str (die->sect_off),
CORE_ADDR baseaddr;
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
bfd *abfd = objfile->obfd;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
/* True if we're recording line info (as opposed to building partial
symtabs and just interested in finding include files mentioned by
the line number program). */
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
struct symbol *sym = NULL;
const char *name;
struct attribute *attr = NULL;
name = dwarf2_name (die, cu);
if (name)
{
- const char *linkagename;
int suppress_add = 0;
if (space)
sym = space;
else
- sym = allocate_symbol (objfile);
+ sym = new (&objfile->objfile_obstack) symbol;
OBJSTAT (objfile, n_syms++);
/* Cache this symbol's name and the name's demangled form (if any). */
sym->set_language (cu->language, &objfile->objfile_obstack);
- linkagename = dwarf2_physname (name, die, cu);
- sym->compute_and_set_names (linkagename, false, objfile->per_bfd);
-
/* Fortran does not have mangling standard and the mangling does differ
between gfortran, iFort etc. */
- if (cu->language == language_fortran
- && symbol_get_demangled_name (sym) == NULL)
- symbol_set_demangled_name (sym,
- dwarf2_full_name (name, die, cu),
- NULL);
+ const char *physname
+ = (cu->language == language_fortran
+ ? dwarf2_full_name (name, die, cu)
+ : dwarf2_physname (name, die, cu));
+ const char *linkagename = dw2_linkage_name (die, cu);
+
+ if (linkagename == nullptr || cu->language == language_ada)
+ sym->set_linkage_name (physname);
+ else
+ {
+ sym->set_demangled_name (physname, &objfile->objfile_obstack);
+ sym->set_linkage_name (linkagename);
+ }
/* Default assumptions.
Use the passed type or decode it from the die. */
/* Compilation with minimal debug info may result in
variables with missing type entries. Change the
misleading `void' type to something sensible. */
- if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
+ if (SYMBOL_TYPE (sym)->code () == TYPE_CODE_VOID)
SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_int;
attr = dwarf2_attr (die, DW_AT_const_value, cu);
/* The symbol's name is already allocated along
with this objfile, so we don't need to
duplicate it for the type. */
- if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
- TYPE_NAME (SYMBOL_TYPE (sym)) = sym->search_name ();
+ if (SYMBOL_TYPE (sym)->name () == 0)
+ SYMBOL_TYPE (sym)->set_name (sym->search_name ());
}
}
}
DW_TAG_namespace DIEs with a name of "::" for the global namespace.
Work around this problem here. */
if (cu->language == language_cplus
- && strcmp (TYPE_NAME (parent_type), "::") == 0)
+ && strcmp (parent_type->name (), "::") == 0)
return "";
/* We give a name to even anonymous namespaces. */
- return TYPE_NAME (parent_type);
+ return parent_type->name ();
case DW_TAG_class_type:
case DW_TAG_interface_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_module:
parent_type = read_type_die (parent, cu);
- if (TYPE_NAME (parent_type) != NULL)
- return TYPE_NAME (parent_type);
+ if (parent_type->name () != NULL)
+ return parent_type->name ();
else
/* An anonymous structure is only allowed non-static data
members; no typedefs, no member functions, et cetera.
parent_type = read_type_die (parent, cu);
if (TYPE_DECLARED_CLASS (parent_type))
{
- if (TYPE_NAME (parent_type) != NULL)
- return TYPE_NAME (parent_type);
+ if (parent_type->name () != NULL)
+ return parent_type->name ();
return "";
}
/* Fall through. */
{
if (name && cu->language == language_cplus)
{
- std::string canon_name = cp_canonicalize_string (name);
+ gdb::unique_xmalloc_ptr<char> canon_name
+ = cp_canonicalize_string (name);
- if (!canon_name.empty ())
- {
- if (canon_name != name)
- name = objfile->intern (canon_name);
- }
+ if (canon_name != nullptr)
+ name = objfile->intern (canon_name.get ());
}
return name;
{
CORE_ADDR pc = (*get_frame_pc) (baton);
CORE_ADDR baseaddr = objfile->text_section_offset ();
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
for (const auto &cand_off
: dwarf2_per_objfile->abstract_to_concrete[die->sect_off])
/* Decode simple location descriptions.
Given a pointer to a dwarf block that defines a location, compute
- the location and return the value.
-
- NOTE drow/2003-11-18: This function is called in two situations
- now: for the address of static or global variables (partial symbols
- only) and for offsets into structures which are expected to be
- (more or less) constant. The partial symbol case should go away,
- and only the constant case should remain. That will let this
- function complain more accurately. A few special modes are allowed
- without complaint for global variables (for instance, global
- register values and thread-local values).
-
- A location description containing no operations indicates that the
- object is optimized out. The return value is 0 for that case.
- FIXME drow/2003-11-16: No callers check for this case any more; soon all
- callers will only want a very basic result and this can become a
- complaint.
-
- Note that stack[0] is unused except as a default error return. */
+ the location and return the value. If COMPUTED is non-null, it is
+ set to true to indicate that decoding was successful, and false
+ otherwise. If COMPUTED is null, then this function may emit a
+ complaint. */
static CORE_ADDR
-decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
+decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu, bool *computed)
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
size_t i;
unsigned int bytes_read, unsnd;
gdb_byte op;
+ if (computed != nullptr)
+ *computed = false;
+
i = 0;
stacki = 0;
stack[stacki] = 0;
case DW_OP_reg31:
stack[++stacki] = op - DW_OP_reg0;
if (i < size)
- dwarf2_complex_location_expr_complaint ();
+ {
+ if (computed == nullptr)
+ dwarf2_complex_location_expr_complaint ();
+ else
+ return 0;
+ }
break;
case DW_OP_regx:
i += bytes_read;
stack[++stacki] = unsnd;
if (i < size)
- dwarf2_complex_location_expr_complaint ();
+ {
+ if (computed == nullptr)
+ dwarf2_complex_location_expr_complaint ();
+ else
+ return 0;
+ }
break;
case DW_OP_addr:
global symbols, although the variable's address will be bogus
in the psymtab. */
if (i < size)
- dwarf2_complex_location_expr_complaint ();
+ {
+ if (computed == nullptr)
+ dwarf2_complex_location_expr_complaint ();
+ else
+ return 0;
+ }
break;
case DW_OP_GNU_push_tls_address:
non-zero to not look as a variable garbage collected by linker
which have DW_OP_addr 0. */
if (i < size)
- dwarf2_complex_location_expr_complaint ();
+ {
+ if (computed == nullptr)
+ dwarf2_complex_location_expr_complaint ();
+ else
+ return 0;
+ }
stack[stacki]++;
break;
case DW_OP_GNU_uninit:
+ if (computed != nullptr)
+ return 0;
break;
case DW_OP_addrx:
break;
default:
- {
- const char *name = get_DW_OP_name (op);
+ if (computed == nullptr)
+ {
+ const char *name = get_DW_OP_name (op);
- if (name)
- complaint (_("unsupported stack op: '%s'"),
- name);
- else
- complaint (_("unsupported stack op: '%02x'"),
- op);
- }
+ if (name)
+ complaint (_("unsupported stack op: '%s'"),
+ name);
+ else
+ complaint (_("unsupported stack op: '%02x'"),
+ op);
+ }
return (stack[stacki]);
}
outside of the allocated space. Also enforce minimum>0. */
if (stacki >= ARRAY_SIZE (stack) - 1)
{
- complaint (_("location description stack overflow"));
+ if (computed == nullptr)
+ complaint (_("location description stack overflow"));
return 0;
}
if (stacki <= 0)
{
- complaint (_("location description stack underflow"));
+ if (computed == nullptr)
+ complaint (_("location description stack underflow"));
return 0;
}
}
+
+ if (computed != nullptr)
+ *computed = true;
return (stack[stacki]);
}
But this is not a problem, because the gnat-specific information
is actually not needed for these types. */
if (need_gnat_info (cu)
- && TYPE_CODE (type) != TYPE_CODE_FUNC
- && TYPE_CODE (type) != TYPE_CODE_FLT
- && TYPE_CODE (type) != TYPE_CODE_METHODPTR
- && TYPE_CODE (type) != TYPE_CODE_MEMBERPTR
- && TYPE_CODE (type) != TYPE_CODE_METHOD
+ && type->code () != TYPE_CODE_FUNC
+ && type->code () != TYPE_CODE_FLT
+ && type->code () != TYPE_CODE_METHODPTR
+ && type->code () != TYPE_CODE_MEMBERPTR
+ && type->code () != TYPE_CODE_METHOD
&& !HAVE_GNAT_AUX_INFO (type))
INIT_GNAT_SPECIFIC (type);
{
struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
- add_dyn_prop (DYN_PROP_ALLOCATED, prop, type);
+ type->add_dyn_prop (DYN_PROP_ALLOCATED, prop);
}
else if (attr != NULL)
{
{
struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
- add_dyn_prop (DYN_PROP_ASSOCIATED, prop, type);
+ type->add_dyn_prop (DYN_PROP_ASSOCIATED, prop);
}
else if (attr != NULL)
{
attr = dwarf2_attr (die, DW_AT_data_location, cu);
if (attr_to_dynamic_prop (attr, die, cu, &prop,
cu->per_cu->addr_type ()))
- add_dyn_prop (DYN_PROP_DATA_LOCATION, prop, type);
+ type->add_dyn_prop (DYN_PROP_DATA_LOCATION, prop);
if (dwarf2_per_objfile->die_type_hash == NULL)
dwarf2_per_objfile->die_type_hash
struct cmd_list_element *set_dwarf_cmdlist;
struct cmd_list_element *show_dwarf_cmdlist;
-static void
-set_dwarf_cmd (const char *args, int from_tty)
-{
- help_list (set_dwarf_cmdlist, "maintenance set dwarf ", all_commands,
- gdb_stdout);
-}
-
-static void
-show_dwarf_cmd (const char *args, int from_tty)
-{
- cmd_show_list (show_dwarf_cmdlist, from_tty, "");
-}
-
static void
show_check_physname (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
void
_initialize_dwarf2_read ()
{
- add_prefix_cmd ("dwarf", class_maintenance, set_dwarf_cmd, _("\
+ add_basic_prefix_cmd ("dwarf", class_maintenance, _("\
Set DWARF specific variables.\n\
Configure DWARF variables such as the cache size."),
- &set_dwarf_cmdlist, "maintenance set dwarf ",
- 0/*allow-unknown*/, &maintenance_set_cmdlist);
+ &set_dwarf_cmdlist, "maintenance set dwarf ",
+ 0/*allow-unknown*/, &maintenance_set_cmdlist);
- add_prefix_cmd ("dwarf", class_maintenance, show_dwarf_cmd, _("\
+ add_show_prefix_cmd ("dwarf", class_maintenance, _("\
Show DWARF specific variables.\n\
Show DWARF variables such as the cache size."),
- &show_dwarf_cmdlist, "maintenance show dwarf ",
- 0/*allow-unknown*/, &maintenance_show_cmdlist);
+ &show_dwarf_cmdlist, "maintenance show dwarf ",
+ 0/*allow-unknown*/, &maintenance_show_cmdlist);
add_setshow_zinteger_cmd ("max-cache-age", class_obscure,
&dwarf_max_cache_age, _("\