diff mbox

[01/21] struct symtab split part 2: symtab.c symtab.h

Message ID 5464aa51.e689440a.41e0.2c16@mx.google.com
State New
Headers show

Commit Message

Doug Evans Nov. 13, 2014, 12:54 p.m. UTC
This patch contains the changes to symtab.c, symtab.h.

Full ChangeLog: https://sourceware.org/ml/gdb-patches/2014-11/msg00233.html

2014-11-12  Doug Evans  <xdje42@gmail.com>

	* symtab.c (set_primary_symtab): Delete.
	(compunit_primary_filetab): New function.
	(compunit_language): New function.
	(iterate_over_some_symtabs): Change type of arguments "first",
	"after_last" to "struct compunit_symtab *".  All callers updated.
	Update to loop over symtabs in each compunit.
	(error_in_psymtab_expansion): Rename symtab argument to cust,
	and change type to "struct compunit_symtab *".  All callers updated.
	(find_pc_sect_compunit_symtab): Renamed from find_pc_sect_symtab.
	Change result type to "struct compunit_symtab *".  All callers updated.
	(find_pc_compunit_symtab): Renamed from find_pc_symtab.
	Change result type to "struct compunit_symtab *".  All callers updated.
	(find_pc_sect_line): Only loop over symtabs within selected compunit
	instead of all symtabs in the objfile.
	* symtab.h (struct symtab) <blockvector>: Moved to compunit_symtab.
	<compunit_symtab> New member.
	<block_line_section>: Moved to compunit_symtab.
	<locations_valid>: Ditto.
	<epilogue_unwind_valid>: Ditto.
	<macro_table>: Ditto.
	<dirname>: Ditto.
	<debugformat>: Ditto.
	<producer>: Ditto.
	<objfile>: Ditto.
	<call_site_htab>: Ditto.
	<includes>: Ditto.
	<user>: Ditto.
	<primary>: Delete
	(SYMTAB_COMPUNIT): New macro.
	(SYMTAB_BLOCKVECTOR): Update definition.
	(SYMTAB_OBJFILE): Update definition.
	(SYMTAB_DIRNAME): Update definition.
	(struct compunit_symtab): New type.  Common members among all source
	symtabs within a compilation unit moved here.  All uses updated.
	(COMPUNIT_OBJFILE): New macro.
	(COMPUNIT_FILETABS): New macro.
	(COMPUNIT_DEBUGFORMAT): New macro.
	(COMPUNIT_PRODUCER): New macro.
	(COMPUNIT_DIRNAME): New macro.
	(COMPUNIT_BLOCKVECTOR): New macro.
	(COMPUNIT_BLOCK_LINE_SECTION): New macro.
	(COMPUNIT_LOCATIONS_VALID): New macro.
	(COMPUNIT_EPILOGUE_UNWIND_VALID): New macro.
	(COMPUNIT_CALL_SITE_HTAB): New macro.
	(COMPUNIT_MACRO_TABLE): New macro.
	(ALL_COMPUNIT_FILETABS): New macro.
	(compunit_symtab_ptr): New typedef.
	(DEF_VEC_P (compunit_symtab_ptr)): New vector type.
diff mbox

Patch

diff --git a/gdb/symtab.c b/gdb/symtab.c
index 3ae0af8..3adc7ce 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -173,20 +173,27 @@  search_domain_name (enum search_domain e)
     }
 }
 
-/* Set the primary field in SYMTAB.  */
+/* See symtab.h.  */
 
-void
-set_symtab_primary (struct symtab *symtab, int primary)
+struct symtab *
+compunit_primary_filetab (const struct compunit_symtab *cust)
 {
-  symtab->primary = primary;
+  gdb_assert (COMPUNIT_FILETABS (cust) != NULL);
 
-  if (symtab_create_debug && primary)
-    {
-      fprintf_unfiltered (gdb_stdlog,
-			  "Created primary symtab %s for %s.\n",
-			  host_address_to_string (symtab),
-			  symtab_to_filename_for_display (symtab));
-    }
+  /* The primary file symtab is the first one in the list.  */
+  return COMPUNIT_FILETABS (cust);
+}
+
+/* See symtab.h.  */
+
+enum language
+compunit_language (const struct compunit_symtab *cust)
+{
+  struct symtab *symtab = compunit_primary_filetab (cust);
+
+/* The language of the compunit symtab is the language of its primary
+   source file.  */
+  return SYMTAB_LANGUAGE (symtab);
 }
 
 /* See whether FILENAME matches SEARCH_NAME using the rule that we
@@ -237,8 +244,9 @@  compare_filenames_for_search (const char *filename, const char *search_name)
    are identical to the `map_symtabs_matching_filename' method of
    quick_symbol_functions.
 
-   FIRST and AFTER_LAST indicate the range of symtabs to search.
-   AFTER_LAST is one past the last symtab to search; NULL means to
+   FIRST and AFTER_LAST indicate the range of compunit symtabs to search.
+   Each symtab within the specified compunit symtab is also searched.
+   AFTER_LAST is one past the last compunit symtab to search; NULL means to
    search until the end of the list.  */
 
 int
