Use a location_t to track the position of LINE_T's.  Use the linemap
associated with the location to track the file name the line belongs
to.

gcc/algol68/ChangeLog:

        * a68-low-bits.cc (a68_bits_elem): Use LINE_NUMBER (p) instead
        of NUMBER (LINE (INFO (p))).
        * a68-low-chars.cc (a68_char_repr): Likewise.
        * a68-low-coercions.cc (a68_lower_uniting): Likewise.
        * a68-low-misc.cc (a68_lower_assertion): Likewise.
        * a68-low-multiples.cc (a68_multiple_slice): Likewise.
        (a68_multiple_single_bound_check): Likewise.
        (a68_boundable_dim_check): Likewise.
        (a68_multiple_bounds_check): Likewise.
        (a68_multiple_bounds_check_equal): Likewise.
        * a68-low.cc (a68_checked_indirect_ref): Likewise.
        * a68-parser-scanner.cc (new_source_line): Adjust the fields
        when creating a LINE_T.
        (append_source_line): Add a location_t to the new line.
        (append_environ): Track the locations of pre/post-lude.
        (read_source_file): Create a linemap for the source file.
        (include_files):  Create a linemap for included source files.
        * a68-parser-top-down.cc (a68_phrase_to_text): Use unsigned
        for line numbers.
        * a68-parser.cc (a68_get_node_location): Return the location of
        the node info line.
        (a68_get_line_location): Return the location of the line.
        * a68-pretty-print.h (a68_line_format_token): Use the line's
        filename to check if it's part of the standard environment.
        * a68-types.h (struct LINE_T): Remove filename and number
        fields from LINE_T and add location.
        (FILENAME): Delete macro.
        (LOCATION): New macro.
        (LINE_NUMBER): Adjust to use LINE_NO (line).
        * a68.h (FILENAME): New function.
        (LINE_NO): Likewise.

Signed-off-by: Pietro Monteiro <[email protected]>
---
 gcc/algol68/a68-low-bits.cc        |  2 +-
 gcc/algol68/a68-low-chars.cc       |  2 +-
 gcc/algol68/a68-low-coercions.cc   |  2 +-
 gcc/algol68/a68-low-misc.cc        |  2 +-
 gcc/algol68/a68-low-multiples.cc   | 10 +++----
 gcc/algol68/a68-low.cc             |  2 +-
 gcc/algol68/a68-parser-scanner.cc  | 45 +++++++++++++++++++-----------
 gcc/algol68/a68-parser-top-down.cc |  3 +-
 gcc/algol68/a68-parser.cc          | 25 +++++------------
 gcc/algol68/a68-pretty-print.h     |  7 +++--
 gcc/algol68/a68-types.h            |  7 ++---
 gcc/algol68/a68.h                  | 24 ++++++++++++++++
 12 files changed, 78 insertions(+), 53 deletions(-)

diff --git a/gcc/algol68/a68-low-bits.cc b/gcc/algol68/a68-low-bits.cc
index 1857b830cb1..2a4cd8b5ada 100644
--- a/gcc/algol68/a68-low-bits.cc
+++ b/gcc/algol68/a68-low-bits.cc
@@ -216,7 +216,7 @@ a68_bits_elem (NODE_T *p, tree pos, tree bits)
   /* Do bounds checking if requested.  */
   if (OPTION_BOUNDS_CHECKING (&A68_JOB))
     {
-      unsigned int lineno = NUMBER (LINE (INFO (p)));
+      unsigned int lineno = LINE_NUMBER (p);
       const char *filename_str = FILENAME (LINE (INFO (p)));
       tree filename = build_string_literal (strlen (filename_str) + 1,
                                            filename_str);
diff --git a/gcc/algol68/a68-low-chars.cc b/gcc/algol68/a68-low-chars.cc
index 90aa6f547ec..381e455b7f1 100644
--- a/gcc/algol68/a68-low-chars.cc
+++ b/gcc/algol68/a68-low-chars.cc
@@ -89,7 +89,7 @@ a68_char_repr (NODE_T *p, tree val)
                                            range1, range2));
 
   /* Call to the runtime run-time error handler.  */
-  unsigned int lineno = NUMBER (LINE (INFO (p)));
+  unsigned int lineno = LINE_NUMBER (p);
   const char *filename_str = FILENAME (LINE (INFO (p)));
   tree filename = build_string_literal (strlen (filename_str) + 1,
                                            filename_str);
