* dwarf2read.c (recursively_write_psymbols): New function.
authorTom Tromey <tromey@redhat.com>
Thu, 10 May 2012 20:17:51 +0000 (20:17 +0000)
committerTom Tromey <tromey@redhat.com>
Thu, 10 May 2012 20:17:51 +0000 (20:17 +0000)
(write_psymtabs_to_index): Use it.

* 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 a user.
(load_partial_comp_unit_reader): Give meaning to the 'data'
argument.
(load_full_comp_unit): Add 'pretend_language' argument.
(process_full_comp_unit): Add 'pretend_language' argument.  Set
language on CU.
(process_imported_unit_die, read_file_scope, read_type_unit_scope):
Update.
(maybe_queue_comp_unit): Add 'pretend_language' argument.
(follow_die_offset, follow_die_sig, read_signatured_type_reader):
Update.
(prepare_one_comp_unit): Add 'pretend_language' argument.

* dwarf2read.c: (dwarf2_per_cu_ptr): New typedef.
(struct dwarf2_per_objfile) <just_read_cus>: New field.
(struct dwarf2_per_cu_data) <imported_symtabs>: New field.
(dw2_do_instantiate_symtab): Check whether symtab was read in
before queueing.
(dw2_instantiate_symtab): Add assertion.  Call
process_cu_includes.
(process_psymtab_comp_unit): Compute 'dependencies' for psymtab.
(partial_symtab_p): New typedef.
(set_partial_user): New function.
(dwarf2_build_psymtabs_hard): Use set_partial_user.
(scan_partial_symbols): Add imported CU to imported_symtabs.
(dwarf2_psymtab_to_symtab): Call process_cu_includes.
(psymtab_to_symtab_1): Do nothing if psymtab is readin.
(get_symtab, recursively_compute_inclusions)
(compute_symtab_includes, process_cu_includes)
(process_imported_unit_die): New functions.
(process_die) <DW_TAG_imported_unit>: New case.
(dwarf2_per_objfile_free): Free 'imported_symtabs'.

* dwarf2read.c (struct dwarf2_per_cu_data) <psymtab>: Update
comment.
(struct partial_die_info) <locdesc>: Remove.
<d>: New field.
(process_psymtab_comp_unit): Add 'read_partial' argument.
Update.
(process_type_comp_unit, dwarf2_build_psymtabs_hard): Update.
(scan_partial_symbols): Handle DW_TAG_imported_unit.
(add_partial_symbol): Update.
(process_die): Handle DW_TAG_partial_unit.
(read_file_scope): Update comment.
(load_partial_dies): Handle DW_TAG_imported_unit.
(read_partial_die): Handle DW_TAG_partial_unit, DW_AT_import.
(determine_prefix, dwarf2_name): Handle DW_TAG_partial_unit.

gdb/ChangeLog
gdb/dwarf2read.c

