This patch changes the way line-maps hold the included-from information. Currently this is an index to another (earlier) line-map, and relies on the fact that #include cause the termination of the current map and emission of a new map. It's then possible to determine the location of the include directive as the last line of the just terminated line map (by examining the first location of the next map).

With modules, I'd like to show the import path in a similar way. But importing a module doesn't (necessarily) cause termination of a line map -- the imported module's 'imported-from' location is in the middle of some other map. Here's what that looks like:
In file of module bob,
          imported at loc-2_b.C:5,
        of module stuart,
          imported at loc-2_d.C:2:
loc-2_a.C:5:18: note:   initializing argument 1 of 'int frob(int*)'

[included-from lines may appear in the middle of that stack too]

Thus, this patch uses a source_location to represent the included from location. No data size changes, as old and new forms are really ints. IMHO it makes the interface somewhat cleaner, as we stop exposing the map indexes to the library users.

[I noticed that a piece of this patch already escaped, we were using LAST_SOURCE_COLUMN in diagnostic_report_current_module, but I'd inadvertently changed that in the prepatch that was intended to prepare the ground for this one. Sorry.]

booted & tested on x86_64-linux, ok?

nathan
--
Nathan Sidwell
2018-08-08  Nathan Sidwell  <nat...@acm.org>

	Make linemap::included_at a location
	libcpp/
	* include/line-map.h (struct line_map_ordinary): Replace
	included_from map index with included_at source_location.
	(ORDINARY_MAP_INCLUDER_FILE_INDEX): Delete.
	(LAST_SOURCE_LINE_LOCATION): Move to line-map.c.
	(LAST_SOURCE_COLUMN): Delete.
	(INCLUDED_AT): New.
	(linemap_included_at): Declare.
	(MAIN_FILE_P): Adjust.
	* line-map.c (linemap_included_at): New.
	(lonemap_check_files_exited): Use linemap_included_at.
	(LAST_SOURCE_LINE_LOCATION): Made internal from header file.
	(linemap_add): Adjust inclusion setting.
	(linemap_dump, linemap_dump_location): Adjust.
	* directives.c (do_linemarker): Use linemap_included_at.
	gcc/
	* diagnostic.c (diagnostic_report_current_module): Use INCLUDED_AT
	& linemap_included_at.
	gcc/c-family/
	* c-common.c (try_to_locate_new_include_inertion_point): Use
	linemap_included_at.
	* c-lex.c (fe_file_change): Use INCLUDED_AT.
	* c-ppoutput.c (pp_file_change): Likewise.
	gcc/fortran/
	* cpp.c (cb_file_change): Use INCLUDED_AT.

Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 263365)
+++ gcc/c-family/c-common.c	(working copy)
@@ -8413,8 +8413,8 @@ try_to_locate_new_include_insertion_poin
       const line_map_ordinary *ord_map
 	= LINEMAPS_ORDINARY_MAP_AT (line_table, i);
 
