* dwarf2read.c (add_partial_subprogram): New procedure.
authorJoel Brobecker <brobecker@gnat.com>
Sat, 13 Sep 2008 22:19:51 +0000 (22:19 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Sat, 13 Sep 2008 22:19:51 +0000 (22:19 +0000)
        (scan_partial_symbols): Use it.
        (load_partial_dies): Read in children of subprogram and lexical
        blocks for Ada compilation units.

gdb/ChangeLog
gdb/dwarf2read.c

index 35985a520817c566e2186cac2dad07b0ddc2e4fb..4b458bb69d45952840c992ceeec5c99f59c2729d 100644 (file)
@@ -1,3 +1,10 @@
+2008-09-13  Joel Brobecker  <brobecker@adacore.com>
+
+        * dwarf2read.c (add_partial_subprogram): New procedure.
+        (scan_partial_symbols): Use it.
+        (load_partial_dies): Read in children of subprogram and lexical
+        blocks for Ada compilation units.
+
 2008-09-13  Tom Tromey  <tromey@redhat.com>
 
        * symfile.c (build_id_verify): Free 'found'.
index a62bd28afcf7cc627b67485bcec8936fc68cd8db..2a4acb98a43d60ac27eac8d9d92eba9630a1c3d2 100644 (file)
@@ -757,6 +757,10 @@ static void add_partial_namespace (struct partial_die_info *pdi,
 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,
                                      bfd *abfd,
@@ -1771,21 +1775,7 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
          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:
@@ -2135,6 +2125,51 @@ add_partial_namespace (struct partial_die_info *pdi,
     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
    this by looking for a member function; its demangled name will
    contain namespace info, if there is any.  */
@@ -5555,6 +5590,7 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab,
          && !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)
@@ -5677,9 +5713,14 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab,
                                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.
+
+        For Ada, we need to scan the children of subprograms and lexical
+        blocks as well because Ada allows the definition of nested
+        entities that could be interesting for the debugger, such as
+        nested subprograms for instance.  */
       if (last_die->has_children
          && (load_all
              || last_die->tag == DW_TAG_namespace
@@ -5688,7 +5729,10 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab,
                  && (last_die->tag == DW_TAG_class_type
                      || last_die->tag == DW_TAG_interface_type
                      || last_die->tag == DW_TAG_structure_type
-                     || last_die->tag == DW_TAG_union_type))))
+                     || last_die->tag == DW_TAG_union_type))
+             || (cu->language == language_ada
+                 && (last_die->tag == DW_TAG_subprogram
+                     || last_die->tag == DW_TAG_lexical_block))))
        {
          nesting_level++;
          parent_die = last_die;