This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[10/10] use the referring CU's language


This last patch is a bit ugly.

When reading, gdb relies on the CU's language to make decisions about
various things, including naming.  However, a partial unit does not have
a DW_AT_language attribute.

This caused some test suite regressions because gdb constructed the name
of a class incorrectly.  In particular, the class was in a namespace in
a PU, but the code in dwarf2_compute_name only properly handles this
situation if the language is set.

So, this patch changes the DWARF reader to propagate a CU's language to
the PU, when reading the PU.

I think this ought to be safe, on the theory that DIEs will only be
pulled into a PU if they come from the compatible subset of the
languages in the referring CUs.  E.g., in the above example, C will
never make a namespace DIE, so we'll never see a C language CU referring
to a PU that would cause that problem.

I'm reasonably convinced that this is always true, but not totally
convinced.  I'm still looking for confounding examples.

There are two Plan B's available that I can think of:

1. Change the PU->symtab correspondence to be per-language.
   Then, read the PU once per referencing language.
   This will add a whole lot more hair to the DWARF reader.

2. If we detect multiple including languages, fall back to the slow
   method of re-reading the PU once per includer.

Tom

>From 947ddf1d84a3bcc22c95d4ee84de6b9f4125cc75 Mon Sep 17 00:00:00 2001
From: Tom Tromey <tromey@redhat.com>
Date: Tue, 24 Apr 2012 23:29:58 -0600
Subject: [PATCH 10/10] when reading a partial unit, use the referring CU's
 language

	* dwarf2read.c (struct dwarf2_queue_item) <pretend_language>: New
	field.
	(load_cu, dw2_do_instantiate_symtab, process_psymtab_comp_unit)
	(load_partial_comp_unit): Update.
	(queue_comp_unit): Add argument 'pretend_language'.
	(process_queue): Update.
	(psymtab_to_symtab_1): Skip dependencies that have users.
	(load_full_comp_unit): Add 'pretend_language' argument.
	(process_full_comp_unit): Add 'pretend_language' argument.  Set
	language on CU.
	(process_die): Update.
	(maybe_queue_comp_unit): Add 'pretend_language' argument.
	(follow_die_offset, follow_die_sig, read_signatured_type): Update.
	(prepare_one_comp_unit): Add 'pretend_language' argument.
---
 gdb/dwarf2read.c |   68 +++++++++++++++++++++++++++++++++--------------------
 1 files changed, 42 insertions(+), 26 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 0794e10..10fe834 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -778,6 +778,7 @@ struct field_info
 struct dwarf2_queue_item
 {
   struct dwarf2_per_cu_data *per_cu;
+  enum language pretend_language;
   struct dwarf2_queue_item *next;
 };
 
@@ -1247,7 +1248,8 @@ static void init_one_comp_unit (struct dwarf2_cu *cu,
 				struct dwarf2_per_cu_data *per_cu);
 
 static void prepare_one_comp_unit (struct dwarf2_cu *cu,
-				   struct die_info *comp_unit_die);
+				   struct die_info *comp_unit_die,
+				   enum language pretend_language);
 
 static void free_heap_comp_unit (void *);
 
@@ -1264,9 +1266,11 @@ static void create_all_comp_units (struct objfile *);
 
 static int create_all_type_units (struct objfile *);
 
-static void load_full_comp_unit (struct dwarf2_per_cu_data *);
+static void load_full_comp_unit (struct dwarf2_per_cu_data *,
+				 enum language);
 
-static void process_full_comp_unit (struct dwarf2_per_cu_data *);
+static void process_full_comp_unit (struct dwarf2_per_cu_data *,
+				    enum language);
 
 static void dwarf2_add_dependence (struct dwarf2_cu *,
 				   struct dwarf2_per_cu_data *);
@@ -1282,10 +1286,12 @@ static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
 
 static void dwarf2_release_queue (void *dummy);
 
-static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu);
+static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
+			     enum language pretend_language);
 
 static int maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
-				  struct dwarf2_per_cu_data *per_cu);
+				  struct dwarf2_per_cu_data *per_cu,
+				  enum language pretend_language);
 
 static void process_queue (void);
 
@@ -1802,7 +1808,7 @@ load_cu (struct dwarf2_per_cu_data *per_cu)
   if (per_cu->debug_types_section)
     load_full_type_unit (per_cu);
   else
-    load_full_comp_unit (per_cu);
+    load_full_comp_unit (per_cu, language_minimal);
 
   gdb_assert (per_cu->cu != NULL);
 
@@ -1822,7 +1828,7 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
       ? per_cu->v.quick->symtab == NULL
       : (per_cu->v.psymtab == NULL || !per_cu->v.psymtab->readin))
     {
-      queue_comp_unit (per_cu);
+      queue_comp_unit (per_cu, language_minimal);
       load_cu (per_cu);
     }
 
@@ -3529,7 +3535,7 @@ process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
       return;
     }
 
-  prepare_one_comp_unit (&cu, comp_unit_die);
+  prepare_one_comp_unit (&cu, comp_unit_die, language_minimal);
 
   /* Allocate a new partial symbol table structure.  */
   attr = dwarf2_attr (comp_unit_die, DW_AT_name, &cu);
@@ -3901,7 +3907,7 @@ load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu)
   info_ptr = read_full_die (&reader_specs, &comp_unit_die, info_ptr,
 			    &has_children);
 
-  prepare_one_comp_unit (cu, comp_unit_die);
+  prepare_one_comp_unit (cu, comp_unit_die, language_minimal);
 
   /* Check if comp unit has_children.
      If so, read the rest of the partial symbols from this comp unit.
@@ -4765,13 +4771,15 @@ dwarf2_psymtab_to_symtab (struct partial_symtab *pst)
 /* Add PER_CU to the queue.  */
 
 static void
