* value.c (value_fn_field): Constify.
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index 0ca9532f70ecf4c6270ecc582ae984d3ffc7c184..562361eab1d67d68154b50c5d17a212d935cf8a2 100644 (file)
@@ -149,6 +149,9 @@ DEF_VEC_I (offset_type);
    a comment by the code that writes the index.  */
 struct mapped_index
 {
+  /* Index data format version.  */
+  int version;
+
   /* The total length of the buffer.  */
   off_t total_size;
 
@@ -401,6 +404,13 @@ struct dwarf2_cu
      DIEs for namespaces, we don't need to try to infer them
      from mangled names.  */
   unsigned int has_namespace_info : 1;
+
+  /* This CU references .debug_loc.  See the symtab->locations_valid field.
+     This test is imperfect as there may exist optimized debug code not using
+     any location list and still facing inlining issues if handled as
+     unoptimized code.  For a future better test see GCC PR other/32998.  */
+
+  unsigned int has_loclist : 1;
 };
 
 /* Persistent data held for a compilation unit, even when not
@@ -1972,17 +1982,23 @@ create_addrmap_from_index (struct objfile *objfile, struct mapped_index *index)
    SYMBOL_HASH_NEXT, but we keep a separate copy to maintain control over the
    implementation.  This is necessary because the hash function is tied to the
    format of the mapped index file.  The hash values do not have to match with
-   SYMBOL_HASH_NEXT.  */
+   SYMBOL_HASH_NEXT.
+   
+   Use INT_MAX for INDEX_VERSION if you generate the current index format.  */
 
 static hashval_t
-mapped_index_string_hash (const void *p)
+mapped_index_string_hash (int index_version, const void *p)
 {
   const unsigned char *str = (const unsigned char *) p;
   hashval_t r = 0;
   unsigned char c;
 
   while ((c = *str++) != 0)
-    r = r * 67 + c - 113;
+    {
+      if (index_version >= 5)
+       c = tolower (c);
+      r = r * 67 + c - 113;
+    }
 
   return r;
 }
@@ -1998,6 +2014,7 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
   struct cleanup *back_to = make_cleanup (null_cleanup, 0);
   offset_type hash;
   offset_type slot, step;
+  int (*cmp) (const char *, const char *);
 
   if (current_language->la_language == language_cplus
       || current_language->la_language == language_java
@@ -2020,9 +2037,17 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
        }
     }
 
-  hash = mapped_index_string_hash (name);
+  /* Index version 4 did not support case insensitive searches.  But the
+     indexes for case insensitive languages are built in lowercase, therefore
+     simulate our NAME being searched is also lowercased.  */
+  hash = mapped_index_string_hash ((index->version == 4
+                                    && case_sensitivity == case_sensitive_off
+                                   ? 5 : index->version),
+                                  name);
+
   slot = hash & (index->symbol_table_slots - 1);
   step = ((hash * 17) & (index->symbol_table_slots - 1)) | 1;
+  cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp);
 
   for (;;)
     {
@@ -2036,7 +2061,7 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
        }
 
       str = index->constant_pool + MAYBE_SWAP (index->symbol_table[i]);
-      if (!strcmp (name, str))
+      if (!cmp (name, str))
        {
          *vec_out = (offset_type *) (index->constant_pool
                                      + MAYBE_SWAP (index->symbol_table[i + 1]));
@@ -2080,15 +2105,17 @@ dwarf2_read_index (struct objfile *objfile)
   /* Versions earlier than 3 emitted every copy of a psymbol.  This
      causes the index to behave very poorly for certain requests.  Version 3
      contained incomplete addrmap.  So, it seems better to just ignore such
-     indices.  */
+     indices.  Index version 4 uses a different hash function than index
+     version 5 and later.  */
   if (version < 4)
     return 0;
   /* Indexes with higher version than the one supported by GDB may be no
      longer backward compatible.  */
-  if (version > 4)
+  if (version > 5)
     return 0;
 
   map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
+  map->version = version;
   map->total_size = dwarf2_per_objfile->gdb_index.size;
 
   metadata = (offset_type *) (addr + sizeof (offset_type));
@@ -4582,14 +4609,52 @@ compute_delayed_physnames (struct dwarf2_cu *cu)
   struct delayed_method_info *mi;
   for (i = 0; VEC_iterate (delayed_method_info, cu->method_list, i, mi) ; ++i)
     {
-      char *physname;
+      const char *physname;
       struct fn_fieldlist *fn_flp
        = &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index);
-      physname = (char *) dwarf2_physname ((char *) mi->name, mi->die, cu);
+      physname = dwarf2_physname ((char *) mi->name, mi->die, cu);
       fn_flp->fn_fields[mi->index].physname = physname ? physname : "";
     }
 }
 