index 31cf97ba77f9f8e4b463760f5e57f2e8cc30c770..f79f1ef1f0ca1dce3aa2a57b1f27a6207499d3a7 100644 (file)
@@ -1,3 +1,62 @@
+2012-05-10  Tom Tromey  <tromey@redhat.com>
+
+       * dwarf2read.c (recursively_write_psymbols): New function.
+       (write_psymtabs_to_index): Use it.
+
+       * 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 a user.
+       (load_partial_comp_unit_reader): Give meaning to the 'data'
+       argument.
+       (load_full_comp_unit): Add 'pretend_language' argument.
+       (process_full_comp_unit): Add 'pretend_language' argument.  Set
+       language on CU.
+       (process_imported_unit_die, read_file_scope, read_type_unit_scope):
+       Update.
+       (maybe_queue_comp_unit): Add 'pretend_language' argument.
+       (follow_die_offset, follow_die_sig, read_signatured_type_reader):
+       Update.
+       (prepare_one_comp_unit): Add 'pretend_language' argument.
+
+       * dwarf2read.c: (dwarf2_per_cu_ptr): New typedef.
+       (struct dwarf2_per_objfile) <just_read_cus>: New field.
+       (struct dwarf2_per_cu_data) <imported_symtabs>: New field.
+       (dw2_do_instantiate_symtab): Check whether symtab was read in
+       before queueing.
+       (dw2_instantiate_symtab): Add assertion.  Call
+       process_cu_includes.
+       (process_psymtab_comp_unit): Compute 'dependencies' for psymtab.
+       (partial_symtab_p): New typedef.
+       (set_partial_user): New function.
+       (dwarf2_build_psymtabs_hard): Use set_partial_user.
+       (scan_partial_symbols): Add imported CU to imported_symtabs.
+       (dwarf2_psymtab_to_symtab): Call process_cu_includes.
+       (psymtab_to_symtab_1): Do nothing if psymtab is readin.
+       (get_symtab, recursively_compute_inclusions)
+       (compute_symtab_includes, process_cu_includes)
+       (process_imported_unit_die): New functions.
+       (process_die) <DW_TAG_imported_unit>: New case.
+       (dwarf2_per_objfile_free): Free 'imported_symtabs'.
+
+       * dwarf2read.c (struct dwarf2_per_cu_data) <psymtab>: Update
+       comment.
+       (struct partial_die_info) <locdesc>: Remove.
+       <d>: New field.
+       (process_psymtab_comp_unit): Add 'read_partial' argument.
+       Update.
+       (process_type_comp_unit, dwarf2_build_psymtabs_hard): Update.
+       (scan_partial_symbols): Handle DW_TAG_imported_unit.
+       (add_partial_symbol): Update.
+       (process_die): Handle DW_TAG_partial_unit.
+       (read_file_scope): Update comment.
+       (load_partial_dies): Handle DW_TAG_imported_unit.
+       (read_partial_die): Handle DW_TAG_partial_unit, DW_AT_import.
+       (determine_prefix, dwarf2_name): Handle DW_TAG_partial_unit.
+
 2012-05-10  Tom Tromey  <tromey@redhat.com>
 
        * cc-with-dwz.sh: New file.
index 8964b00b4689d918a404d31fa0c5713e35b26b45..f06dea68e690f8092f07b7566a9d6a9f30c49d24 100644 (file)
@@ -148,6 +148,9 @@ struct mapped_index
   const char *constant_pool;
 };
 
+typedef struct dwarf2_per_cu_data *dwarf2_per_cu_ptr;
+DEF_VEC_P (dwarf2_per_cu_ptr);
+
 /* Collection of data recorded per objfile.
    This hangs off of dwarf2_objfile_data_key.  */
 
@@ -221,6 +224,9 @@ struct dwarf2_per_objfile
      This is NULL if not allocated yet.
      The mapping is done via (CU/TU signature + DIE offset) -> type.  */
   htab_t die_type_hash;
+
+  /* The CUs we recently read.  */
+  VEC (dwarf2_per_cu_ptr) *just_read_cus;
 };
 
 static struct dwarf2_per_objfile *dwarf2_per_objfile;
@@ -483,13 +489,18 @@ struct dwarf2_per_cu_data
   union
   {
     /* The partial symbol table associated with this compilation unit,
-       or NULL for partial units (which do not have an associated
-       symtab).  */
+       or NULL for unread partial units.  */
     struct partial_symtab *psymtab;
 
     /* Data needed by the "quick" functions.  */
     struct dwarf2_per_cu_quick_data *quick;
   } v;
+
+  /* The CUs we import using DW_TAG_imported_unit.  This is filled in
+     while reading psymtabs, used to compute the psymtab dependencies,
+     and then cleared.  Then it is filled in again while reading full
+     symbols, and only deleted when the objfile is destroyed.  */
+  VEC (dwarf2_per_cu_ptr) *imported_symtabs;
 };
 
 /* Entry in the signatured_types hash table.  */
@@ -695,8 +706,15 @@ struct partial_die_info
        when this compilation unit leaves the cache.  */
     char *scope;
 
-    /* The location description associated with this DIE, if any.  */
-    struct dwarf_block *locdesc;
+    /* Some data associated with the partial DIE.  The tag determines
+       which field is live.  */
+    union
+    {
+      /* The location description associated with this DIE, if any.  */
+      struct dwarf_block *locdesc;
+      /* The offset of an import, for DW_TAG_imported_unit.  */
+      sect_offset offset;
+    } d;
 
     /* If HAS_PC_INFO, the PC range associated with this DIE.  */
     CORE_ADDR lowpc;
@@ -887,6 +905,7 @@ struct field_info
 struct dwarf2_queue_item
 {
   struct dwarf2_per_cu_data *per_cu;
+  enum language pretend_language;
   struct dwarf2_queue_item *next;
 };
 
