OSDN Git Service

* builtins.def: Alphabetize.
[pf3gnuchains/gcc-fork.git] / gcc / line-map.c
index 1cd1bfd..f04350d 100644 (file)
@@ -25,52 +25,58 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 #include "line-map.h"
 #include "intl.h"
 
+static void trace_include (const struct line_maps *, const struct line_map *);
+
 /* Initialize a line map set.  */
 
 void
-init_line_maps (set)
-     struct line_maps *set;
+linemap_init (struct line_maps *set)
 {
   set->maps = 0;
   set->allocated = 0;
   set->used = 0;
   set->last_listed = -1;
+  set->trace_includes = false;
+  set->depth = 0;
 }
 
 /* Free a line map set.  */
 
 void
-free_line_maps (set)
-     struct line_maps *set;
+linemap_free (struct line_maps *set)
 {
   if (set->maps)
     {
-#ifdef ENABLE_CHECKING
       struct line_map *map;
 
+      /* Depending upon whether we are handling preprocessed input or
+        not, this can be a user error or an ICE.  */
       for (map = CURRENT_LINE_MAP (set); ! MAIN_FILE_P (map);
           map = INCLUDED_FROM (set, map))
        fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
                 map->to_file);
-#endif
+
       free (set->maps);
     }
 }
 
 /* Add a mapping of logical source line to physical source file and
-   line number.  Ther text pointed to by TO_FILE must have a lifetime
-   at least as long as the final call to lookup_line ().
+   line number.
+
+   The text pointed to by TO_FILE must have a lifetime
+   at least as long as the final call to lookup_line ().  An empty
+   TO_FILE means standard input.  If reason is LC_LEAVE, and
+   TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
+   natural values considering the file we are returning to.
 
    FROM_LINE should be monotonic increasing across calls to this
-   function.  */
-
-struct line_map *
-add_line_map (set, reason, from_line, to_file, to_line)
-     struct line_maps *set;
-     enum lc_reason reason;
-     unsigned int from_line;
-     const char *to_file;
-     unsigned int to_line;
+   function.  A call to this function can relocate the previous set of
+   maps, so any stored line_map pointers should not be used.  */
+
+const struct line_map *
+linemap_add (struct line_maps *set, enum lc_reason reason,
+            unsigned int sysp, unsigned int from_line,
+            const char *to_file, unsigned int to_line)
 {
   struct line_map *map;
 
@@ -80,40 +86,77 @@ add_line_map (set, reason, from_line, to_file, to_line)
   if (set->used == set->allocated)
     {
       set->allocated = 2 * set->allocated + 256;
-      set->maps = (struct line_map *)
-       xrealloc (set->maps, set->allocated * sizeof (struct line_map));
+      set->maps = xrealloc (set->maps, set->allocated * sizeof (struct line_map));
     }
 
-  map = &set->maps[set->used];
-  map->from_line = from_line;
-  map->to_file = to_file;
-  map->to_line = to_line;
+  map = &set->maps[set->used++];
+
+  if (to_file && *to_file == '\0')
+    to_file = "<stdin>";
 
   /* If we don't keep our line maps consistent, we can easily
      segfault.  Don't rely on the client to do it for us.  */
-  if (set->used == 0)
+  if (set->depth == 0)
     reason = LC_ENTER;
   else if (reason == LC_LEAVE)
     {
-      if (MAIN_FILE_P (map - 1)
-         || strcmp (INCLUDED_FROM (set, map - 1)->to_file, to_file))
+      struct line_map *from;
+      bool error;
+
+      if (MAIN_FILE_P (map - 1))
+       {
+         if (to_file == NULL)
+           {
+             set->depth--;
+             set->used--;
+             return NULL;
+           }
+         error = true;
+          reason = LC_RENAME;
+          from = map - 1;
+       }
+      else
        {
-#ifdef ENABLE_CHECKING
-         fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n",
-                  to_file);
-#endif
-         reason = LC_RENAME;
+         from = INCLUDED_FROM (set, map - 1);
+         error = to_file && strcmp (from->to_file, to_file);
+       }
+
+      /* Depending upon whether we are handling preprocessed input or
+        not, this can be a user error or an ICE.  */
+      if (error)
+       fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n",
+                to_file);
+
+      /* A TO_FILE of NULL is special - we use the natural values.  */
+      if (error || to_file == NULL)
+       {
+         to_file = from->to_file;
+         to_line = LAST_SOURCE_LINE (from) + 1;
+         sysp = from->sysp;
        }
     }
 
+  map->reason = reason;
+  map->sysp = sysp;
+  map->from_line = from_line;
+  map->to_file = to_file;
+  map->to_line = to_line;
+
   if (reason == LC_ENTER)
-    map->included_from = set->used - 1;
+    {
+      map->included_from = set->depth == 0 ? -1 : (int) (set->used - 2);
+      set->depth++;
+      if (set->trace_includes)
+       trace_include (set, map);
+    }
   else if (reason == LC_RENAME)
     map->included_from = map[-1].included_from;
   else if (reason == LC_LEAVE)
-    map->included_from = INCLUDED_FROM (set, map - 1)->included_from;
+    {
+      set->depth--;
+      map->included_from = INCLUDED_FROM (set, map - 1)->included_from;
+    }
 
-  set->used++;
   return map;
 }
 
@@ -122,10 +165,8 @@ add_line_map (set, reason, from_line, to_file, to_line)
    chronologically, the logical lines are monotonic increasing, and so
    the list is sorted and we can use a binary search.  */
 
-struct line_map *
-lookup_line (set, line)
-     struct line_maps *set;
-     unsigned int line;
+const struct line_map *
+linemap_lookup (struct line_maps *set, unsigned int line)
 {
   unsigned int md, mn = 0, mx = set->used;
 
@@ -149,9 +190,8 @@ lookup_line (set, line)
    the most recently listed stack is the same as the current one.  */
 
 void
-print_containing_files (set, map)
-     struct line_maps *set;
-     struct line_map *map;
+linemap_print_containing_files (struct line_maps *set,
+                               const struct line_map *map)
 {
   if (MAIN_FILE_P (map) || set->last_listed == map->included_from)
     return;
@@ -183,3 +223,15 @@ print_containing_files (set, map)
 
   fputs (":\n", stderr);
 }
+
+/* Print an include trace, for e.g. the -H option of the preprocessor.  */
+
+static void
+trace_include (const struct line_maps *set, const struct line_map *map)
+{
+  unsigned int i = set->depth;
+
+  while (--i)
+    putc ('.', stderr);
+  fprintf (stderr, " %s\n", map->to_file);
+}