+/* Check for GCC >= 4.0.  */
+
+static int
+producer_is_gcc_ge_4_0 (struct dwarf2_cu *cu)
+{
+  const char *cs;
+  int major, minor;
+
+  if (cu->producer == NULL)
+    {
+      /* For unknown compilers expect their behavior is not compliant.  For GCC
+        this case can also happen for -gdwarf-4 type units supported since
+        gcc-4.5.  */
+
+      return 0;
+    }
+
+  /* Skip any identifier after "GNU " - such as "C++" or "Java".  */
+
+  if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0)
+    {
+      /* For non-GCC compilers expect their behavior is not compliant.  */
+
+      return 0;
+    }
+  cs = &cu->producer[strlen ("GNU ")];
+  while (*cs && !isdigit (*cs))
+    cs++;
+  if (sscanf (cs, "%d.%d", &major, &minor) != 2)
+    {
+      /* Not recognized as GCC.  */
+
+      return 0;
+    }
+
+  return major >= 4;
+}
+
 /* Generate full symbol information for PST and CU, whose DIEs have
    already been loaded into memory.  */
 
@@ -4629,13 +4694,26 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
 
   symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
 
-  /* Set symtab language to language from DW_AT_language.
-     If the compilation is from a C file generated by language preprocessors,
-     do not set the language if it was already deduced by start_subfile.  */
-  if (symtab != NULL
-      && !(cu->language == language_c && symtab->language != language_c))
+  if (symtab != NULL)
     {
-      symtab->language = cu->language;
+      /* Set symtab language to language from DW_AT_language.  If the
+        compilation is from a C file generated by language preprocessors, do
+        not set the language if it was already deduced by start_subfile.  */
+      if (!(cu->language == language_c && symtab->language != language_c))
+       symtab->language = cu->language;
+
+      /* GCC-4.0 has started to support -fvar-tracking.  GCC-3.x still can
+        produce DW_AT_location with location lists but it can be possibly
+        invalid without -fvar-tracking.
+
+        For -gdwarf-4 type units LOCATIONS_VALID indication is fortunately not
+        needed, it would be wrong due to missing DW_AT_producer there.
+
+        Still one can confuse GDB by using non-standard GCC compilation
+        options - this waits on GCC PR other/32998 (-frecord-gcc-switches).
+        */ 
+      if (cu->has_loclist && producer_is_gcc_ge_4_0 (cu))
+       symtab->locations_valid = 1;
     }
 
   if (dwarf2_per_objfile->using_index)
@@ -6287,6 +6365,41 @@ dwarf2_default_access_attribute (struct die_info *die, struct dwarf2_cu *cu)
     }
 }
 
+/* Look for DW_AT_data_member_location.  Set *OFFSET to the byte
+   offset.  If the attribute was not found return 0, otherwise return
+   1.  If it was found but could not properly be handled, set *OFFSET
+   to 0.  */
+
+static int
+handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
+                            LONGEST *offset)
+{
+  struct attribute *attr;
+
+  attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
+  if (attr != NULL)
+    {
+      *offset = 0;
+
+      /* Note that we do not check for a section offset first here.
+        This is because DW_AT_data_member_location is new in DWARF 4,
+        so if we see it, we can assume that a constant form is really
+        a constant and not a section offset.  */
+      if (attr_form_is_constant (attr))
+       *offset = dwarf2_get_attr_constant_value (attr, 0);
+      else if (attr_form_is_section_offset (attr))
+       dwarf2_complex_location_expr_complaint ();
+      else if (attr_form_is_block (attr))
+       *offset = decode_locdesc (DW_BLOCK (attr), cu);
+      else
+       dwarf2_complex_location_expr_complaint ();
+
+      return 1;
+    }
+
+  return 0;
+}
+
 /* Add an aggregate field to the field list.  */
 
 static void