@@ -1346,7 +1365,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 *);
 
@@ -1363,9 +1383,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 *);
@@ -1381,7 +1403,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,
+                                 enum language pretend_language);
 
 static void process_queue (void);
 
@@ -1407,7 +1434,7 @@ static void init_cutu_and_read_dies_simple
 
 static htab_t allocate_signatured_type_table (struct objfile *objfile);
 
-static void process_psymtab_comp_unit (struct dwarf2_per_cu_data *);
+static void process_psymtab_comp_unit (struct dwarf2_per_cu_data *, int);
 
 static htab_t allocate_dwo_unit_table (struct objfile *objfile);
 
@@ -1421,6 +1448,8 @@ static void free_dwo_file_cleanup (void *);
 
 static void munmap_section_buffer (struct dwarf2_section_info *);
 
+static void process_cu_includes (void);
+
 #if WORDS_BIGENDIAN
 
 /* Convert VALUE between big- and little-endian.  */
@@ -1926,7 +1955,7 @@ load_cu (struct dwarf2_per_cu_data *per_cu)
   if (per_cu->is_debug_types)
     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);
 
@@ -1942,9 +1971,13 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
 
   back_to = make_cleanup (dwarf2_release_queue, NULL);
 
-  queue_comp_unit (per_cu);
-
-  load_cu (per_cu);
+  if (dwarf2_per_objfile->using_index
+      ? per_cu->v.quick->symtab == NULL
+      : (per_cu->v.psymtab == NULL || !per_cu->v.psymtab->readin))
+    {
+      queue_comp_unit (per_cu, language_minimal);
+      load_cu (per_cu);
+    }
 
   process_queue ();
 
@@ -1962,11 +1995,13 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
 static struct symtab *
 dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
 {
+  gdb_assert (dwarf2_per_objfile->using_index);
   if (!per_cu->v.quick->symtab)
     {
       struct cleanup *back_to = make_cleanup (free_cached_comp_units, NULL);
       increment_reading_symtab ();
       dw2_do_instantiate_symtab (per_cu);
+      process_cu_includes ();
       do_cleanups (back_to);
     }
   return per_cu->v.quick->symtab;
@@ -4014,11 +4049,14 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
   struct partial_symtab *pst;
   int has_pc_info;
   const char *filename;
+  int *want_partial_unit_ptr = data;
 
-  if (comp_unit_die->tag == DW_TAG_partial_unit)
+  if (comp_unit_die->tag == DW_TAG_partial_unit
+      && (want_partial_unit_ptr == NULL
+         || !*want_partial_unit_ptr))
     return;
 
-  prepare_one_comp_unit (cu, comp_unit_die);
+  prepare_one_comp_unit (cu, comp_unit_die, language_minimal);
 
   cu->list_in_scope = &file_symbols;
 
@@ -4100,6 +4138,26 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
     (objfile->static_psymbols.list + pst->statics_offset);
   sort_pst_symbols (pst);
 
+  if (!VEC_empty (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs))
+    {
+      int i;
+      int len = VEC_length (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
+      struct dwarf2_per_cu_data *iter;
+
+      /* Fill in 'dependencies' here; we fill in 'users' in a
+        post-pass.  */
+      pst->number_of_dependencies = len;
+      pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
+                                        len * sizeof (struct symtab *));
+      for (i = 0;
+          VEC_iterate (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
+                       i, iter);
+          ++i)
+       pst->dependencies[i] = iter->v.psymtab;
+
+      VEC_free (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
+    }
+
   if (per_cu->is_debug_types)
     {
       /* It's not clear we want to do anything with stmt lists here.
@@ -4117,7 +4175,8 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
    Process compilation unit THIS_CU for a psymtab.  */
 
 static void
-process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu)
+process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
+                          int want_partial_unit)
 {
   /* If this compilation unit was already read in, free the
      cached copy in order to read it in again. This is
@@ -4129,7 +4188,7 @@ process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu)
 
   gdb_assert (! this_cu->is_debug_types);
   init_cutu_and_read_dies (this_cu, 0, 0, process_psymtab_comp_unit_reader,
-                          NULL);
+                          &want_partial_unit);
 
   /* Age out any secondary CUs.  */
   age_cached_comp_units ();
@@ -4187,6 +4246,28 @@ psymtabs_addrmap_cleanup (void *o)
   objfile->psymtabs_addrmap = NULL;
 }
 
+/* Compute the 'user' field for each psymtab in OBJFILE.  */
+
+static void
+set_partial_user (struct objfile *objfile)
+{
+  int i;
+
+  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+    {
+      struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
+      struct partial_symtab *pst = per_cu->v.psymtab;
+      int j;
+
+      for (j = 0; j < pst->number_of_dependencies; ++j)
+       {
+         /* Set the 'user' field only if it is not already set.  */
+         if (pst->dependencies[j]->user == NULL)
+           pst->dependencies[j]->user = pst;
+       }
+    }
+}
+
 /* Build the partial symbol table by doing a quick pass through the
    .debug_info and .debug_abbrev sections.  */
 
@@ -4220,9 +4301,11 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile)
     {
       struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
 
-      process_psymtab_comp_unit (per_cu);
+      process_psymtab_comp_unit (per_cu, 0);
     }
 