@@ -247,48 +255,52 @@  iterate_over_some_symtabs (const char *name,
 			   int (*callback) (struct symtab *symtab,
 					    void *data),
 			   void *data,
-			   struct symtab *first,
-			   struct symtab *after_last)
+			   struct compunit_symtab *first,
+			   struct compunit_symtab *after_last)
 {
-  struct symtab *s = NULL;
+  struct compunit_symtab *cust;
+  struct symtab *s;
   const char* base_name = lbasename (name);
 
-  for (s = first; s != NULL && s != after_last; s = s->next)
+  for (cust = first; cust != NULL && cust != after_last; cust = cust->next)
     {
-      if (compare_filenames_for_search (s->filename, name))
+      ALL_COMPUNIT_FILETABS (cust, s)
 	{
-	  if (callback (s, data))
-	    return 1;
-	  continue;
-	}
-
-      /* Before we invoke realpath, which can get expensive when many
-	 files are involved, do a quick comparison of the basenames.  */
-      if (! basenames_may_differ
-	  && FILENAME_CMP (base_name, lbasename (s->filename)) != 0)
-	continue;
-
-      if (compare_filenames_for_search (symtab_to_fullname (s), name))
-	{
-	  if (callback (s, data))
-	    return 1;
-	  continue;
-	}
+	  if (compare_filenames_for_search (s->filename, name))
+	    {
+	      if (callback (s, data))
+		return 1;
+	      continue;
+	    }
 
-      /* If the user gave us an absolute path, try to find the file in
-	 this symtab and use its absolute path.  */
-      if (real_path != NULL)
-	{
-	  const char *fullname = symtab_to_fullname (s);
+	  /* Before we invoke realpath, which can get expensive when many
+	     files are involved, do a quick comparison of the basenames.  */
+	  if (! basenames_may_differ
+	      && FILENAME_CMP (base_name, lbasename (s->filename)) != 0)
+	    continue;
 
-	  gdb_assert (IS_ABSOLUTE_PATH (real_path));
-	  gdb_assert (IS_ABSOLUTE_PATH (name));
-	  if (FILENAME_CMP (real_path, fullname) == 0)
+	  if (compare_filenames_for_search (symtab_to_fullname (s), name))
 	    {
 	      if (callback (s, data))
 		return 1;
 	      continue;
 	    }
+
+	  /* If the user gave us an absolute path, try to find the file in
+	     this symtab and use its absolute path.  */
+	  if (real_path != NULL)
+	    {
+	      const char *fullname = symtab_to_fullname (s);
+
+	      gdb_assert (IS_ABSOLUTE_PATH (real_path));
+	      gdb_assert (IS_ABSOLUTE_PATH (name));
+	      if (FILENAME_CMP (real_path, fullname) == 0)
+		{
+		  if (callback (s, data))
+		    return 1;
+		  continue;
+		}
+	    }
 	}
     }
 
@@ -324,7 +336,7 @@  iterate_over_symtabs (const char *name,
   ALL_OBJFILES (objfile)
   {
     if (iterate_over_some_symtabs (name, real_path, callback, data,
-				   objfile->symtabs, NULL))
+				   objfile->compunit_symtabs, NULL))
       {
 	do_cleanups (cleanups);
 	return;
@@ -1067,12 +1079,12 @@  expand_symtab_containing_pc (CORE_ADDR pc, struct obj_section *section)
 
   ALL_OBJFILES (objfile)
   {
-    struct symtab *s = NULL;
+    struct compunit_symtab *cust = NULL;
 
     if (objfile->sf)
-      s = objfile->sf->qf->find_pc_sect_symtab (objfile, msymbol,
-						pc, section, 0);
-    if (s != NULL)
+      cust = objfile->sf->qf->find_pc_sect_compunit_symtab (objfile, msymbol,
+							    pc, section, 0);
+    if (cust)
       return;
   }
 }
@@ -1516,17 +1528,16 @@  struct objfile *
 lookup_objfile_from_block (const struct block *block)
 {
   struct objfile *obj;
-  struct symtab *s;
+  struct compunit_symtab *cust;
 
   if (block == NULL)
     return NULL;
 
   block = block_global_block (block);
-  /* Go through SYMTABS.
-     Non-primary symtabs share the block vector with their primary symtabs
-     so we use ALL_PRIMARY_SYMTABS here instead of ALL_SYMTABS.  */
-  ALL_PRIMARY_SYMTABS (obj, s)
-    if (block == BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (s), GLOBAL_BLOCK))
+  /* Look through all blockvectors.  */
+  ALL_COMPUNITS (obj, cust)
+    if (block == BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust),
+				    GLOBAL_BLOCK))
       {
 	if (obj->separate_debug_objfile_backlink)
 	  obj = obj->separate_debug_objfile_backlink;
@@ -1563,19 +1574,21 @@  lookup_global_symbol_from_objfile (const struct objfile *main_objfile,
 				   const domain_enum domain)
 {
   const struct objfile *objfile;
-  struct symbol *sym;
-  const struct blockvector *bv;
-  const struct block *block;
-  struct symtab *s;
 
   for (objfile = main_objfile;
        objfile;
        objfile = objfile_separate_debug_iterate (main_objfile, objfile))
     {
+      struct compunit_symtab *cust;
+      struct symbol *sym;
+
       /* Go through symtabs.  */
-      ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s)
+      ALL_OBJFILE_COMPUNITS (objfile, cust)
 	{
-	  bv = SYMTAB_BLOCKVECTOR (s);
+	  const struct blockvector *bv;
+	  const struct block *block;
+
+	  bv = COMPUNIT_BLOCKVECTOR (cust);
 	  block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
 	  sym = block_lookup_symbol (block, name, domain);
 	  if (sym)
@@ -1603,14 +1616,15 @@  static struct symbol *
 lookup_symbol_in_objfile_symtabs (struct objfile *objfile, int block_index,
 				  const char *name, const domain_enum domain)
 {
-  struct symbol *sym = NULL;
-  const struct blockvector *bv;
-  const struct block *block;
-  struct symtab *s;
+  struct compunit_symtab *cust;
 
-  ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s)
+  ALL_OBJFILE_COMPUNITS (objfile, cust)
     {
-      bv = SYMTAB_BLOCKVECTOR (s);
+      const struct blockvector *bv;
+      const struct block *block;
+      struct symbol *sym;
+
+      bv = COMPUNIT_BLOCKVECTOR (cust);
       block = BLOCKVECTOR_BLOCK (bv, block_index);
       sym = block_lookup_symbol (block, name, domain);
       if (sym)
@@ -1670,14 +1684,16 @@  lookup_symbol_in_objfile_from_linkage_name (struct objfile *objfile,
 
 static void ATTRIBUTE_NORETURN
 error_in_psymtab_expansion (int block_index, const char *name,
-			    struct symtab *symtab)
+			    struct compunit_symtab *cust)
 {
   error (_("\
 Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n	 \
 (if a template, try specifying an instantiation: %s<type>)."),
 	 block_index == GLOBAL_BLOCK ? "global" : "static",
-	 name, symtab_to_filename_for_display (symtab), name, name);
+	 name,
+	 symtab_to_filename_for_display (compunit_primary_filetab (cust)),
+	 name, name);
 }
 
 /* A helper function for various lookup routines that interfaces with
@@ -1687,22 +1703,22 @@  static struct symbol *
 lookup_symbol_via_quick_fns (struct objfile *objfile, int block_index,
 			     const char *name, const domain_enum domain)
 {
-  struct symtab *symtab;
+  struct compunit_symtab *cust;
   const struct blockvector *bv;
   const struct block *block;
   struct symbol *sym;
 
   if (!objfile->sf)
     return NULL;
-  symtab = objfile->sf->qf->lookup_symbol (objfile, block_index, name, domain);
-  if (!symtab)
+  cust = objfile->sf->qf->lookup_symbol (objfile, block_index, name, domain);
+  if (cust == NULL)
     return NULL;
 
-  bv = SYMTAB_BLOCKVECTOR (symtab);
+  bv = COMPUNIT_BLOCKVECTOR (cust);
   block = BLOCKVECTOR_BLOCK (bv, block_index);
   sym = block_lookup_symbol (block, name, domain);
   if (!sym)
-    error_in_psymtab_expansion (block_index, name, symtab);
+    error_in_psymtab_expansion (block_index, name, cust);
   block_found = block;
   return fixup_symbol_section (sym, objfile);
 }
@@ -1911,23 +1927,23 @@  static struct type *
 basic_lookup_transparent_type_quick (struct objfile *objfile, int block_index,
 				     const char *name)
 {
-  struct symtab *symtab;
+  struct compunit_symtab *cust;
   const struct blockvector *bv;
   struct block *block;
   struct symbol *sym;
 
   if (!objfile->sf)
     return NULL;
-  symtab = objfile->sf->qf->lookup_symbol (objfile, block_index, name,
-					   STRUCT_DOMAIN);
-  if (!symtab)
+  cust = objfile->sf->qf->lookup_symbol (objfile, block_index, name,
+					 STRUCT_DOMAIN);
+  if (cust == NULL)
     return NULL;
 
-  bv = SYMTAB_BLOCKVECTOR (symtab);
+  bv = COMPUNIT_BLOCKVECTOR (cust);
   block = BLOCKVECTOR_BLOCK (bv, block_index);
   sym = block_lookup_symbol (block, name, STRUCT_DOMAIN);
   if (!sym)
-    error_in_psymtab_expansion (block_index, name, symtab);
+    error_in_psymtab_expansion (block_index, name, cust);
 
   if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
     return SYMBOL_TYPE (sym);
@@ -1945,7 +1961,7 @@  struct type *
 basic_lookup_transparent_type (const char *name)
 {
   struct symbol *sym;
-  struct symtab *s = NULL;
+  struct compunit_symtab *cust;
   const struct blockvector *bv;
   struct objfile *objfile;
   struct block *block;
@@ -1958,9 +1974,9 @@  basic_lookup_transparent_type (const char *name)
 
   ALL_OBJFILES (objfile)
   {
-    ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s)
+    ALL_OBJFILE_COMPUNITS (objfile, cust)
       {
-	bv = SYMTAB_BLOCKVECTOR (s);
+	bv = COMPUNIT_BLOCKVECTOR (cust);
 	block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
 	sym = block_lookup_symbol (block, name, STRUCT_DOMAIN);
 	if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
@@ -1986,9 +2002,9 @@  basic_lookup_transparent_type (const char *name)
 
   ALL_OBJFILES (objfile)
   {
-    ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s)
+    ALL_OBJFILE_COMPUNITS (objfile, cust)
       {
-	bv = SYMTAB_BLOCKVECTOR (s);
+	bv = COMPUNIT_BLOCKVECTOR (cust);
 	block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
 	sym = block_lookup_symbol (block, name, STRUCT_DOMAIN);
 	if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
@@ -2036,16 +2052,14 @@  iterate_over_symbols (const struct block *block, const char *name,
     }
 }
 
-/* Find the symtab associated with PC and SECTION.  Look through the
-   psymtabs and read in another symtab if necessary.  */
+/* Find the compunit symtab associated with PC and SECTION.
+   This will read in debug info as necessary.  */
 
-struct symtab *
-find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
+struct compunit_symtab *
+find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
 {
-  struct block *b;
-  const struct blockvector *bv;
-  struct symtab *s = NULL;
-  struct symtab *best_s = NULL;
+  struct compunit_symtab *cust;
+  struct compunit_symtab *best_cust = NULL;
   struct objfile *objfile;
   CORE_ADDR distance = 0;
   struct bound_minimal_symbol msymbol;
@@ -2079,9 +2093,12 @@  find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
      It also happens for objfiles that have their functions reordered.
      For these, the symtab we are looking for is not necessarily read in.  */
 
-  ALL_PRIMARY_SYMTABS (objfile, s)
+  ALL_COMPUNITS (objfile, cust)
   {
-    bv = SYMTAB_BLOCKVECTOR (s);
+    struct block *b;
+    const struct blockvector *bv;
+
+    bv = COMPUNIT_BLOCKVECTOR (cust);
     b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
 
     if (BLOCK_START (b) <= pc
@@ -2097,14 +2114,14 @@  find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
 	   can't be found.  */
 	if ((objfile->flags & OBJF_REORDERED) && objfile->sf)
 	  {
-	    struct symtab *result;
+	    struct compunit_symtab *result;
 
 	    result
-	      = objfile->sf->qf->find_pc_sect_symtab (objfile,
-						      msymbol,
-						      pc, section,
-						      0);
-	    if (result)
+	      = objfile->sf->qf->find_pc_sect_compunit_symtab (objfile,
+							       msymbol,
+							       pc, section,
+							       0);
+	    if (result != NULL)
 	      return result;
 	  }
 	if (section != 0)
@@ -2124,39 +2141,40 @@  find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
 				   section.  */
 	  }
 	distance = BLOCK_END (b) - BLOCK_START (b);
-	best_s = s;
+	best_cust = cust;
       }
   }
 
-  if (best_s != NULL)
-    return (best_s);
+  if (best_cust != NULL)
+    return best_cust;
 
   /* Not found in symtabs, search the "quick" symtabs (e.g. psymtabs).  */
 
   ALL_OBJFILES (objfile)
   {
-    struct symtab *result;
+    struct compunit_symtab *result;
 
     if (!objfile->sf)
       continue;
-    result = objfile->sf->qf->find_pc_sect_symtab (objfile,
-						   msymbol,
-						   pc, section,
-						   1);
-    if (result)
+    result = objfile->sf->qf->find_pc_sect_compunit_symtab (objfile,
+							    msymbol,
+							    pc, section,
+							    1);
+    if (result != NULL)
       return result;
   }
 
   return NULL;
 }
 
-/* Find the symtab associated with PC.  Look through the psymtabs and read
-   in another symtab if necessary.  Backward compatibility, no section.  */
+/* Find the compunit symtab associated with PC.
+   This will read in debug info as necessary.
+   Backward compatibility, no section.  */
 
-struct symtab *
-find_pc_symtab (CORE_ADDR pc)
+struct compunit_symtab *
+find_pc_compunit_symtab (CORE_ADDR pc)
 {
-  return find_pc_sect_symtab (pc, find_pc_mapped_section (pc));
+  return find_pc_sect_compunit_symtab (pc, find_pc_mapped_section (pc));
 }
 
 
@@ -2180,7 +2198,8 @@  find_pc_symtab (CORE_ADDR pc)
 struct symtab_and_line
 find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
 {
-  struct symtab *s;
+  struct compunit_symtab *cust;
+  struct symtab *iter_s;
   struct linetable *l;
   int len;
   int i;
@@ -2188,7 +2207,6 @@  find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
   struct symtab_and_line val;
   const struct blockvector *bv;
   struct bound_minimal_symbol msymbol;
-  struct objfile *objfile;
 
   /* Info on best line seen so far, and where it starts, and its file.  */
 
@@ -2306,8 +2324,8 @@  find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
       }
 
 
-  s = find_pc_sect_symtab (pc, section);
-  if (!s)
+  cust = find_pc_sect_compunit_symtab (pc, section);
+  if (cust == NULL)
     {
       /* If no symbol information, return previous pc.  */
       if (notcurrent)
@@ -2316,20 +2334,16 @@  find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
       return val;
     }
 
-  bv = SYMTAB_BLOCKVECTOR (s);
-  objfile = SYMTAB_OBJFILE (s);
+  bv = COMPUNIT_BLOCKVECTOR (cust);
 
   /* Look at all the symtabs that share this blockvector.
      They all have the same apriori range, that we found was right;
      but they have different line tables.  */
 
-  ALL_OBJFILE_SYMTABS (objfile, s)
+  ALL_COMPUNIT_FILETABS (cust, iter_s)
     {
-      if (SYMTAB_BLOCKVECTOR (s) != bv)
-	continue;
-
       /* Find the best line in this symtab.  */
-      l = SYMTAB_LINETABLE (s);
+      l = SYMTAB_LINETABLE (iter_s);
       if (!l)
 	continue;
       len = l->nitems;
@@ -2373,7 +2387,7 @@  find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
       if (prev && prev->line && (!best || prev->pc > best->pc))
 	{
 	  best = prev;
-	  best_symtab = s;
+	  best_symtab = iter_s;
 
 	  /* Discard BEST_END if it's before the PC of the current BEST.  */
 	  if (best_end <= best->pc)
@@ -2487,6 +2501,7 @@  find_line_symtab (struct symtab *symtab, int line,
       int best;
 
       struct objfile *objfile;
+      struct compunit_symtab *cu;
       struct symtab *s;
 
       if (best_index >= 0)
@@ -2501,7 +2516,7 @@  find_line_symtab (struct symtab *symtab, int line,
 						   symtab_to_fullname (symtab));
       }
 
-      ALL_SYMTABS (objfile, s)
+      ALL_FILETABS (objfile, cu, s)
       {
 	struct linetable *l;
 	int ind;
@@ -2849,7 +2864,7 @@  skip_prologue_sal (struct symtab_and_line *sal)
   /* Be conservative - allow direct PC (without skipping prologue) only if we
      have proven the CU (Compilation Unit) supports it.  sal->SYMTAB does not
      have to be set by the caller so we use SYM instead.  */
-  if (sym && SYMBOL_SYMTAB (sym)->locations_valid)
+  if (sym && COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (SYMBOL_SYMTAB (sym))))
     force_skip = 0;
 
   saved_pc = pc;
@@ -3336,6 +3351,7 @@  output_partial_symbol_filename (const char *filename, const char *fullname,
 static void
 sources_info (char *ignore, int from_tty)
 {
+  struct compunit_symtab *cu;
   struct symtab *s;
   struct objfile *objfile;
   struct output_source_filename_data data;
@@ -3353,7 +3369,7 @@  sources_info (char *ignore, int from_tty)
   printf_filtered ("Source files for which symbols have been read in:\n\n");
 
   data.first = 1;
-  ALL_SYMTABS (objfile, s)
+  ALL_FILETABS (objfile, cu, s)
   {
     const char *fullname = symtab_to_fullname (s);
 
@@ -3551,7 +3567,7 @@  search_symbols (const char *regexp, enum search_domain kind,
 		int nfiles, const char *files[],
 		struct symbol_search **matches)
 {
-  struct symtab *s;
+  struct compunit_symtab *cust;
   const struct blockvector *bv;
   struct block *b;
   int i = 0;
@@ -3691,10 +3707,10 @@  search_symbols (const char *regexp, enum search_domain kind,
 	      {
 		/* Note: An important side-effect of these lookup functions
 		   is to expand the symbol table if msymbol is found, for the
-		   benefit of the next loop on ALL_PRIMARY_SYMTABS.  */
+		   benefit of the next loop on ALL_COMPUNITS.  */
 		if (kind == FUNCTIONS_DOMAIN
-		    ? find_pc_symtab (MSYMBOL_VALUE_ADDRESS (objfile,
-							     msymbol)) == NULL
+		    ? (find_pc_compunit_symtab
+		       (MSYMBOL_VALUE_ADDRESS (objfile, msymbol)) == NULL)
 		    : (lookup_symbol_in_objfile_from_linkage_name
 		       (objfile, MSYMBOL_LINKAGE_NAME (msymbol), VAR_DOMAIN)
 		       == NULL))
@@ -3709,9 +3725,9 @@  search_symbols (const char *regexp, enum search_domain kind,
   nfound = 0;
   retval_chain = make_cleanup_free_search_symbols (&found);
 
-  ALL_PRIMARY_SYMTABS (objfile, s)
+  ALL_COMPUNITS (objfile, cust)
   {
-    bv = SYMTAB_BLOCKVECTOR (s);
+    bv = COMPUNIT_BLOCKVECTOR (cust);
     for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
       {
 	b = BLOCKVECTOR_BLOCK (bv, i);
@@ -3796,8 +3812,8 @@  search_symbols (const char *regexp, enum search_domain kind,
 		/* For functions we can do a quick check of whether the
 		   symbol might be found via find_pc_symtab.  */
 		if (kind != FUNCTIONS_DOMAIN
-		    || find_pc_symtab (MSYMBOL_VALUE_ADDRESS (objfile,
-							      msymbol)) == NULL)
+		    || (find_pc_compunit_symtab
+			(MSYMBOL_VALUE_ADDRESS (objfile, msymbol)) == NULL))
 		  {
 		    if (lookup_symbol_in_objfile_from_linkage_name
 			(objfile, MSYMBOL_LINKAGE_NAME (msymbol), VAR_DOMAIN)
@@ -4349,7 +4365,7 @@  default_make_symbol_completion_list_break_on (const char *text,
      won't be that many.  */
 
   struct symbol *sym;
-  struct symtab *s;
+  struct compunit_symtab *cust;
   struct minimal_symbol *msymbol;
   struct objfile *objfile;
   const struct block *b;
@@ -4515,10 +4531,10 @@  default_make_symbol_completion_list_break_on (const char *text,
   /* Go through the symtabs and check the externs and statics for
      symbols which match.  */
 
-  ALL_PRIMARY_SYMTABS (objfile, s)
+  ALL_COMPUNITS (objfile, cust)
   {
     QUIT;
-    b = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (s), GLOBAL_BLOCK);
+    b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), GLOBAL_BLOCK);
     ALL_BLOCK_SYMBOLS (b, iter, sym)
       {
 	if (code == TYPE_CODE_UNDEF
@@ -4528,10 +4544,10 @@  default_make_symbol_completion_list_break_on (const char *text,
       }
   }
 
-  ALL_PRIMARY_SYMTABS (objfile, s)
+  ALL_COMPUNITS (objfile, cust)
   {
     QUIT;
-    b = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (s), STATIC_BLOCK);
+    b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), STATIC_BLOCK);
     ALL_BLOCK_SYMBOLS (b, iter, sym)
       {
 	if (code == TYPE_CODE_UNDEF
@@ -4808,6 +4824,7 @@  maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
 VEC (char_ptr) *
 make_source_files_completion_list (const char *text, const char *word)
 {
+  struct compunit_symtab *cu;
   struct symtab *s;
   struct objfile *objfile;
   size_t text_len = strlen (text);
@@ -4826,7 +4843,7 @@  make_source_files_completion_list (const char *text, const char *word)
   cache_cleanup = make_cleanup (delete_filename_seen_cache,
 				filename_seen_cache);
 
-  ALL_SYMTABS (objfile, s)
+  ALL_FILETABS (objfile, cu, s)
     {
       if (not_interesting_fname (s->filename))
 	continue;
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 169c6a6..85b7399 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -870,6 +870,7 @@  struct section_offsets
    + sizeof (((struct section_offsets *) 0)->offsets) * ((n)-1))
 
 /* Each source file or header is represented by a struct symtab.
+   The name "symtab" is historical, another name for it is "filetab".
    These objects are chained through the `next' field.  */
 
 struct symtab
@@ -878,52 +879,19 @@  struct symtab
 
   struct symtab *next;
 
-  /* List of all symbol scope blocks for this symtab.  May be shared
-     between different symtabs (and normally is for all the symtabs
-     in a given compilation unit).  */
+  /* Backlink to containing compunit symtab.  */
 
-  const struct blockvector *blockvector;
+  struct compunit_symtab *compunit_symtab;
 
   /* Table mapping core addresses to line numbers for this file.
      Can be NULL if none.  Never shared between different symtabs.  */
 
   struct linetable *linetable;
 
-  /* Section in objfile->section_offsets for the blockvector and
-     the linetable.  Probably always SECT_OFF_TEXT.  */
-
-  int block_line_section;
-
-  /* If several symtabs share a blockvector, exactly one of them
-     should be designated the primary, so that the blockvector
-     is relocated exactly once by objfile_relocate.  */
-
-  unsigned int primary : 1;
-
-  /* Symtab has been compiled with both optimizations and debug info so that
-     GDB may stop skipping prologues as variables locations are valid already
-     at function entry points.  */
-
-  unsigned int locations_valid : 1;
-
-  /* DWARF unwinder for this CU is valid even for epilogues (PC at the return
-     instruction).  This is supported by GCC since 4.5.0.  */
-
-  unsigned int epilogue_unwind_valid : 1;
-
-  /* The macro table for this symtab.  Like the blockvector, this
-     may be shared between different symtabs --- and normally is for
-     all the symtabs in a given compilation unit.  */
-  struct macro_table *macro_table;
-
   /* Name of this source file.  This pointer is never NULL.  */
 
   const char *filename;
 
-  /* Directory in which it was compiled, or NULL if we don't know.  */
-
-  const char *dirname;
-
   /* Total number of lines found in source file.  */
 
   int nlines;
@@ -938,59 +906,141 @@  struct symtab
 
   enum language language;
 
-  /* String that identifies the format of the debugging information, such
-     as "stabs", "dwarf 1", "dwarf 2", "coff", etc.  This is mostly useful
+  /* Full name of file as found by searching the source path.
+     NULL if not yet known.  */
+
+  char *fullname;
+};
+
+#define SYMTAB_COMPUNIT(symtab) ((symtab)->compunit_symtab)
+#define SYMTAB_LINETABLE(symtab) ((symtab)->linetable)
+#define SYMTAB_LANGUAGE(symtab) ((symtab)->language)
+
+#define SYMTAB_BLOCKVECTOR(symtab) \
+  COMPUNIT_BLOCKVECTOR (SYMTAB_COMPUNIT (symtab))
+#define SYMTAB_OBJFILE(symtab) \
+  COMPUNIT_OBJFILE (SYMTAB_COMPUNIT (symtab))
+#define SYMTAB_PSPACE(symtab) (SYMTAB_OBJFILE (symtab)->pspace)
+#define SYMTAB_DIRNAME(symtab) \
+  COMPUNIT_DIRNAME (SYMTAB_COMPUNIT (symtab))
+
+typedef struct symtab *symtab_ptr;
+DEF_VEC_P (symtab_ptr);
+
+/* Compunit symtabs contain the actual "symbol table", aka blockvector, as well
+   as the list of all source files (what gdb has historically associated with
+   the term "symtab").
+   Additional information is recorded here that is common to all symtabs in a
+   compilation unit (DWARF or otherwise).  */
+
+struct compunit_symtab
+{
+  /* Unordered chain of all compunit symtabs of this objfile.  */
+  struct compunit_symtab *next;
+
+  /* Object file from which this symtab information was read.  */
+  struct objfile *objfile;
+
+  /* Name of the symtab.
+     This is *not* intended to be a usable filename, and is
+     for debugging purposes only.  */
+  const char *name;
+
+  /* Unordered list of file symtabs, except that by convention the "main"
+     source file (e.g., .c, .cc) is guaranteed to be first.
+     Each symtab is a file, either the "main" source file (e.g., .c, .cc)
+     or header (e.g., .h).  */
+  struct symtab *filetabs;
+
+  /* Last entry in FILETABS list.
+     Subfiles are added to the end of the list so they accumulate in order,
+     with the main source subfile living at the front.
+     The main reason is so that the main source file symtab is at the head
+     of the list, and the rest appear in order for debugging convenience.  */
+  struct symtab *last_filetab;
+
+  /* Non-NULL string that identifies the format of the debugging information,
+     such as "stabs", "dwarf 1", "dwarf 2", "coff", etc.  This is mostly useful
      for automated testing of gdb but may also be information that is
      useful to the user.  */
-
   const char *debugformat;
 
-  /* String of producer version information.  May be zero.  */
-
+  /* String of producer version information, or NULL if we don't know.  */
   const char *producer;
 
-  /* Full name of file as found by searching the source path.
-     NULL if not yet known.  */
+  /* Directory in which it was compiled, or NULL if we don't know.  */
+  const char *dirname;
 
-  char *fullname;
+  /* List of all symbol scope blocks for this symtab.  It is shared among
+     all symtabs in a given compilation unit.  */
+  const struct blockvector *blockvector;
 
-  /* Object file from which this symbol information was read.  */
+  /* Section in objfile->section_offsets for the blockvector and
+     the linetable.  Probably always SECT_OFF_TEXT.  */
+  int block_line_section;
 
-  struct objfile *objfile;
+  /* Symtab has been compiled with both optimizations and debug info so that
+     GDB may stop skipping prologues as variables locations are valid already
+     at function entry points.  */
+  unsigned int locations_valid : 1;
 
-  /* struct call_site entries for this compilation unit or NULL.  */
+  /* DWARF unwinder for this CU is valid even for epilogues (PC at the return
+     instruction).  This is supported by GCC since 4.5.0.  */
+  unsigned int epilogue_unwind_valid : 1;
 
+  /* struct call_site entries for this compilation unit or NULL.  */
   htab_t call_site_htab;
 
+  /* The macro table for this symtab.  Like the blockvector, this
+     is shared between different symtabs in a given compilation unit.
+     It's debatable whether it *should* be shared among all the symtabs in
+     the given compilation unit, but it currently is.  */
+  struct macro_table *macro_table;
+
   /* If non-NULL, then this points to a NULL-terminated vector of
-     included symbol tables.  When searching the static or global
-     block of this symbol table, the corresponding block of all
-     included symbol tables will also be searched.  Note that this
+     included compunits.  When searching the static or global
+     block of this compunit, the corresponding block of all
+     included compunits will also be searched.  Note that this
      list must be flattened -- the symbol reader is responsible for
      ensuring that this vector contains the transitive closure of all
-     included symbol tables.  */
-
-  struct symtab **includes;
+     included compunits.  */
+  struct compunit_symtab **includes;
 
-  /* If this is an included symbol table, this points to one includer
-     of the table.  This user is considered the canonical symbol table
-     containing this one.  An included symbol table may itself be
+  /* If this is an included compunit, this points to one includer
+     of the table.  This user is considered the canonical compunit
+     containing this one.  An included compunit may itself be
      included by another.  */
-
-  struct symtab *user;
+  struct compunit_symtab *user;
 };
 
-#define SYMTAB_BLOCKVECTOR(symtab) ((symtab)->blockvector)
-#define SYMTAB_LINETABLE(symtab) ((symtab)->linetable)
-#define SYMTAB_OBJFILE(symtab)	((symtab)->objfile)
-#define SYMTAB_PSPACE(symtab)	(SYMTAB_OBJFILE (symtab)->pspace)
-#define SYMTAB_DIRNAME(symtab)	((symtab)->dirname)
+#define COMPUNIT_OBJFILE(cust) ((cust)->objfile)
+#define COMPUNIT_FILETABS(cust) ((cust)->filetabs)
+#define COMPUNIT_DEBUGFORMAT(cust) ((cust)->debugformat)
+#define COMPUNIT_PRODUCER(cust) ((cust)->producer)
+#define COMPUNIT_DIRNAME(cust) ((cust)->dirname)
+#define COMPUNIT_BLOCKVECTOR(cust) ((cust)->blockvector)
+#define COMPUNIT_BLOCK_LINE_SECTION(cust) ((cust)->block_line_section)
+#define COMPUNIT_LOCATIONS_VALID(cust) ((cust)->locations_valid)
+#define COMPUNIT_EPILOGUE_UNWIND_VALID(cust) ((cust)->epilogue_unwind_valid)
+#define COMPUNIT_CALL_SITE_HTAB(cust) ((cust)->call_site_htab)
+#define COMPUNIT_MACRO_TABLE(cust) ((cust)->macro_table)
 
-/* Call this to set the "primary" field in struct symtab.  */
-extern void set_symtab_primary (struct symtab *, int primary);
+/* Iterate over all file tables (struct symtab) within a compunit.  */
 
-typedef struct symtab *symtab_ptr;
-DEF_VEC_P (symtab_ptr);
+#define ALL_COMPUNIT_FILETABS(cu, s) \
+  for ((s) = (cu) -> filetabs; (s) != NULL; (s) = (s) -> next)
+
+/* Return the primary symtab of CUST.  */
+
+extern struct symtab *
+  compunit_primary_filetab (const struct compunit_symtab *cust);
+
+/* Return the language of CUST.  */
+
+extern enum language compunit_language (const struct compunit_symtab *cust);
+
+typedef struct compunit_symtab *compunit_symtab_ptr;
+DEF_VEC_P (compunit_symtab_ptr);
 
 
 
@@ -1171,11 +1221,12 @@  extern void expand_symtab_containing_pc (CORE_ADDR, struct obj_section *);
 
 /* lookup full symbol table by address.  */
 
-extern struct symtab *find_pc_symtab (CORE_ADDR);
+extern struct compunit_symtab *find_pc_compunit_symtab (CORE_ADDR);
 
 /* lookup full symbol table by address and section.  */
 
-extern struct symtab *find_pc_sect_symtab (CORE_ADDR, struct obj_section *);
+extern struct compunit_symtab *
+  find_pc_sect_compunit_symtab (CORE_ADDR, struct obj_section *);
 
 extern int find_pc_line_pc_range (CORE_ADDR, CORE_ADDR *, CORE_ADDR *);
 
@@ -1432,8 +1483,8 @@  int iterate_over_some_symtabs (const char *name,
 			       int (*callback) (struct symtab *symtab,
 						void *data),
 			       void *data,
-			       struct symtab *first,
-			       struct symtab *after_last);
+			       struct compunit_symtab *first,
+			       struct compunit_symtab *after_last);
 
 void iterate_over_symtabs (const char *name,
 			   int (*callback) (struct symtab *symtab,