-      const line_map_ordinary *from = INCLUDED_FROM (line_table, ord_map);
-      if (from)
+      if (const line_map_ordinary *from
+	  = linemap_included_at (line_table, ord_map))
 	if (from->to_file == file)
 	  {
 	    last_include_ord_map = from;
Index: gcc/c-family/c-lex.c
===================================================================
--- gcc/c-family/c-lex.c	(revision 263365)
+++ gcc/c-family/c-lex.c	(working copy)
@@ -199,7 +199,7 @@ fe_file_change (const line_map_ordinary
 	 we already did in compile_file.  */
       if (!MAIN_FILE_P (new_map))
 	{
-	  unsigned int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1);
+	  location_t included_at = INCLUDED_AT (new_map);
 	  int line = 0;
 	  if (included_at > BUILTINS_LOCATION)
 	    line = SOURCE_LINE (new_map - 1, included_at);
Index: gcc/c-family/c-ppoutput.c
===================================================================
--- gcc/c-family/c-ppoutput.c	(revision 263365)
+++ gcc/c-family/c-ppoutput.c	(working copy)
@@ -663,11 +663,9 @@ pp_file_change (const line_map_ordinary
 	  /* Bring current file to correct line when entering a new file.  */
 	  if (map->reason == LC_ENTER)
 	    {
-	      const line_map_ordinary *from = INCLUDED_FROM (line_table, map);
-	      maybe_print_line (LAST_SOURCE_LINE_LOCATION (from));
+	      maybe_print_line (INCLUDED_AT (map));
+	      flags = " 1";
 	    }
-	  if (map->reason == LC_ENTER)
-	    flags = " 1";
 	  else if (map->reason == LC_LEAVE)
 	    flags = " 2";
 	  print_line (map->start_location, flags);
Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c	(revision 263365)
+++ gcc/diagnostic.c	(working copy)
@@ -590,9 +590,10 @@ diagnostic_report_current_module (diagno
 	  bool first = true;
 	  do
 	    {
-	      map = INCLUDED_FROM (line_table, map);
+	      where = INCLUDED_AT (map);
+	      map = linemap_included_at (line_table, map);
 	      const char *line_col
-		= maybe_line_and_column (LAST_SOURCE_LINE (map),
+		= maybe_line_and_column (SOURCE_LINE (map, where),
 					 first && context->show_column
 					 ? SOURCE_COLUMN (map, where) : 0);
 	      static const char *const msgs[] =
Index: gcc/fortran/cpp.c
===================================================================
--- gcc/fortran/cpp.c	(revision 263365)
+++ gcc/fortran/cpp.c	(working copy)
@@ -881,10 +881,7 @@ cb_file_change (cpp_reader * ARG_UNUSED
 	{
 	  /* Bring current file to correct line when entering a new file.  */
 	  if (map->reason == LC_ENTER)
-	    {
-	      const line_map_ordinary *from = INCLUDED_FROM (line_table, map);
-	      maybe_print_line (LAST_SOURCE_LINE_LOCATION (from));
-	    }
+	    maybe_print_line (INCLUDED_AT (map));
 	  if (map->reason == LC_ENTER)
 	    flags = " 1";
 	  else if (map->reason == LC_LEAVE)
Index: libcpp/directives.c
===================================================================
--- libcpp/directives.c	(revision 263365)
+++ libcpp/directives.c	(working copy)
@@ -1088,10 +1088,9 @@ do_linemarker (cpp_reader *pfile)
       /* Reread map since cpp_get_token can invalidate it with a
 	 reallocation.  */
       map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
-      const line_map_ordinary *from;      
+      const line_map_ordinary *from = linemap_included_at (line_table, map);
       if (MAIN_FILE_P (map)
-	  || (new_file
-	      && (from = INCLUDED_FROM (pfile->line_table, map)) != NULL
+	  || (from
 	      && filename_cmp (ORDINARY_MAP_FILE_NAME (from), new_file) != 0))
 	{
 	  cpp_warning (pfile, CPP_W_NONE,
Index: libcpp/include/line-map.h
===================================================================
--- libcpp/include/line-map.h	(revision 263365)
+++ libcpp/include/line-map.h	(working copy)
@@ -440,10 +440,10 @@ struct GTY((tag ("1"))) line_map_ordinar
   const char *to_file;
   linenum_type to_line;
 
-  /* An index into the set that gives the line mapping at whose end
-     the current one was included.  File(s) at the bottom of the
-     include stack have this set to -1.  */
-  int included_from;
+  /* Location at which this line map was included from.  For regular
+     #includes, this location will be the last location of a map.  For
+     outermost file, this is 0.  */
+  source_location included_at;
 
   /* Size is 20 or 24 bytes, no padding  */
 };
@@ -634,17 +634,6 @@ ORDINARY_MAP_STARTING_LINE_NUMBER (const
   return ord_map->to_line;
 }
 
-/* Get the index of the ordinary map at whose end
-   ordinary map MAP was included.
-
-   File(s) at the bottom of the include stack have this set.  */
-
-inline int
-ORDINARY_MAP_INCLUDER_FILE_INDEX (const line_map_ordinary *ord_map)
-{
-  return ord_map->included_from;
-}
-
 /* Return a positive value if map encodes locations from a system
    header, 0 otherwise. Returns 1 if ordinary map MAP encodes locations
    in a system header and 2 if it encodes locations in a C system header
@@ -1192,51 +1181,23 @@ SOURCE_COLUMN (const line_map_ordinary *
 	  & ((1 << ord_map->m_column_and_range_bits) - 1)) >> ord_map->m_range_bits;
 }
 
-/* Return the location of the last source line within an ordinary
-   map.  */
-inline source_location
-LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map)
-{
-  return (((map[1].start_location - 1
-	    - map->start_location)
-	   & ~((1 << map->m_column_and_range_bits) - 1))
-	  + map->start_location);
-}
-
-/* Returns the last source line number within an ordinary map.  This
-   is the (last) line of the #include, or other directive, that caused
-   a map change.  */
-inline linenum_type
-LAST_SOURCE_LINE (const line_map_ordinary *map)
-{
-  return SOURCE_LINE (map, LAST_SOURCE_LINE_LOCATION (map));
-}
 
-/* Return the last column number within an ordinary map.  */
-
-inline linenum_type
-LAST_SOURCE_COLUMN (const line_map_ordinary *map)
+inline source_location
+INCLUDED_AT (const line_map_ordinary *ord_map)
 {
-  return SOURCE_COLUMN (map, LAST_SOURCE_LINE_LOCATION (map));
+  return ord_map->included_at;
 }
 
-/* Returns the map a given map was included from, or NULL if the map
-   belongs to the main file, i.e, a file that wasn't included by
-   another one.  */
-inline line_map_ordinary *
-INCLUDED_FROM (struct line_maps *set, const line_map_ordinary *ord_map)
-{
-  return ((ord_map->included_from == -1)
-	  ? NULL
-	  : LINEMAPS_ORDINARY_MAP_AT (set, ord_map->included_from));
-}
+/* The linemap containing the included-from location.  */
+const line_map_ordinary *linemap_included_at (line_maps *set,
+					      const line_map_ordinary *);
 
 /* True if the map is at the bottom of the include stack.  */
 
 inline bool
 MAIN_FILE_P (const line_map_ordinary *ord_map)
 {
-  return ord_map->included_from < 0;
+  return ord_map->included_at == 0;
 }
 
 /* Encode and return a source_location from a column number. The
Index: libcpp/line-map.c
===================================================================
--- libcpp/line-map.c	(revision 263366)
+++ libcpp/line-map.c	(working copy)
@@ -355,17 +355,25 @@ linemap_init (struct line_maps *set,
   set->builtin_location = builtin_location;
 }
 
+/* Return the ordinary line map from whence MAP was included.  Returns
+   NULL if MAP was not an included.  */
+
+const line_map_ordinary *
+linemap_included_at (line_maps *set, const line_map_ordinary *map)
+{
+  return linemap_ordinary_map_lookup (set, INCLUDED_AT (map));
+}
+
 /* Check for and warn about line_maps entered but not exited.  */
 
 void
 linemap_check_files_exited (struct line_maps *set)
 {
-  const line_map_ordinary *map;
   /* Depending upon whether we are handling preprocessed input or
      not, this can be a user error or an ICE.  */
-  for (map = LINEMAPS_LAST_ORDINARY_MAP (set);
+  for (const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
        ! MAIN_FILE_P (map);
-       map = INCLUDED_FROM (set, map))
+       map = linemap_included_at (set, map))
     fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
 	     ORDINARY_MAP_FILE_NAME (map));
 }
@@ -435,6 +443,17 @@ new_linemap (struct line_maps *set,  sou
   return result;
 }
 
+/* Return the location of the last source line within an ordinary
+   map.  */
+inline source_location
+LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map)
+{
+  return (((map[1].start_location - 1
+	    - map->start_location)
+	   & ~((1 << map->m_column_and_range_bits) - 1))
+	  + map->start_location);
+}
+
 /* Add a mapping of logical source line to physical source file and
    line number.
 
@@ -494,19 +513,19 @@ linemap_add (struct line_maps *set, enum
   if (reason == LC_RENAME_VERBATIM)
     reason = LC_RENAME;
 
+  const line_map_ordinary *from = NULL;
   if (reason == LC_LEAVE)
     {
       /* When we are just leaving an "included" file, and jump to the next
 	 location inside the "includer" right after the #include
 	 "included", this variable points the map in use right before the
 	 #include "included", inside the same "includer" file.  */
-      line_map_ordinary *from;
 
       linemap_assert (!MAIN_FILE_P (map - 1));
       /* (MAP - 1) points to the map we are leaving. The
 	 map from which (MAP - 1) got included should be the map
 	 that comes right before MAP in the same file.  */
-      from = INCLUDED_FROM (set, map - 1);
+      from = linemap_included_at (set, map - 1);
 
       /* A TO_FILE of NULL is special - we use the natural values.  */
       if (to_file == NULL)
@@ -538,19 +557,20 @@ linemap_add (struct line_maps *set, enum
 
   if (reason == LC_ENTER)
     {
-      map->included_from =
-	set->depth == 0 ? -1 : (int) (LINEMAPS_ORDINARY_USED (set) - 2);
+      if (set->depth == 0)
+	map->included_at = 0;
+      else
+	map->included_at = LAST_SOURCE_LINE_LOCATION (map - 1);
       set->depth++;
       if (set->trace_includes)
 	trace_include (set, map);
     }
   else if (reason == LC_RENAME)
-    map->included_from = ORDINARY_MAP_INCLUDER_FILE_INDEX (&map[-1]);
+    map->included_at = INCLUDED_AT (&map[-1]);
   else if (reason == LC_LEAVE)
     {
       set->depth--;
-      map->included_from =
-	ORDINARY_MAP_INCLUDER_FILE_INDEX (INCLUDED_FROM (set, map - 1));
+      map->included_at = INCLUDED_AT (from);
     }
 
   return map;
@@ -1761,17 +1781,12 @@ linemap_dump (FILE *stream, struct line_
   if (!is_macro)
     {
       const line_map_ordinary *ord_map = linemap_check_ordinary (map);
-      unsigned includer_ix;
-      const line_map_ordinary *includer_map;
-
-      includer_ix = ORDINARY_MAP_INCLUDER_FILE_INDEX (ord_map);
-      includer_map = includer_ix < LINEMAPS_ORDINARY_USED (set)
-		     ? LINEMAPS_ORDINARY_MAP_AT (set, includer_ix)
-		     : NULL;
+      const line_map_ordinary *includer_map = linemap_included_at (set, ord_map);
 
       fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map),
 	       ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
-      fprintf (stream, "Included from: [%d] %s\n", includer_ix,
+      fprintf (stream, "Included from: [%d] %s\n",
+	       includer_map ? int (includer_map - set->info_ordinary.maps) : -1,
 	       includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
     }
   else
@@ -1821,9 +1836,10 @@ linemap_dump_location (struct line_maps
       if (e)
 	from = "N/A";
       else
-	from = (INCLUDED_FROM (set, map))
-	  ? LINEMAP_FILE (INCLUDED_FROM (set, map))
-	  : "<NULL>";
+	{
+	  const line_map_ordinary *from_map = linemap_included_at (set, map);
+	  from = from_map ? LINEMAP_FILE (from_map) : "<NULL>";
+	}
     }
 
   /* P: path, L: line, C: column, S: in-system-header, M: map address,

Reply via email to