-queue_comp_unit (struct dwarf2_per_cu_data *per_cu)
+queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
+		 enum language pretend_language)
 {
   struct dwarf2_queue_item *item;
 
   per_cu->queued = 1;
   item = xmalloc (sizeof (*item));
   item->per_cu = per_cu;
+  item->pretend_language = pretend_language;
   item->next = NULL;
 
   if (dwarf2_queue == NULL)
@@ -4796,7 +4804,7 @@ process_queue (void)
       if (dwarf2_per_objfile->using_index
 	  ? !item->per_cu->v.quick->symtab
 	  : (item->per_cu->v.psymtab && !item->per_cu->v.psymtab->readin))
-	process_full_comp_unit (item->per_cu);
+	process_full_comp_unit (item->per_cu, item->pretend_language);
 
       item->per_cu->queued = 0;
       next_item = item->next;
@@ -4848,7 +4856,8 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
     return;
 
   for (i = 0; i < pst->number_of_dependencies; i++)
-    if (!pst->dependencies[i]->readin)
+    if (!pst->dependencies[i]->readin
+	&& pst->dependencies[i]->users == NULL)
       {
         /* Inform about additional files that need to be read in.  */
         if (info_verbose)
@@ -4881,7 +4890,8 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
 /* Load the DIEs associated with PER_CU into memory.  */
 
 static void
-load_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
+load_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
+		     enum language pretend_language)
 {
   struct objfile *objfile = per_cu->objfile;
   bfd *abfd = objfile->obfd;
@@ -4939,7 +4949,7 @@ load_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
      all CUs needed for references have been loaded yet, and symbol
      table processing isn't initialized.  But we have to set the CU language,
      or we won't be able to build types correctly.  */
-  prepare_one_comp_unit (cu, cu->dies);
+  prepare_one_comp_unit (cu, cu->dies, pretend_language);
 
   /* Similarly, if we do not read the producer, we can not apply
      producer-specific interpretation.  */
@@ -5118,7 +5128,8 @@ process_cu_includes (void)
    already been loaded into memory.  */
 
 static void
-process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
+process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
+			enum language pretend_language)
 {
   struct dwarf2_cu *cu = per_cu->cu;
   struct objfile *objfile = per_cu->objfile;
@@ -5135,6 +5146,9 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
 
   cu->list_in_scope = &file_symbols;
 
+  cu->language = pretend_language;
+  cu->language_defn = language_def (cu->language);
+
   /* Do line number decoding in read_file_scope () */
   process_die (cu->dies, cu);
 
@@ -5292,8 +5306,8 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
 	    per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
 
 	    /* Queue the unit, if needed.  */
-	    if (maybe_queue_comp_unit (cu, per_cu))
-	      load_full_comp_unit (per_cu);
+	    if (maybe_queue_comp_unit (cu, per_cu, cu->language))
+	      load_full_comp_unit (per_cu, cu->language);
 
 	    VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
 			   per_cu);
@@ -14509,7 +14523,8 @@ dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
 
 static int
 maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
-		       struct dwarf2_per_cu_data *per_cu)
+		       struct dwarf2_per_cu_data *per_cu,
+		       enum language pretend_language)
 {
   /* We may arrive here during partial symbol reading, if we need full
      DIEs to process an unusual case (e.g. template arguments).  Do
@@ -14538,7 +14553,7 @@ maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
     }
 
   /* Add it to the queue.  */
-  queue_comp_unit (per_cu);
+  queue_comp_unit (per_cu, pretend_language);
 
   return 1;
 }
@@ -14597,8 +14612,8 @@ follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
       per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
 
       /* If necessary, add it to the queue and load its DIEs.  */
-      if (maybe_queue_comp_unit (cu, per_cu))
-	load_full_comp_unit (per_cu);
+      if (maybe_queue_comp_unit (cu, per_cu, cu->language))
+	load_full_comp_unit (per_cu, cu->language);
 
       target_cu = per_cu->cu;
     }
@@ -14606,7 +14621,7 @@ follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
     {
       /* We're loading full DIEs during partial symbol reading.  */
       gdb_assert (dwarf2_per_objfile->reading_partial_symbols);
-      load_full_comp_unit (cu->per_cu);
+      load_full_comp_unit (cu->per_cu, language_minimal);
     }
 
   *ref_cu = target_cu;
@@ -14738,7 +14753,7 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr,
 
   /* If necessary, add it to the queue and load its DIEs.  */
 
-  if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu))
+  if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu, language_minimal))
     read_signatured_type (sig_type);
 
   gdb_assert (sig_type->per_cu.cu != NULL);
@@ -14863,7 +14878,7 @@ read_signatured_type (struct signatured_type *sig_type)
      all CUs needed for references have been loaded yet, and symbol
      table processing isn't initialized.  But we have to set the CU language,
      or we won't be able to build types correctly.  */
-  prepare_one_comp_unit (cu, cu->dies);
+  prepare_one_comp_unit (cu, cu->dies, language_minimal);
 
   do_cleanups (back_to);
 
@@ -16306,7 +16321,8 @@ init_one_comp_unit (struct dwarf2_cu *cu, struct dwarf2_per_cu_data *per_cu)
 /* Initialize basic fields of dwarf_cu CU according to DIE COMP_UNIT_DIE.  */
 
 static void
-prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die)
+prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
+		       enum language pretend_language)
 {
   struct attribute *attr;
 
@@ -16316,7 +16332,7 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die)
     set_cu_language (DW_UNSND (attr), cu);
   else
     {
-      cu->language = language_minimal;
+      cu->language = pretend_language;
       cu->language_defn = language_def (cu->language);
     }
 }
-- 
1.7.7.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]