OK.
Thanks.

> 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;

Reply via email to