@@ -6335,6 +6448,8 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   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.  */
@@ -6354,22 +6469,8 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
        }
 
       /* Get bit offset of field.  */
-      attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
-      if (attr)
-       {
-          int byte_offset = 0;
-
-          if (attr_form_is_section_offset (attr))
-           dwarf2_complex_location_expr_complaint ();
-          else if (attr_form_is_constant (attr))
-            byte_offset = dwarf2_get_attr_constant_value (attr, 0);
-          else if (attr_form_is_block (attr))
-            byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
-         else
-           dwarf2_complex_location_expr_complaint ();
-
-          SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
-       }
+      if (handle_data_member_location (die, cu, &offset))
+       SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
       attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
       if (attr)
        {
@@ -6472,23 +6573,11 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
     }
   else if (die->tag == DW_TAG_inheritance)
     {
-      /* C++ base class field.  */
-      attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
-      if (attr)
-       {
-          int byte_offset = 0;
-
-          if (attr_form_is_section_offset (attr))
-           dwarf2_complex_location_expr_complaint ();
-          else if (attr_form_is_constant (attr))
-            byte_offset = dwarf2_get_attr_constant_value (attr, 0);
-          else if (attr_form_is_block (attr))
-            byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
-         else
-           dwarf2_complex_location_expr_complaint ();
+      LONGEST offset;
 
-          SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
-       }
+      /* C++ base class field.  */
+      if (handle_data_member_location (die, cu, &offset))
+       SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
       FIELD_BITSIZE (*fp) = 0;
       FIELD_TYPE (*fp) = die_type (die, cu);
       FIELD_NAME (*fp) = type_name_no_tag (fp->type);
@@ -6703,7 +6792,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
     }
   else
     {
-      char *physname = (char *) dwarf2_physname (fieldname, die, cu);
+      const char *physname = dwarf2_physname (fieldname, die, cu);
       fnp->physname = physname ? physname : "";
     }
 
@@ -7598,22 +7687,13 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
       child_die = die->child;
       while (child_die && child_die->tag)
        {
+         LONGEST offset;
+
          sym = new_symbol (child_die, NULL, cu);
-         attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu);
-         if (sym != NULL && attr != NULL)
+         if (sym != NULL
+             && handle_data_member_location (child_die, cu, &offset))
            {
-             CORE_ADDR byte_offset = 0;
-
-             if (attr_form_is_section_offset (attr))
-               dwarf2_complex_location_expr_complaint ();
-             else if (attr_form_is_constant (attr))
-               byte_offset = dwarf2_get_attr_constant_value (attr, 0);
-             else if (attr_form_is_block (attr))
-               byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
-             else
-               dwarf2_complex_location_expr_complaint ();
-
-             SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset;
+             SYMBOL_VALUE_ADDRESS (sym) = base + offset;
              add_symbol_to_list (sym, &global_symbols);
            }
          child_die = sibling_die (child_die);