+  set_partial_user (objfile);
+
   objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
                                                    &objfile->objfile_obstack);
   discard_cleanups (addrmap_cleanup);
@@ -4241,7 +4324,7 @@ load_partial_comp_unit_reader (const struct die_reader_specs *reader,
 {
   struct dwarf2_cu *cu = reader->cu;
 
-  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.
@@ -4350,7 +4433,8 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
         enums.  */
 
       if (pdi->name != NULL || pdi->tag == DW_TAG_namespace
-         || pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type)
+         || pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type
+         || pdi->tag == DW_TAG_imported_unit)
        {
          switch (pdi->tag)
            {
@@ -4390,6 +4474,21 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
            case DW_TAG_module:
              add_partial_module (pdi, lowpc, highpc, need_pc, cu);
              break;
+           case DW_TAG_imported_unit:
+             {
+               struct dwarf2_per_cu_data *per_cu;
+
+               per_cu = dwarf2_find_containing_comp_unit (pdi->d.offset,
+                                                          cu->objfile);
+
+               /* Go read the partial unit, if needed.  */
+               if (per_cu->v.psymtab == NULL)
+                 process_psymtab_comp_unit (per_cu, 1);
+
+               VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
+                              per_cu);
+             }
+             break;
            default:
              break;
            }
@@ -4598,10 +4697,10 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
       }
       break;
     case DW_TAG_variable:
-      if (pdi->locdesc)
-       addr = decode_locdesc (pdi->locdesc, cu);
+      if (pdi->d.locdesc)
+       addr = decode_locdesc (pdi->d.locdesc, cu);
 
