switch (pdi->tag)
{
case DW_TAG_subprogram:
- if (pdi->is_external)
+ if (pdi->is_external || cu->language == language_ada)
{
+ /* brobecker/2007-12-26: Normally, only "external" DIEs are part
+ of the global scope. But in Ada, we want to be able to access
+ nested procedures globally. So all Ada subprograms are stored
+ in the global scope. */
/*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
mst_text, objfile); */
psym = add_psymbol_to_list (actual_name, strlen (actual_name),
struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct nextfield *new_field;
struct attribute *attr;
struct field *fp;
attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
if (attr)
{
- if (BITS_BIG_ENDIAN)
+ if (gdbarch_bits_big_endian (gdbarch))
{
/* For big endian bits, the DW_AT_bit_offset gives the
additional bit offset from the MSB of the containing
TYPE_LENGTH (type) = 0;
}
+ /* The enumeration DIE can be incomplete. In Ada, any type can be
+ declared as private in the package spec, and then defined only
+ inside the package body. Such types are known as Taft Amendment
+ Types. When another package uses such a type, an incomplete DIE
+ may be generated by the compiler. */
+ if (die_is_declaration (die, cu))
+ TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
+
set_die_type (die, type, cu);
}
static void
read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
{
+ struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
struct comp_unit_head *cu_header = &cu->header;
struct type *type;
struct attribute *attr_byte_size;
length accordingly. */
if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none)
{
- if (gdbarch_address_class_type_flags_p (current_gdbarch))
+ if (gdbarch_address_class_type_flags_p (gdbarch))
{
int type_flags;
type_flags = gdbarch_address_class_type_flags
- (current_gdbarch, byte_size, addr_class);
+ (gdbarch, byte_size, addr_class);
gdb_assert ((type_flags & ~TYPE_FLAG_ADDRESS_CLASS_ALL) == 0);
type = make_type_with_address_space (type, type_flags);
}
static void
read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
{
+ struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
struct type *base_type;
struct type *range_type;
struct attribute *attr;
complaint (&symfile_complaints,
_("DW_AT_type missing from DW_TAG_subrange_type"));
base_type
- = init_type (TYPE_CODE_INT, gdbarch_addr_bit (current_gdbarch) / 8,
+ = init_type (TYPE_CODE_INT, gdbarch_addr_bit (gdbarch) / 8,
0, NULL, cu->objfile);
}
case DW_LANG_Pascal83:
cu->language = language_pascal;
break;
+ case DW_LANG_ObjC:
+ cu->language = language_objc;
+ break;
case DW_LANG_Cobol74:
case DW_LANG_Cobol85:
default:
new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct symbol *sym = NULL;
char *name;
struct attribute *attr = NULL;
finish_block. */
SYMBOL_CLASS (sym) = LOC_BLOCK;
attr2 = dwarf2_attr (die, DW_AT_external, cu);
- if (attr2 && (DW_UNSND (attr2) != 0))
+ if ((attr2 && (DW_UNSND (attr2) != 0))
+ || cu->language == language_ada)
{
+ /* Subprograms marked external are stored as a global symbol.
+ Ada subprograms, whether marked external or not, are always
+ stored as a global symbol, because we want to be able to
+ access them globally. For instance, we want to be able
+ to break on a nested subprogram without having to
+ specify the context. */
add_symbol_to_list (sym, &global_symbols);
}
else
to something sensible. */
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
SYMBOL_TYPE (sym)
- = builtin_type (current_gdbarch)->nodebug_data_symbol;
+ = builtin_type (gdbarch)->nodebug_data_symbol;
attr = dwarf2_attr (die, DW_AT_const_value, cu);
if (attr)
static struct type *
die_type (struct die_info *die, struct dwarf2_cu *cu)
{
+ struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
struct type *type;
struct attribute *type_attr;
struct die_info *type_die;
if (!type_attr)
{
/* A missing DW_AT_type represents a void type. */
- return builtin_type (current_gdbarch)->builtin_void;
+ return builtin_type (gdbarch)->builtin_void;
}
else
type_die = follow_die_ref (die, type_attr, cu);
case DW_FORM_ref_addr:
case DW_FORM_addr:
fprintf_unfiltered (gdb_stderr, "address: ");
- deprecated_print_address_numeric (DW_ADDR (&die->attrs[i]), 1, gdb_stderr);
+ fputs_filtered (paddress (DW_ADDR (&die->attrs[i])), gdb_stderr);
break;
case DW_FORM_block2:
case DW_FORM_block4:
dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->objfile;
-
- /* Save the master objfile, so that we can report and look up the
- correct file containing this variable. */
- if (objfile->separate_debug_objfile_backlink)
- objfile = objfile->separate_debug_objfile_backlink;
-
if (attr_form_is_section_offset (attr)
/* ".debug_loc" may not exist at all, or the offset may be outside
the section. If so, fall through to the complaint in the
baton = obstack_alloc (&cu->objfile->objfile_obstack,
sizeof (struct dwarf2_loclist_baton));
- baton->objfile = objfile;
+ baton->per_cu = cu->per_cu;
+ gdb_assert (baton->per_cu);
/* We don't know how long the location list is, but make sure we
don't run off the edge of the section. */
baton = obstack_alloc (&cu->objfile->objfile_obstack,
sizeof (struct dwarf2_locexpr_baton));
- baton->objfile = objfile;
+ baton->per_cu = cu->per_cu;
+ gdb_assert (baton->per_cu);
if (attr_form_is_block (attr))
{
}
}
+/* Return the OBJFILE associated with the compilation unit CU. */
+
+struct objfile *
+dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *per_cu)
+{
+ struct objfile *objfile = per_cu->psymtab->objfile;
+
+ /* Return the master objfile, so that we can report and look up the
+ correct file containing this variable. */
+ if (objfile->separate_debug_objfile_backlink)
+ objfile = objfile->separate_debug_objfile_backlink;
+
+ return objfile;
+}
+
+/* Return the address size given in the compilation unit header for CU. */
+
+CORE_ADDR
+dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
+{
+ if (per_cu->cu)
+ return per_cu->cu->header.addr_size;
+ else
+ {
+ /* If the CU is not currently read in, we re-read its header. */
+ struct objfile *objfile = per_cu->psymtab->objfile;
+ struct dwarf2_per_objfile *per_objfile
+ = objfile_data (objfile, dwarf2_objfile_data_key);
+ gdb_byte *info_ptr = per_objfile->info_buffer + per_cu->offset;
+
+ struct comp_unit_head cu_header;
+ memset (&cu_header, 0, sizeof cu_header);
+ read_comp_unit_head (&cu_header, info_ptr, objfile->obfd);
+ return cu_header.addr_size;
+ }
+}
+
/* Locate the compilation unit from CU's objfile which contains the
DIE at OFFSET. Raises an error on failure. */