@@ -8926,7 +9006,7 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
       if (parent_die == NULL
          && part_die->has_specification == 0
          && part_die->is_declaration == 0
-         && (part_die->tag == DW_TAG_typedef
+         && ((part_die->tag == DW_TAG_typedef && !part_die->has_children)
              || part_die->tag == DW_TAG_base_type
              || part_die->tag == DW_TAG_subrange_type))
        {
@@ -8939,6 +9019,20 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
          continue;
        }
 
+      /* The exception for DW_TAG_typedef with has_children above is
+        a workaround of GCC PR debug/47510.  In the case of this complaint
+        type_name_no_tag_or_error will error on such types later.
+
+        GDB skipped children of DW_TAG_typedef by the shortcut above and then
+        it could not find the child DIEs referenced later, this is checked
+        above.  In correct DWARF DW_TAG_typedef should have no children.  */
+
+      if (part_die->tag == DW_TAG_typedef && part_die->has_children)
+       complaint (&symfile_complaints,
+                  _("DW_TAG_typedef has childen - GCC PR debug/47510 bug "
+                    "- DIE at 0x%x [in module %s]"),
+                  part_die->offset, cu->objfile->name);
+
       /* If we're at the second level, and we're an enumerator, and
         our parent has no specification (meaning possibly lives in a
         namespace elsewhere), then we can add the partial symbol now
@@ -10934,6 +11028,9 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
 
   dwarf2_symbol_mark_computed (attr, sym, cu);
   SYMBOL_CLASS (sym) = LOC_COMPUTED;
+
+  if (SYMBOL_COMPUTED_OPS (sym) == &dwarf2_loclist_funcs)
+    cu->has_loclist = 1;
 }
 
 /* Given a pointer to a DWARF information entry, figure out if we need
@@ -12997,6 +13094,18 @@ dwarf_stack_op_name (unsigned op)
       return "DW_OP_GNU_uninit";
     case DW_OP_GNU_implicit_pointer:
       return "DW_OP_GNU_implicit_pointer";
+    case DW_OP_GNU_entry_value:
+      return "DW_OP_GNU_entry_value";
+    case DW_OP_GNU_const_type:
+      return "DW_OP_GNU_const_type";
+    case DW_OP_GNU_regval_type:
+      return "DW_OP_GNU_regval_type";
+    case DW_OP_GNU_deref_type:
+      return "DW_OP_GNU_deref_type";
+    case DW_OP_GNU_convert:
+      return "DW_OP_GNU_convert";
+    case DW_OP_GNU_reinterpret:
+      return "DW_OP_GNU_reinterpret";
     default:
       return NULL;
     }
@@ -13555,6 +13664,17 @@ dwarf2_fetch_die_location_block (unsigned int offset,
   return retval;
 }
 
+/* Return the type of the DIE at DIE_OFFSET in the CU named by
+   PER_CU.  */
+
+struct type *
+dwarf2_get_die_type (unsigned int die_offset,
+                    struct dwarf2_per_cu_data *per_cu)
+{
+  dw2_setup (per_cu->objfile);
+  return get_die_type_at_offset (die_offset, per_cu);
+}
+
 /* Follow the signature attribute ATTR in SRC_DIE.
    On entry *REF_CU is the CU of SRC_DIE.
    On exit *REF_CU is the CU of the result.  */
@@ -15256,13 +15376,16 @@ struct strtab_entry
   const char *str;
 };
 
-/* Hash function for a strtab_entry.  */
+/* Hash function for a strtab_entry.
+
+   Function is used only during write_hash_table so no index format backward
+   compatibility is needed.  */
 
 static hashval_t
 hash_strtab_entry (const void *e)
 {
   const struct strtab_entry *entry = e;
-  return mapped_index_string_hash (entry->str);
+  return mapped_index_string_hash (INT_MAX, entry->str);
 }
 
 /* Equality function for a strtab_entry.  */
@@ -15400,12 +15523,15 @@ cleanup_mapped_symtab (void *p)
 }
 
 /* Find a slot in SYMTAB for the symbol NAME.  Returns a pointer to
-   the slot.  */
+   the slot.
+   
+   Function is used only during write_hash_table so no index format backward
+   compatibility is needed.  */
 
 static struct symtab_index_entry **
 find_slot (struct mapped_symtab *symtab, const char *name)
 {
-  offset_type index, step, hash = mapped_index_string_hash (name);
+  offset_type index, step, hash = mapped_index_string_hash (INT_MAX, name);
 
   index = hash & (symtab->size - 1);
   step = ((hash * 17) & (symtab->size - 1)) | 1;
@@ -15934,7 +16060,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
   total_len = size_of_contents;
 
   /* The version number.  */
-  val = MAYBE_SWAP (4);
+  val = MAYBE_SWAP (5);
   obstack_grow (&contents, &val, sizeof (val));
 
   /* The offset of the CU list from the start of the file.  */
This page took 0.043731 seconds and 4 git commands to generate.