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 *);
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;
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;
}
}
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
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,
prop.kind = PROP_VARIANT_PARTS;
prop.data.variant_parts = prop_value;
- add_dyn_prop (DYN_PROP_VARIANT_PARTS, prop, type);
+ 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)
/* 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);
TYPE_NFIELDS (type) = 3;
/* Save the field we care about. */
struct field saved_field = TYPE_FIELD (type, 0);
TYPE_FIELD (type, 1) = saved_field;
TYPE_FIELD_NAME (type, 1)
= rust_last_path_segment (TYPE_NAME (TYPE_FIELD_TYPE (type, 1)));
- TYPE_NAME (TYPE_FIELD_TYPE (type, 1))
- = rust_fully_qualify (&objfile->objfile_obstack, TYPE_NAME (type),
- TYPE_FIELD_NAME (type, 1));
+ TYPE_FIELD_TYPE (type, 1)->set_name
+ (rust_fully_qualify (&objfile->objfile_obstack, TYPE_NAME (type),
+ TYPE_FIELD_NAME (type, 1)));
const char *dataless_name
= rust_fully_qualify (&objfile->objfile_obstack, TYPE_NAME (type),
{
/* 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);
struct type *field_type = TYPE_FIELD_TYPE (type, 0);
const char *variant_name
= rust_last_path_segment (TYPE_NAME (field_type));
TYPE_FIELD_NAME (type, 0) = variant_name;
- TYPE_NAME (field_type)
- = rust_fully_qualify (&objfile->objfile_obstack,
- TYPE_NAME (type), variant_name);
+ field_type->set_name
+ (rust_fully_qualify (&objfile->objfile_obstack,
+ TYPE_NAME (type), variant_name));
}
else
{
{
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;
/* 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 space for the discriminant field. */
struct field *disr_field = &TYPE_FIELD (disr_type, 0);
++TYPE_FIELDS (sub_type);
}
TYPE_FIELD_NAME (type, i) = variant_name;
- TYPE_NAME (sub_type)
- = rust_fully_qualify (&objfile->objfile_obstack,
- TYPE_NAME (type), variant_name);
+ sub_type->set_name
+ (rust_fully_qualify (&objfile->objfile_obstack,
+ TYPE_NAME (type), variant_name));
}
/* Indicate that this is a variant type. */
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;
}
the two cases. */
if (TYPE_NFIELDS (type) > 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. */
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)
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;
}
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;
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;
}
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
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);
/* A convenience typedef that's used when finding the discriminant
field for a variant part. */
-typedef std::unordered_map<sect_offset, int> offset_map_type;
+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
= ((gdb::array_view<variant_part> *)
obstack_copy (&objfile->objfile_obstack, &parts, sizeof (parts)));
- add_dyn_prop (DYN_PROP_VARIANT_PARTS, prop, type);
+ type->add_dyn_prop (DYN_PROP_VARIANT_PARTS, prop);
}
/* Create the vector of fields, and attach it to the type. */
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);
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_NFIELDS (type) != 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
/* || 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));
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;
+ 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)
struct dynamic_prop prop;
if (attr_to_dynamic_prop (attr, die, cu, &prop,
cu->per_cu->addr_type ()))
- add_dyn_prop (DYN_PROP_BYTE_SIZE, prop, type);
+ type->add_dyn_prop (DYN_PROP_BYTE_SIZE, prop);
TYPE_LENGTH (type) = 0;
}
}
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_NFIELDS (type) = fields.size ();
+ TYPE_FIELDS (type) = (struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * fields.size ());
+ memcpy (TYPE_FIELDS (type), 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);
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);
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);
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)
{
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
/* 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 (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),
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);
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 ();
+ SYMBOL_TYPE (sym)->set_name (sym->search_name ());
}
}
}
{
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;
/* 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