2003-06-01 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index b5fd38982f3e670dadf074f450f23a529625fa90..182ee4fd064d476829c77290c1896cc32e2d8c57 100644 (file)
@@ -43,6 +43,7 @@
 #include "bcache.h"
 #include "dwarf2expr.h"
 #include "dwarf2loc.h"
+#include "cp-support.h"
 
 #include <fcntl.h>
 #include "gdb_string.h"
@@ -867,6 +868,10 @@ static void process_die (struct die_info *, struct objfile *,
 
 static char *dwarf2_linkage_name (struct die_info *);
 
+static char *dwarf2_name (struct die_info *die);
+
+static struct die_info *dwarf2_extension (struct die_info *die);
+
 static char *dwarf_tag_name (unsigned int);
 
 static char *dwarf_attr_name (unsigned int);
@@ -1498,7 +1503,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
          /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
             mst_text, objfile); */
          add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                              VAR_NAMESPACE, LOC_BLOCK,
+                              VAR_DOMAIN, LOC_BLOCK,
                               &objfile->global_psymbols,
                            0, pdi->lowpc + baseaddr, cu_language, objfile);
        }
@@ -1507,7 +1512,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
          /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
             mst_file_text, objfile); */
          add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                              VAR_NAMESPACE, LOC_BLOCK,
+                              VAR_DOMAIN, LOC_BLOCK,
                               &objfile->static_psymbols,
                            0, pdi->lowpc + baseaddr, cu_language, objfile);
        }
@@ -1532,7 +1537,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
            addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
          if (pdi->locdesc || pdi->has_type)
            add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                                VAR_NAMESPACE, LOC_STATIC,
+                                VAR_DOMAIN, LOC_STATIC,
                                 &objfile->global_psymbols,
                                 0, addr + baseaddr, cu_language, objfile);
        }
@@ -1545,7 +1550,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
          /*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
             mst_file_data, objfile); */
          add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                              VAR_NAMESPACE, LOC_STATIC,
+                              VAR_DOMAIN, LOC_STATIC,
                               &objfile->static_psymbols,
                               0, addr + baseaddr, cu_language, objfile);
        }
@@ -1553,7 +1558,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
     case DW_TAG_typedef:
     case DW_TAG_base_type:
       add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                          VAR_NAMESPACE, LOC_TYPEDEF,
+                          VAR_DOMAIN, LOC_TYPEDEF,
                           &objfile->static_psymbols,
                           0, (CORE_ADDR) 0, cu_language, objfile);
       break;
@@ -1566,7 +1571,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
       if (pdi->has_children == 0)
        return;
       add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                          STRUCT_NAMESPACE, LOC_TYPEDEF,
+                          STRUCT_DOMAIN, LOC_TYPEDEF,
                           &objfile->static_psymbols,
                           0, (CORE_ADDR) 0, cu_language, objfile);
 
@@ -1574,14 +1579,14 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile,
        {
          /* For C++, these implicitly act as typedefs as well. */
          add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                              VAR_NAMESPACE, LOC_TYPEDEF,
+                              VAR_DOMAIN, LOC_TYPEDEF,
                               &objfile->static_psymbols,
                               0, (CORE_ADDR) 0, cu_language, objfile);
        }
       break;
     case DW_TAG_enumerator:
       add_psymbol_to_list (pdi->name, strlen (pdi->name),
-                          VAR_NAMESPACE, LOC_CONST,
+                          VAR_DOMAIN, LOC_CONST,
                           &objfile->static_psymbols,
                           0, (CORE_ADDR) 0, cu_language, objfile);
       break;