-      if (pdi->locdesc
+      if (pdi->d.locdesc
          && addr == 0
          && !dwarf2_per_objfile->has_section_at_zero)
        {
@@ -4625,7 +4724,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
             used by GDB, but it comes in handy for debugging partial symbol
             table building.  */
 
-         if (pdi->locdesc || pdi->has_type)
+         if (pdi->d.locdesc || pdi->has_type)
            add_psymbol_to_list (actual_name, strlen (actual_name),
                                 built_actual_name,
                                 VAR_DOMAIN, LOC_STATIC,
@@ -4636,7 +4735,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
       else
        {
          /* Static Variable.  Skip symbols without location descriptors.  */
-         if (pdi->locdesc == NULL)
+         if (pdi->d.locdesc == NULL)
            {
              if (built_actual_name)
                xfree (actual_name);
@@ -5079,6 +5178,8 @@ dwarf2_psymtab_to_symtab (struct partial_symtab *pst)
            printf_filtered (_("done.\n"));
        }
     }
+
+  process_cu_includes ();
 }
 \f
 /* Reading in full CUs.  */
@@ -5086,13 +5187,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)
@@ -5117,7 +5220,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;
@@ -5165,8 +5268,12 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   struct cleanup *back_to;
   int i;
 
+  if (pst->readin)
+    return;
+
   for (i = 0; i < pst->number_of_dependencies; i++)
-    if (!pst->dependencies[i]->readin)
+    if (!pst->dependencies[i]->readin
+       && pst->dependencies[i]->user == NULL)
       {
         /* Inform about additional files that need to be read in.  */
         if (info_verbose)
@@ -5232,6 +5339,7 @@ load_full_comp_unit_reader (const struct die_reader_specs *reader,
 {
   struct dwarf2_cu *cu = reader->cu;
   struct attribute *attr;
+  enum language *language_ptr = data;
 
   gdb_assert (cu->die_hash == NULL);
   cu->die_hash =
@@ -5255,17 +5363,19 @@ load_full_comp_unit_reader (const struct die_reader_specs *reader,
      or we won't be able to build types correctly.
      Similarly, if we do not read the producer, we can not apply
      producer-specific interpretation.  */
-  prepare_one_comp_unit (cu, cu->dies);
+  prepare_one_comp_unit (cu, cu->dies, *language_ptr);
 }
 
 /* Load the DIEs associated with PER_CU into memory.  */
 
 static void
-load_full_comp_unit (struct dwarf2_per_cu_data *this_cu)
+load_full_comp_unit (struct dwarf2_per_cu_data *this_cu,
+                    enum language pretend_language)
 {
   gdb_assert (! this_cu->is_debug_types);
 
-  init_cutu_and_read_dies (this_cu, 1, 1, load_full_comp_unit_reader, NULL);
+  init_cutu_and_read_dies (this_cu, 1, 1, load_full_comp_unit_reader,
+                          &pretend_language);
 }
 
 /* Add a DIE to the delayed physname list.  */
@@ -5390,11 +5500,117 @@ fixup_go_packaging (struct dwarf2_cu *cu)
     }
 }
 
+static void compute_symtab_includes (struct dwarf2_per_cu_data *per_cu);
+
+/* Return the symtab for PER_CU.  This works properly regardless of
+   whether we're using the index or psymtabs.  */
+
+static struct symtab *
+get_symtab (struct dwarf2_per_cu_data *per_cu)
+{
+  return (dwarf2_per_objfile->using_index
+         ? per_cu->v.quick->symtab
+         : per_cu->v.psymtab->symtab);
+}
+
+/* A helper function for computing the list of all symbol tables
+   included by PER_CU.  */
+
+static void
+recursively_compute_inclusions (VEC (dwarf2_per_cu_ptr) **result,
+                               htab_t all_children,
+                               struct dwarf2_per_cu_data *per_cu)
+{
+  void **slot;
+  int ix;
+  struct dwarf2_per_cu_data *iter;
+
+  slot = htab_find_slot (all_children, per_cu, INSERT);
+  if (*slot != NULL)
+    {
+      /* This inclusion and its children have been processed.  */
+      return;
+    }
+
+  *slot = per_cu;
+  /* Only add a CU if it has a symbol table.  */
+  if (get_symtab (per_cu) != NULL)
+    VEC_safe_push (dwarf2_per_cu_ptr, *result, per_cu);
+
+  for (ix = 0;
+       VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs, ix, iter);
+       ++ix)
+    recursively_compute_inclusions (result, all_children, iter);
+}
+
+/* Compute the symtab 'includes' fields for the symtab related to
+   PER_CU.  */
+
+static void
+compute_symtab_includes (struct dwarf2_per_cu_data *per_cu)
+{
+  if (!VEC_empty (dwarf2_per_cu_ptr, per_cu->imported_symtabs))
+    {
+      int ix, len;
+      struct dwarf2_per_cu_data *iter;
+      VEC (dwarf2_per_cu_ptr) *result_children = NULL;
+      htab_t all_children;
+      struct symtab *symtab = get_symtab (per_cu);
+
+      /* If we don't have a symtab, we can just skip this case.  */
+      if (symtab == NULL)
+       return;
+
+      all_children = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer,
+                                       NULL, xcalloc, xfree);
+
+      for (ix = 0;
+          VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs,
+                       ix, iter);
+          ++ix)
+       recursively_compute_inclusions (&result_children, all_children, iter);
+
+      /* Now we have a transitive closure of all the included CUs, so
+        we can convert it to a list of symtabs.  */
+      len = VEC_length (dwarf2_per_cu_ptr, result_children);
+      symtab->includes
+       = obstack_alloc (&dwarf2_per_objfile->objfile->objfile_obstack,
+                        (len + 1) * sizeof (struct symtab *));
+      for (ix = 0;
+          VEC_iterate (dwarf2_per_cu_ptr, result_children, ix, iter);
+          ++ix)
+       symtab->includes[ix] = get_symtab (iter);
+      symtab->includes[len] = NULL;
+
+      VEC_free (dwarf2_per_cu_ptr, result_children);
+      htab_delete (all_children);
+    }
+}
+
+/* Compute the 'includes' field for the symtabs of all the CUs we just
+   read.  */
+
+static void
+process_cu_includes (void)
+{
+  int ix;
+  struct dwarf2_per_cu_data *iter;
+
+  for (ix = 0;
+       VEC_iterate (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus,
+                   ix, iter);
+       ++ix)
+    compute_symtab_includes (iter);
+
+  VEC_free (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus);
+}
+
 /* Generate full symbol information for PER_CU, whose DIEs have
    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;
@@ -5411,6 +5627,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);
 
@@ -5471,9 +5690,38 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
       pst->readin = 1;
     }
 
+  /* Push it for inclusion processing later.  */
+  VEC_safe_push (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus, per_cu);
+
   do_cleanups (back_to);
 }
 