diff --git a/gcc/algol68/a68-low-coercions.cc b/gcc/algol68/a68-low-coercions.cc
index 3941917223f..54079122880 100644
--- a/gcc/algol68/a68-low-coercions.cc
+++ b/gcc/algol68/a68-low-coercions.cc
@@ -117,7 +117,7 @@ a68_lower_uniting (NODE_T *p, LOW_CTX_T ctx)
 
          /* This should not be reached.  Emit run-time error.  */
          {
-           unsigned int lineno = NUMBER (LINE (INFO (p)));
+           unsigned int lineno = LINE_NUMBER (p);
            const char *filename_str = FILENAME (LINE (INFO (p)));
            tree filename = build_string_literal (strlen (filename_str) + 1,
                                                  filename_str);
diff --git a/gcc/algol68/a68-low-misc.cc b/gcc/algol68/a68-low-misc.cc
index b1048b6b8ca..8d0d157e5b3 100644
--- a/gcc/algol68/a68-low-misc.cc
+++ b/gcc/algol68/a68-low-misc.cc
@@ -54,7 +54,7 @@ a68_lower_assertion (NODE_T *p, LOW_CTX_T ctx)
     return a68_get_empty();
 
   /* Build the call to the assert run-time function.  */
-  unsigned int lineno = NUMBER (LINE (INFO (p)));
+  unsigned int lineno = LINE_NUMBER (p);
   const char *filename_str = FILENAME (LINE (INFO (p)));
   tree filename = build_string_literal (strlen (filename_str) + 1,
                                        filename_str);
diff --git a/gcc/algol68/a68-low-multiples.cc b/gcc/algol68/a68-low-multiples.cc
index b72f8bbb89a..3f63d7d93b2 100644
--- a/gcc/algol68/a68-low-multiples.cc
+++ b/gcc/algol68/a68-low-multiples.cc
@@ -525,7 +525,7 @@ a68_multiple_slice (NODE_T *p,
       if (OPTION_BOUNDS_CHECKING (&A68_JOB))
        {
          tree upper_bound = a68_multiple_upper_bound (multiple, size_int 
(idx));
-         unsigned int lineno = NUMBER (LINE (INFO (p)));
+         unsigned int lineno = LINE_NUMBER (p);
          const char *filename_str = FILENAME (LINE (INFO (p)));
          tree filename = build_string_literal (strlen (filename_str) + 1,
                                                    filename_str);
@@ -858,7 +858,7 @@ a68_multiple_single_bound_check (NODE_T *p, tree dim,
                            : A68_LIBCALL_ARRAYLOWERBOUND);
 
   /* Build the call to ARRAY*BOUNDS. */
-  unsigned int lineno = NUMBER (LINE (INFO (p)));
+  unsigned int lineno = LINE_NUMBER (p);
   const char *filename_str = FILENAME (LINE (INFO (p)));
   tree filename = build_string_literal (strlen (filename_str) + 1,
                                        filename_str);
@@ -897,7 +897,7 @@ a68_boundable_dim_check (NODE_T *p, tree boundable_dim, 
tree dim)
   dim = save_expr (dim);
 
   /* Build the call to ARRAYDIM. */
-  unsigned int lineno = NUMBER (LINE (INFO (p)));
+  unsigned int lineno = LINE_NUMBER (p);
   const char *filename_str = FILENAME (LINE (INFO (p)));
   tree filename = build_string_literal (strlen (filename_str) + 1,
                                        filename_str);
@@ -965,7 +965,7 @@ a68_multiple_bounds_check (NODE_T *p, tree dim,
   tree lower_bound = a68_multiple_lower_bound (multiple, dim);
 
   /* Build the call to ARRAYBOUNDS. */
-  unsigned int lineno = NUMBER (LINE (INFO (p)));
+  unsigned int lineno = LINE_NUMBER (p);
   const char *filename_str = FILENAME (LINE (INFO (p)));
   tree filename = build_string_literal (strlen (filename_str) + 1,
                                        filename_str);
@@ -1043,7 +1043,7 @@ a68_multiple_bounds_check_equal (NODE_T *p, tree m1, tree 
m2)
                                       fold_build2 (EQ_EXPR, boolean_type_node,
                                                    ub1, ub2));
 
-      unsigned int lineno = NUMBER (LINE (INFO (p)));
+      unsigned int lineno = LINE_NUMBER (p);
       const char *filename_str = FILENAME (LINE (INFO (p)));
       tree filename = build_string_literal (strlen (filename_str) + 1,
                                            filename_str);
diff --git a/gcc/algol68/a68-low.cc b/gcc/algol68/a68-low.cc
index 40636601c03..ea69206c5cc 100644
--- a/gcc/algol68/a68-low.cc
+++ b/gcc/algol68/a68-low.cc
@@ -673,7 +673,7 @@ a68_checked_indirect_ref (NODE_T *p, tree exp, MOID_T 
*exp_mode)
       tree consolidated_exp = a68_consolidate_ref (exp_mode, exp);
 
       /* Check whether we are dereferencing NIL.  */
-      unsigned int lineno = NUMBER (LINE (INFO (p)));
+      unsigned int lineno = LINE_NUMBER (p);
       const char *filename_str = FILENAME (LINE (INFO (p)));
       tree filename = build_string_literal (strlen (filename_str) + 1,
                                            filename_str);
diff --git a/gcc/algol68/a68-parser-scanner.cc 
b/gcc/algol68/a68-parser-scanner.cc
index 5ddf25894a2..ce8df69d111 100644
--- a/gcc/algol68/a68-parser-scanner.cc
+++ b/gcc/algol68/a68-parser-scanner.cc
@@ -219,8 +219,7 @@ new_source_line (void)
 
   MARKER (z)[0] = '\0';
   STRING (z) = NO_TEXT;
-  FILENAME (z) = NO_TEXT;
-  NUMBER (z) = 0;
+  LOCATION (z) = UNKNOWN_LOCATION;
   NEXT (z) = NO_LINE;
   PREVIOUS (z) = NO_LINE;
   return z;
@@ -229,15 +228,15 @@ new_source_line (void)
 /* Append a source line to the internal source file.  */
 
 static void
-append_source_line (const char *str, LINE_T **ref_l, int *line_num,
-                   const char *filename)
+append_source_line (const char *str, LINE_T **ref_l, int *line_num)
 {
   LINE_T *z = new_source_line ();
 
   /* Link line into the chain.  */
   STRING (z) = xstrdup (str);
-  FILENAME (z) = ggc_strdup (filename);
-  NUMBER (z) = (*line_num)++;
+  LOCATION (z) = linemap_line_start (line_table,
+                                    (*line_num)++,
+                                    80 /* max_column_hint */);
   NEXT (z) = NO_LINE;
   PREVIOUS (z) = *ref_l;
   if (TOP_LINE (&A68_JOB) == NO_LINE)
@@ -250,14 +249,15 @@ append_source_line (const char *str, LINE_T **ref_l, int 
*line_num,
 /* Append environment source lines.  */
 
 static void
-append_environ (const char *str[], LINE_T **ref_l, int *line_num, const char 
*name)
+append_environ (const char *str[], LINE_T **ref_l, const char *name)
 {
+  linemap_add (line_table, LC_ENTER, 1 /* sys_p */, name, 0 /* to_line */);
   for (int k = 0; str[k] != NO_TEXT; k++)
     {
-      int zero_line_num = 0;
-      (*line_num)++;
-      append_source_line (str[k], ref_l, &zero_line_num, name);
+      int line_num = 1;
+      append_source_line (str[k], ref_l, &line_num);
     }
+  linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
 }
 
 /*
@@ -292,7 +292,7 @@ read_source_file (const char *filename)
 {
   struct stat statbuf;
   LINE_T *ref_l = NO_LINE;
-  int line_num = 0;
+  int line_num;
   size_t k;
   size_t bytes_read;
   ssize_t l;
@@ -328,13 +328,14 @@ read_source_file (const char *filename)
   /* Prelude.  */
   append_environ (OPTION_STROPPING (&A68_JOB) == UPPER_STROPPING
                  ? upper_prelude_start : supper_prelude_start,
-                 &ref_l, &line_num, "prelude");
+                 &ref_l, "prelude");
 
   /* Read the file into a single buffer, so we save on system calls.  */
   line_num = 1;
   buffer = (char *) xmalloc (8 + source_file_size);
   bytes_read = a68_file_read (fileno (f), buffer, source_file_size);
   gcc_assert (bytes_read == source_file_size);
+  linemap_add (line_table, LC_ENTER, 0 /* sys_p */, filename, 0 /* to_line */);
 
   /* Link all lines into the list.  */
   k = 0;
@@ -357,20 +358,27 @@ read_source_file (const char *filename)
       A68_PARSER (scan_buf)[l] = '\0';
       if (k < source_file_size)
        k++;
-      append_source_line (A68_PARSER (scan_buf), &ref_l, &line_num,
-                         FILE_SOURCE_NAME (&A68_JOB));
+      append_source_line (A68_PARSER (scan_buf), &ref_l, &line_num);
       SCAN_ERROR (l != (ssize_t) strlen (A68_PARSER (scan_buf)),
                  NO_LINE, NO_TEXT, "invalid characters in source file");
     }
 
+  /* Extra line before adding postlude.  */
+  linemap_line_start (line_table,
+                     line_num,
+                     80 /* max_column_hint */);
+
   /* Postlude.  */
   append_environ (OPTION_STROPPING (&A68_JOB) == UPPER_STROPPING
                  ? upper_postlude : supper_postlude,
-                 &ref_l, &line_num, "postlude");
+                 &ref_l, "postlude");
 
   /* Include files.  */
   include_files (TOP_LINE (&A68_JOB));
 
+  linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
+  linemap_check_files_exited (line_table);
+
   if (fclose (FILE_SOURCE_FD (&A68_JOB)) != 0)
     gcc_unreachable ();
   return ret;
@@ -1060,6 +1068,8 @@ include_files (LINE_T *top)
              SCAN_ERROR ((size_t) bytes_read != fsize, start_l, start_c,
                          "error while reading file");
 
+             linemap_add (line_table, LC_ENTER, 0 /* sys_p */, fn,
+                          0 /* to_line */);
              /* Buffer still usable?.  */
              if (fsize > A68_PARSER (max_scan_buf_length))
                {
@@ -1077,7 +1087,7 @@ include_files (LINE_T *top)
                  /* If file is empty, insert single empty line.  */
                  A68_PARSER (scan_buf)[0] = NEWLINE_CHAR;
                  A68_PARSER (scan_buf)[1] = NULL_CHAR;
-                 append_source_line (A68_PARSER (scan_buf), &t, &linum, fn);
+                 append_source_line (A68_PARSER (scan_buf), &t, &linum);
                }
              else
                {
@@ -1098,11 +1108,12 @@ include_files (LINE_T *top)
                      A68_PARSER (scan_buf)[n] = NULL_CHAR;
                      if (k < fsize)
                        k++;
-                     append_source_line (A68_PARSER (scan_buf), &t, &linum, 
fn);
+                     append_source_line (A68_PARSER (scan_buf), &t, &linum);
                    }
                }
 
              /* Conclude and go find another include directive, if any.  */
+             linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
              NEXT (t) = s;
              PREVIOUS (s) = t;
              if (fclose (fp) != 0)
diff --git a/gcc/algol68/a68-parser-top-down.cc 
b/gcc/algol68/a68-parser-top-down.cc
index 238749fcb66..b3f332101b8 100644
--- a/gcc/algol68/a68-parser-top-down.cc
+++ b/gcc/algol68/a68-parser-top-down.cc
@@ -64,7 +64,8 @@ const char *
 a68_phrase_to_text (NODE_T * p, NODE_T ** w)
 {
 #define MAX_TERMINALS 8
-  int count = 0, line = -1;
+  int count = 0;
+  unsigned int line = 0;
   static BUFFER buffer;
 
   for (buffer[0] = '\0'; p != NO_NODE && count < MAX_TERMINALS; FORWARD (p))
diff --git a/gcc/algol68/a68-parser.cc b/gcc/algol68/a68-parser.cc
index 4303d5297e8..878d9d6cd9b 100644
--- a/gcc/algol68/a68-parser.cc
+++ b/gcc/algol68/a68-parser.cc
@@ -1153,18 +1153,9 @@ a68_get_node_location (NODE_T *p)
   if (line == NO_LINE)
     return UNKNOWN_LOCATION;
 
-  unsigned line_number = NUMBER (line);
-  unsigned column_number = CHAR_IN_LINE (INFO (p)) - STRING (line) + 1;
-  const char *filename = FILENAME (line);
-
-  location_t gcc_location;
-
-  linemap_add (line_table, LC_ENTER, 0, filename, line_number);
-  linemap_line_start (line_table, line_number, 0);
-  gcc_location = linemap_position_for_column (line_table, column_number);
-  linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
-
-  return gcc_location;
+  const char *start_pos = CHAR_IN_LINE (INFO (p));
+  location_t start_loc = a68_get_line_location (line, start_pos);
+  return start_loc;
 }
 
 /* Get the location of POS inside LINE as a GCC location.  */
@@ -1172,11 +1163,9 @@ a68_get_node_location (NODE_T *p)
 location_t
 a68_get_line_location (LINE_T *line, const char *pos)
 {
-  location_t loc;
-
-  linemap_add (line_table, LC_ENTER, 0, FILENAME (line), NUMBER (line));
-  linemap_line_start (line_table, NUMBER (line), 0);
-  loc = linemap_position_for_column (line_table, pos - STRING (line) + 1);
-  linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
+  unsigned column_number = pos - STRING (line) + 1;
+  location_t loc = linemap_position_for_loc_and_offset (line_table,
+                                                       LOCATION(line),
+                                                       column_number);
   return loc;
 }
diff --git a/gcc/algol68/a68-pretty-print.h b/gcc/algol68/a68-pretty-print.h
index 16dbb415b86..0b78599876f 100644
--- a/gcc/algol68/a68-pretty-print.h
+++ b/gcc/algol68/a68-pretty-print.h
@@ -223,14 +223,15 @@ public:
   a68_line_format_token (LINE_T *l, NODE_T *n)
   {
     gcc_assert (l != NO_LINE);
-    if (NUMBER (l) == 0)
+    const char *fname = FILENAME (l);
+    if (strcmp (fname, "prelude") == 0 || strcmp (fname, "postlude") == 0)
       m_str = xstrdup ("in standard environment");
-    else if (n != NO_NODE && NUMBER (l) == LINE_NUMBER (n))
+    else if (n != NO_NODE && LINE_NO (l) == LINE_NUMBER (n))
       m_str = xstrdup ("in this line");
     else
       {
        m_str = (char *) xmalloc (18);
-       if (snprintf (m_str, 18, "in line %d", NUMBER (l)) < 0)
+       if (snprintf (m_str, 18, "in line %d", LINE_NO (l)) < 0)
          gcc_unreachable ();
       }
   }
diff --git a/gcc/algol68/a68-types.h b/gcc/algol68/a68-types.h
index 5bf348890f7..472a8bb29ef 100644
--- a/gcc/algol68/a68-types.h
+++ b/gcc/algol68/a68-types.h
@@ -537,8 +537,7 @@ struct GTY((chain_next ("%h.next"))) LINE_T
 {
   char marker[6];
   char * GTY((skip)) string;
-  const char *filename;
-  int number;
+  location_t location;
   LINE_T *next, *previous;
 };
 #define NO_LINE ((LINE_T *) 0)
@@ -949,7 +948,6 @@ struct GTY(()) A68_T
 #define EXTRACT_VARIABLE(p) ((p)->variable)
 #define WARNING_COUNT(p) ((p)->warning_count)
 #define F(p) ((p)->f)
-#define FILENAME(p) ((p)->filename)
 #define FILE_SOURCE_FD(p) ((p)->file_source_fd)
 #define FILE_SOURCE_NAME(p) ((p)->file_source_name)
 #define FLEXO(p) ((p).flexo)
@@ -996,10 +994,11 @@ struct GTY(()) A68_T
 #define LEX_LEVEL(p) (LEVEL (TABLE (p)))
 #define LINBUF(p) ((p)->linbuf)
 #define LINE(p) ((p)->line)
+#define LOCATION(p) ((p)->location)
 #define LINE_APPLIED(p) ((p)->line_applied)
 #define LINE_DEFINED(p) ((p)->line_defined)
 #define LINE_END_MENDED(p) ((p)->line_end_mended)
-#define LINE_NUMBER(p) (NUMBER (LINE (INFO (p))))
+#define LINE_NUMBER(p) (LINE_NO (LINE (INFO (p))))
 #define LINSIZ(p) ((p)->linsiz)
 #define LIST(p) ((p)->list)
 #define ln(x) (log (x))
diff --git a/gcc/algol68/a68.h b/gcc/algol68/a68.h
index 13603061290..bf0e00e6d84 100644
--- a/gcc/algol68/a68.h
+++ b/gcc/algol68/a68.h
@@ -107,6 +107,30 @@ enum
 
 #include "a68-types.h"
 
+/* Location-tracking functions.  */
+
+/* Get the file name that LINE belongs to.  */
+
+inline const char *
+FILENAME (LINE_T *line)
+{
+  const line_map_ordinary * ord_map;
+  ord_map = (const line_map_ordinary *)(linemap_lookup (line_table,
+                                                       LOCATION (line)));
+  return LINEMAP_FILE (ord_map);
+}
+
+/* Get the 1-based line number of LINE.  */
+
+inline unsigned int
+LINE_NO (LINE_T *line)
+{
+  location_t loc = LOCATION (line);
+  const line_map_ordinary * ord_map;
+  ord_map = (const line_map_ordinary *)(linemap_lookup (line_table, loc));
+  return SOURCE_LINE (ord_map, loc);
+}
+
 /* Front-end global state.  */
 
 extern GTY(()) A68_T a68_common;
-- 
2.55.0

Reply via email to