diff -r d71d6b13aae1 -r a7f96d0b3354 gdb/dwarf2read.c --- a/gdb/dwarf2read.c Wed Sep 10 12:23:56 2008 -0700 +++ b/gdb/dwarf2read.c Thu Sep 11 10:32:58 2008 -0700 @@ -766,6 +766,10 @@ static void add_partial_enumeration (struct partial_die_info *enum_pdi, struct dwarf2_cu *cu); + +static void add_partial_subprogram (struct partial_die_info *pdi, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct dwarf2_cu *cu); static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi, gdb_byte *info_ptr, @@ -1783,21 +1787,7 @@ switch (pdi->tag) { case DW_TAG_subprogram: - if (pdi->has_pc_info) - { - if (pdi->lowpc < *lowpc) - { - *lowpc = pdi->lowpc; - } - if (pdi->highpc > *highpc) - { - *highpc = pdi->highpc; - } - if (!pdi->is_declaration) - { - add_partial_symbol (pdi, cu); - } - } + add_partial_subprogram (pdi, lowpc, highpc, cu); break; case DW_TAG_variable: case DW_TAG_typedef: @@ -2145,6 +2135,51 @@ if (pdi->has_children) scan_partial_symbols (pdi->die_child, lowpc, highpc, cu); +} + +/* Read a partial die corresponding to a subprogram and create a partial + symbol for that subprogram. When the CU language allows it, this + routine also defines a partial symbol for each nested subprogram + that this subprogram contains. + + DIE my also be a lexical block, in which case we simply search + recursively for suprograms defined inside that lexical block. + Again, this is only performed when the CU language allows this + type of definitions. */ + +static void +add_partial_subprogram (struct partial_die_info *pdi, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct dwarf2_cu *cu) +{ + if (pdi->tag == DW_TAG_subprogram) + { + if (pdi->has_pc_info) + { + if (pdi->lowpc < *lowpc) + *lowpc = pdi->lowpc; + if (pdi->highpc > *highpc) + *highpc = pdi->highpc; + if (!pdi->is_declaration) + add_partial_symbol (pdi, cu); + } + } + + if (! pdi->has_children) + return; + + if (cu->language == language_ada) + { + pdi = pdi->die_child; + while (pdi != NULL) + { + fixup_partial_die (pdi, cu); + if (pdi->tag == DW_TAG_subprogram + || pdi->tag == DW_TAG_lexical_block) + add_partial_subprogram (pdi, lowpc, highpc, cu); + pdi = pdi->die_sibling; + } + } } /* See if we can figure out if the class lives in a namespace. We do @@ -5567,6 +5602,7 @@ && !is_type_tag_for_partial (abbrev->tag) && abbrev->tag != DW_TAG_enumerator && abbrev->tag != DW_TAG_subprogram + && abbrev->tag != DW_TAG_lexical_block && abbrev->tag != DW_TAG_variable && abbrev->tag != DW_TAG_namespace && abbrev->tag != DW_TAG_member) @@ -5689,13 +5725,19 @@ sizeof (struct partial_die_info)); /* For some DIEs we want to follow their children (if any). For C - we have no reason to follow the children of structures; for other + we have no reason to follow the children of structures; for other languages we have to, both so that we can get at method physnames - to infer fully qualified class names, and for DW_AT_specification. */ + to infer fully qualified class names, and for DW_AT_specification. + We need to scan the children of procedures and lexical blocks + because certain languages such as Ada allow the definition of + nested entities that could be interesting for the debugger, such + as nested procedures for instance. */ if (last_die->has_children && (load_all || last_die->tag == DW_TAG_namespace || last_die->tag == DW_TAG_enumeration_type + || last_die->tag == DW_TAG_subprogram + || last_die->tag == DW_TAG_lexical_block || (cu->language != language_c && (last_die->tag == DW_TAG_class_type || last_die->tag == DW_TAG_interface_type