+/* Process an imported unit DIE.  */
+
+static void
+process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct attribute *attr;
+
+  attr = dwarf2_attr (die, DW_AT_import, cu);
+  if (attr != NULL)
+    {
+      struct dwarf2_per_cu_data *per_cu;
+      struct symtab *imported_symtab;
+      sect_offset offset;
+
+      offset = dwarf2_get_ref_die_offset (attr);
+      per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
+
+      /* Queue the unit, if needed.  */
+      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);
+    }
+}
+
 /* Process a die and its children.  */
 
 static void
@@ -5484,6 +5732,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_padding:
       break;
     case DW_TAG_compile_unit:
+    case DW_TAG_partial_unit:
       read_file_scope (die, cu);
       break;
     case DW_TAG_type_unit:
@@ -5552,6 +5801,11 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
                   dwarf_tag_name (die->tag));
       read_import_statement (die, cu);
       break;
+
+    case DW_TAG_imported_unit:
+      process_imported_unit_die (die, cu);
+      break;
+
     default:
       new_symbol (die, NULL, cu);
       break;
@@ -6226,7 +6480,7 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
     }
 }
 
-/* Process DW_TAG_compile_unit.  */
+/* Process DW_TAG_compile_unit or DW_TAG_partial_unit.  */
 
 static void
 read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -6255,7 +6509,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   find_file_and_directory (die, cu, &name, &comp_dir);
 
-  prepare_one_comp_unit (cu, die);
+  prepare_one_comp_unit (cu, die, cu->language);
 
   /* The XLCL doesn't generate DW_LANG_OpenCL because this attribute is not
      standardised yet.  As a workaround for the language detection we fall
@@ -6365,7 +6619,7 @@ read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (name == NULL)
     name = "<unknown>";
 
-  prepare_one_comp_unit (cu, die);
+  prepare_one_comp_unit (cu, die, language_minimal);
 
   /* We assume that we're processing GCC output.  */
   processing_gcc_compilation = 2;
@@ -10688,7 +10942,8 @@ load_partial_dies (const struct die_reader_specs *reader,
          && abbrev->tag != DW_TAG_variable
          && abbrev->tag != DW_TAG_namespace
          && abbrev->tag != DW_TAG_module
-         && abbrev->tag != DW_TAG_member)
+         && abbrev->tag != DW_TAG_member
+         && abbrev->tag != DW_TAG_imported_unit)
        {
          /* Otherwise we skip to the next sibling, if any.  */
          info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev);