@@ -1763,6 +1768,8 @@ process_die (struct die_info *die, struct objfile *objfile,
          of a function and make GDB `next' properly over inlined functions.  */
       break;
     case DW_TAG_lexical_block:
+    case DW_TAG_try_block:
+    case DW_TAG_catch_block:
       read_lexical_block_scope (die, objfile, cu_header);
       break;
     case DW_TAG_class_type:
@@ -1805,6 +1812,11 @@ process_die (struct die_info *die, struct objfile *objfile,
     case DW_TAG_common_inclusion:
       break;
     case DW_TAG_namespace:
+      if (!processing_has_namespace_info)
+       {
+         processing_has_namespace_info = 1;
+         processing_current_namespace = "";
+       }
       read_namespace (die, objfile, cu_header);
       break;
     case DW_TAG_imported_declaration:
@@ -1815,6 +1827,11 @@ process_die (struct die_info *die, struct objfile *objfile,
         shouldn't in the C++ case, but conceivably could in the
         Fortran case, so we'll have to replace this gdb_assert if
         Fortran compilers start generating that info.  */
+      if (!processing_has_namespace_info)
+       {
+         processing_has_namespace_info = 1;
+         processing_current_namespace = "";
+       }
       gdb_assert (!die->has_children);
       break;
     default:
@@ -3187,13 +3204,59 @@ read_common_block (struct die_info *die, struct objfile *objfile,
 
 /* Read a C++ namespace.  */
 
-/* FIXME: carlton/2002-10-16: For now, we don't actually do anything
-   useful with the namespace data: we just process its children.  */
-
 static void
 read_namespace (struct die_info *die, struct objfile *objfile,
                const struct comp_unit_head *cu_header)
 {
+  const char *previous_namespace = processing_current_namespace;
+  const char *name = NULL;
+  int is_anonymous;
+  struct die_info *current_die;
+
+  /* Loop through the extensions until we find a name.  */
+
+  for (current_die = die;
+       current_die != NULL;
+       current_die = dwarf2_extension (die))
+    {
+      name = dwarf2_name (current_die);
+      if (name != NULL)
+       break;
+    }
+
+  /* Is it an anonymous namespace?  */
+
+  is_anonymous = (name == NULL);
+  if (is_anonymous)
+    name = "(anonymous namespace)";
+
+  /* Now build the name of the current namespace.  */
+
+  if (previous_namespace[0] == '\0')
+    {
+      processing_current_namespace = name;
+    }
+  else
+    {
+      /* We need temp_name around because processing_current_namespace
+        is a const char *.  */
+      char *temp_name = alloca (strlen (previous_namespace)
+                               + 2 + strlen(name) + 1);
+      strcpy (temp_name, previous_namespace);
+      strcat (temp_name, "::");
+      strcat (temp_name, name);
+
+      processing_current_namespace = temp_name;
+    }
+
+  /* If it's an anonymous namespace that we're seeing for the first
+     time, add a using directive.  */
+
+  if (is_anonymous && dwarf_attr (die, DW_AT_extension) == NULL)
+    cp_add_using_directive (processing_current_namespace,
+                           strlen (previous_namespace),
+                           strlen (processing_current_namespace));
+
   if (die->has_children)
     {
       struct die_info *child_die = die->next;
@@ -3204,6 +3267,8 @@ read_namespace (struct die_info *die, struct objfile *objfile,
          child_die = sibling_die (child_die);
        }
     }
+
+  processing_current_namespace = previous_namespace;
 }
 
 /* Extract all information from a DW_TAG_pointer_type DIE and add to
@@ -4485,7 +4550,7 @@ set_cu_language (unsigned int lang)
     case DW_LANG_Pascal83:
     case DW_LANG_Modula2:
     default:
-      cu_language = language_unknown;
+      cu_language = language_minimal;
       break;
     }
   cu_language_defn = language_def (cu_language);
@@ -4815,8 +4880,8 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
                * lh->minimum_instruction_length;
              line += lh->line_base + (adj_opcode % lh->line_range);
              /* append row to matrix using current values */
-             address = check_cu_functions (address);
-             record_line (current_subfile, line, address);
+             record_line (current_subfile, line, 
+                          check_cu_functions (address));
              basic_block = 1;
            }
          else switch (op_code)
@@ -4862,8 +4927,8 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
                }
              break;
            case DW_LNS_copy:
-             address = check_cu_functions (address);
-             record_line (current_subfile, line, address);
+             record_line (current_subfile, line, 
+                          check_cu_functions (address));
              basic_block = 0;
              break;
            case DW_LNS_advance_pc:
@@ -5059,7 +5124,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
 
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
-      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
       SYMBOL_CLASS (sym) = LOC_STATIC;
       if (type != NULL)
        SYMBOL_TYPE (sym) = type;
@@ -5189,7 +5254,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
        case DW_TAG_union_type:
        case DW_TAG_enumeration_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
-         SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+         SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
          add_symbol_to_list (sym, list_in_scope);
 
          /* The semantics of C++ state that "struct foo { ... }" also
@@ -5201,7 +5266,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
              obstack_alloc (&objfile->symbol_obstack,
                             sizeof (struct symbol));
              *typedef_sym = *sym;
-             SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE;
+             SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
              if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
                TYPE_NAME (SYMBOL_TYPE (sym)) =
                  obsavestring (DEPRECATED_SYMBOL_NAME (sym),
@@ -5213,7 +5278,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
        case DW_TAG_typedef:
        case DW_TAG_base_type:
          SYMBOL_CLASS (sym) = LOC_TYPEDEF;
-         SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+         SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
          add_symbol_to_list (sym, list_in_scope);
          break;
        case DW_TAG_enumerator:
@@ -5256,8 +5321,10 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
                                                                   (sym)));
       SYMBOL_VALUE_BYTES (sym) = (char *)
        obstack_alloc (&objfile->symbol_obstack, cu_header->addr_size);
-      store_address (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size,
-                    DW_ADDR (attr));
+      /* NOTE: cagney/2003-05-09: In-lined store_address call with
+         it's body - store_unsigned_integer.  */
+      store_unsigned_integer (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size,
+                             DW_ADDR (attr));
       SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
       break;
     case DW_FORM_block1:
@@ -5670,6 +5737,43 @@ dwarf2_linkage_name (struct die_info *die)
   return NULL;
 }
 
+/* Get name of a die, return NULL if not found.  */
+
+static char *
+dwarf2_name (struct die_info *die)
+{
+  struct attribute *attr;
+
+  attr = dwarf_attr (die, DW_AT_name);
+  if (attr && DW_STRING (attr))
+    return DW_STRING (attr);
+  return NULL;
+}
+
+/* Return the die that this die in an extension of, or NULL if there
+   is none.  */
+
+static struct die_info *
+dwarf2_extension (struct die_info *die)
+{
+  struct attribute *attr;
+  struct die_info *extension_die;
+  unsigned int ref;
+
+  attr = dwarf_attr (die, DW_AT_extension);
+  if (attr == NULL)
+    return NULL;
+
+  ref = dwarf2_get_ref_die_offset (attr);
+  extension_die = follow_die_ref (ref);
+  if (!extension_die)
+    {
+      error ("Dwarf Error: Cannot find referent at offset %d.", ref);
+    }
+
+  return extension_die;
+}
+
 /* Convert a DIE tag into its string name.  */
 
 static char *
This page took 0.029381 seconds and 4 git commands to generate.