@@ -10906,6 +11161,7 @@ read_partial_die (const struct die_reader_specs *reader,
          switch (part_die->tag)
            {
            case DW_TAG_compile_unit:
+           case DW_TAG_partial_unit:
            case DW_TAG_type_unit:
              /* Compilation units have a DW_AT_name that is a filename, not
                 a source language identifier.  */
@@ -10950,7 +11206,7 @@ read_partial_die (const struct die_reader_specs *reader,
           /* Support the .debug_loc offsets.  */
           if (attr_form_is_block (&attr))
             {
-              part_die->locdesc = DW_BLOCK (&attr);
+              part_die->d.locdesc = DW_BLOCK (&attr);
             }
           else if (attr_form_is_section_offset (&attr))
             {
@@ -11019,6 +11275,12 @@ read_partial_die (const struct die_reader_specs *reader,
              || DW_UNSND (&attr) == DW_INL_declared_inlined)
            part_die->may_be_inlined = 1;
          break;
+
+       case DW_AT_import:
+         if (part_die->tag == DW_TAG_imported_unit)
+           part_die->d.offset = dwarf2_get_ref_die_offset (&attr);
+         break;
+
        default:
          break;
        }
@@ -14021,6 +14283,7 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
             So it does not need a prefix.  */
          return "";
       case DW_TAG_compile_unit:
+      case DW_TAG_partial_unit:
        /* gcc-4.5 -gdwarf-4 can drop the enclosing namespace.  Cope.  */
        if (cu->language == language_cplus
            && !VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types)
@@ -14141,6 +14404,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
   switch (die->tag)
     {
     case DW_TAG_compile_unit:
+    case DW_TAG_partial_unit:
       /* Compilation units have a DW_AT_name that is a filename, not
         a source language identifier.  */
     case DW_TAG_enumeration_type:
@@ -14174,7 +14438,8 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
              if (die->tag == DW_TAG_class_type)
                return dwarf2_name (die, cu);
            }
-         while (die->tag != DW_TAG_compile_unit);
+         while (die->tag != DW_TAG_compile_unit
+                && die->tag != DW_TAG_partial_unit);
        }
       break;
 
@@ -14571,7 +14836,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
@@ -14600,7 +14866,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;
 }
@@ -14659,8 +14925,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;
     }
@@ -14668,7 +14934,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;
@@ -14800,7 +15066,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);
@@ -14913,7 +15179,7 @@ read_signatured_type_reader (const struct die_reader_specs *reader,
      or we won't be able to build types correctly.
      Similarly, if we do not read the producer, we can not apply
      producer-specific interpretation.  */
-  prepare_one_comp_unit (cu, cu->dies);
+  prepare_one_comp_unit (cu, cu->dies, language_minimal);
 }
 
 /* Read in a signatured type and build its CU and DIEs.
@@ -16379,7 +16645,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;
 
@@ -16389,7 +16656,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);
     }
 
@@ -16833,6 +17100,10 @@ dwarf2_per_objfile_free (struct objfile *objfile, void *d)
        ++ix)
     munmap_section_buffer (section);
 
+  for (ix = 0; ix < dwarf2_per_objfile->n_comp_units; ++ix)
+    VEC_free (dwarf2_per_cu_ptr,
+             dwarf2_per_objfile->all_comp_units[ix]->imported_symtabs);
+
   VEC_free (dwarf2_section_info_def, data->types);
 
   if (data->dwo_files)
@@ -17393,6 +17664,35 @@ write_one_signatured_type (void **slot, void *d)
   return 1;
 }
 
+/* Recurse into all "included" dependencies and write their symbols as
+   if they appeared in this psymtab.  */
+
+static void
+recursively_write_psymbols (struct objfile *objfile,
+                           struct partial_symtab *psymtab,
+                           struct mapped_symtab *symtab,
+                           htab_t psyms_seen,
+                           offset_type cu_index)
+{
+  int i;
+
+  for (i = 0; i < psymtab->number_of_dependencies; ++i)
+    if (psymtab->dependencies[i]->user != NULL)
+      recursively_write_psymbols (objfile, psymtab->dependencies[i],
+                                 symtab, psyms_seen, cu_index);
+
+  write_psymbols (symtab,
+                 psyms_seen,
+                 objfile->global_psymbols.list + psymtab->globals_offset,
+                 psymtab->n_global_syms, cu_index,
+                 0);
+  write_psymbols (symtab,
+                 psyms_seen,
+                 objfile->static_psymbols.list + psymtab->statics_offset,
+                 psymtab->n_static_syms, cu_index,
+                 1);
+}
+
 /* Create an index file for OBJFILE in the directory DIR.  */
 
 static void
@@ -17477,16 +17777,8 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
       struct psymtab_cu_index_map *map;
       void **slot;
 
-      write_psymbols (symtab,
-                     psyms_seen,
-                     objfile->global_psymbols.list + psymtab->globals_offset,
-                     psymtab->n_global_syms, i,
-                     0);
-      write_psymbols (symtab,
-                     psyms_seen,
-                     objfile->static_psymbols.list + psymtab->statics_offset,
-                     psymtab->n_static_syms, i,
-                     1);
+      if (psymtab->user == NULL)
+       recursively_write_psymbols (objfile, psymtab, symtab, psyms_seen, i);
 
       map = &psymtab_cu_index_map[i];
       map->psymtab = psymtab;