Represent column numbers using line-map's source_location.
authorPer Bothner <per@bothner.com>
Wed, 11 Feb 2004 15:29:30 +0000 (07:29 -0800)
committerPer Bothner <bothner@gcc.gnu.org>
Wed, 11 Feb 2004 15:29:30 +0000 (07:29 -0800)
The "next available source_location" is now managed internally by
line-maps.c rather than by clients.
* line-map.h (struct line_map):  New field column_bits.
<from_line>:  Rename field to start_location.
(struct line_maps):  New fields highest_location and max_column_hint.
(linemap_check_files_exited):  New declaration.
(linemap_line_start):  New declaration.
(linemap_add):  Remove from_line parameter; use highest_location field.
(SOURCE_LINE, LAST_SOURCE_LINE):  Modify to use column_bits.
(SOURCE_COLUMN, LAST_SOURCE_LINE_LOCATION):  New macros.
(CURRENT_LINE_MAP):  Remove macro.
(linemap_position_for_column):  New inline function.
* line-map.c (linemap_init):  Clear new fields.
(linemap_check_files_exited):  New function, extracted from ...
(linemap_free):  Use linemap_check_files_exited.
(linemap_add):  Remove from_line parameter.  Various updates.
(linemap_line_start):  New function.
(linemap_lookeup):  Update for new field names.
* cpphash.h (struct cpp_reader) <map>:  Field removed.  Because
linemap_position_for_column may unpredictably change the current map,
it is cleaner and simpler for us to not cache it in cpp_reader.
(struct cpp_buffer):  New sysp field.
Changed warned_cplusplus_comments and from_stage3 to bitfields.
* cppinit.c (cpp_read_min_file):  pfile->map no longer exists.
* cpplib.c (do_line, do_linemarker, _cpp_do_file_change):  Get
current map using linemap_lookup.
(do_linemarker):  Also set buffer's sysp field.
(destringize_and_run):  No longer need to decrement current line.
* cppfiles.c (_cpp_stack_file):  Set sysp from and in buffer.
(search_path_head, open_file_failed):  Use buffer's sysp.
(cpp_make_system_header):  Get current map using linemap_lookup.
Also set buffer's sysp flag.
* cppmacro.c (_cpp_builtin_macro_text):  Likewise use linemap_lookup.
* cpphash.h (CPP_INCREMENT_LINE):  New macro.
(struct cpp_buffer):  Moved fields saved_cur, saved_rlimit to ...
(struct cpp_reader):  ... and adding saved_line_base field.
* cpptrad.c (_cpp_overlay_buffer, _cpp_remove_overlay):
Update accordingly.  Don't adjust line.
(_cpp_scan_out_logical_line):  Use CPP_INCREMENT_LINE.
* cpphash.c (CPP_IN_SYSTEM_HEADER):  Replaced macro by ...
(cpp_in_system_header):  ... new inline function, using buffer's sysp.
* cpperror.c (_cpp_begin_message):  Update to use cpp_in_system_header.
* cpplex.c (_cpp_lex_direct):  Likewise.
* cppmacro.c (_cpp_builtin_macro_text):  Likewise.
* cppmacro.c (_cpp_create_definition):  Use buffer's sysp field.
* cpplib.h (struct cpp_token):  Rename line field to src_loc.
Remove col field as it is now subsumed by src_loc.
* cpperror.c:  Update various field, parameter, and macro names.
(print_location):  If col==0, try SOURCE_COLUMN of line.
(cpp_error):  Use cur_token's src_loc field, rather than line+col.
* cpplib.c (do_diagnostic):  Token's src_loc fields replaces line+col.
* cpplex.c (_cpp_process_line_notes, _cpp_lex_direct,
_cpp_skip_block_comment):  Use CPP_INCREMENT_LINE.
(_cpp_temp_token):  Replace cpp_token's line+col fields by src_loc.
(_cpp_get_fresh_line):  Don't need to adjust line for missing newline.
(_cpp_lex_direct):  Use linemap_position_for_column.
* c-ppoutput.c (maybe_print_line, print_line):  Don't take map
parameter.  Instead get it from the line_table global.  Adjust callers.
(print):  Remove map field.  Replace line field to src_line.
(init_pp_output, account_for_newlines, maybe_print_line):  Adjust.
(cb_line_change):  Use SOURCE_COLUMN.  Minor optimizations.
(pp_file_change):  Use MAIN_FILE_P since we cannot checked print.map.
Use LAST_SOURCE_LINE_LOCATION to "catch up" after #include.
* cpptrad.c (copy_comment):  Rename variable.
* c-lex.c (map):  Remove static variable, for same reason we removed
cpp_reader's map field.
(cb_line_change, cb_def_pragma, cb_define, cb_undef):  Hence we need
to call linemap_lookup.
(cb_line_change):  Token's line field replaced by src_loc.
(fe_file_change):  Use MAINFILE_P and LAST_SOURCE_LINE macros.
Don't save new_map.

* cpphash.h, cpperror.c, cpplib.h:  Some renames of fileline to
source_location.

From-SVN: r77663

14 files changed:
gcc/ChangeLog
gcc/c-lex.c
gcc/c-ppoutput.c
gcc/cpperror.c
gcc/cppfiles.c
gcc/cpphash.h
gcc/cppinit.c
gcc/cpplex.c
gcc/cpplib.c
gcc/cpplib.h
gcc/cppmacro.c
gcc/cpptrad.c
gcc/line-map.c
gcc/line-map.h

index 4dab85484caa14b2c0270f264d9a961ee5cfc42f..2921e539f730aee75835b6268aa13258f81aaeda 100644 (file)
@@ -1,3 +1,82 @@
+
+2004-02-11  Per Bothner  <per@bothner.com>
+
+       Represent column numbers using line-map's source_location.
+       The "next available source_location" is now managed internally by
+       line-maps.c rather than by clients.
+       * line-map.h (struct line_map):  New field column_bits.
+       <from_line>:  Rename field to start_location.
+       (struct line_maps):  New fields highest_location and max_column_hint.
+       (linemap_check_files_exited):  New declaration.
+       (linemap_line_start):  New declaration.
+       (linemap_add):  Remove from_line parameter; use highest_location field.
+       (SOURCE_LINE, LAST_SOURCE_LINE):  Modify to use column_bits.
+       (SOURCE_COLUMN, LAST_SOURCE_LINE_LOCATION):  New macros.
+       (CURRENT_LINE_MAP):  Remove macro.
+       (linemap_position_for_column):  New inline function.
+       * line-map.c (linemap_init):  Clear new fields.
+       (linemap_check_files_exited):  New function, extracted from ...
+       (linemap_free):  Use linemap_check_files_exited.
+       (linemap_add):  Remove from_line parameter.  Various updates.
+       (linemap_line_start):  New function.
+       (linemap_lookeup):  Update for new field names.
+       * cpphash.h (struct cpp_reader) <map>:  Field removed.  Because
+       linemap_position_for_column may unpredictably change the current map,
+       it is cleaner and simpler for us to not cache it in cpp_reader.
+       (struct cpp_buffer):  New sysp field.
+       Changed warned_cplusplus_comments and from_stage3 to bitfields.
+       * cppinit.c (cpp_read_min_file):  pfile->map no longer exists.
+       * cpplib.c (do_line, do_linemarker, _cpp_do_file_change):  Get
+       current map using linemap_lookup.
+       (do_linemarker):  Also set buffer's sysp field.
+       (destringize_and_run):  No longer need to decrement current line.
+       * cppfiles.c (_cpp_stack_file):  Set sysp from and in buffer.
+       (search_path_head, open_file_failed):  Use buffer's sysp.
+       (cpp_make_system_header):  Get current map using linemap_lookup.
+       Also set buffer's sysp flag.
+       * cppmacro.c (_cpp_builtin_macro_text):  Likewise use linemap_lookup.
+       * cpphash.h (CPP_INCREMENT_LINE):  New macro.
+       (struct cpp_buffer):  Moved fields saved_cur, saved_rlimit to ...
+       (struct cpp_reader):  ... and adding saved_line_base field.
+       * cpptrad.c (_cpp_overlay_buffer, _cpp_remove_overlay):
+       Update accordingly.  Don't adjust line.
+       (_cpp_scan_out_logical_line):  Use CPP_INCREMENT_LINE.
+       * cpphash.c (CPP_IN_SYSTEM_HEADER):  Replaced macro by ...
+       (cpp_in_system_header):  ... new inline function, using buffer's sysp.
+       * cpperror.c (_cpp_begin_message):  Update to use cpp_in_system_header.
+       * cpplex.c (_cpp_lex_direct):  Likewise.
+       * cppmacro.c (_cpp_builtin_macro_text):  Likewise.
+       * cppmacro.c (_cpp_create_definition):  Use buffer's sysp field.
+       * cpplib.h (struct cpp_token):  Rename line field to src_loc.
+       Remove col field as it is now subsumed by src_loc.
+       * cpperror.c:  Update various field, parameter, and macro names.
+       (print_location):  If col==0, try SOURCE_COLUMN of line.
+       (cpp_error):  Use cur_token's src_loc field, rather than line+col.
+       * cpplib.c (do_diagnostic):  Token's src_loc fields replaces line+col.
+       * cpplex.c (_cpp_process_line_notes, _cpp_lex_direct,
+       _cpp_skip_block_comment):  Use CPP_INCREMENT_LINE.
+       (_cpp_temp_token):  Replace cpp_token's line+col fields by src_loc.
+       (_cpp_get_fresh_line):  Don't need to adjust line for missing newline.
+       (_cpp_lex_direct):  Use linemap_position_for_column.
+       * c-ppoutput.c (maybe_print_line, print_line):  Don't take map
+       parameter.  Instead get it from the line_table global.  Adjust callers.
+       (print):  Remove map field.  Replace line field to src_line.
+       (init_pp_output, account_for_newlines, maybe_print_line):  Adjust.
+       (cb_line_change):  Use SOURCE_COLUMN.  Minor optimizations.
+       (pp_file_change):  Use MAIN_FILE_P since we cannot checked print.map.
+       Use LAST_SOURCE_LINE_LOCATION to "catch up" after #include.
+       * cpptrad.c (copy_comment):  Rename variable.
+       * c-lex.c (map):  Remove static variable, for same reason we removed
+       cpp_reader's map field.
+       (cb_line_change, cb_def_pragma, cb_define, cb_undef):  Hence we need
+       to call linemap_lookup.
+       (cb_line_change):  Token's line field replaced by src_loc.
+       (fe_file_change):  Use MAINFILE_P and LAST_SOURCE_LINE macros.
+       Don't save new_map.
+
+       * cpphash.h, cpperror.c, cpplib.h:  Some renames of fileline to
+       source_location.
+
 2004-02-11  Hartmut Penner  <hpenner@de.ibm.com>
        
        * config/rs6000/altivec.md (*movv4si_internal): At least one
index aba571fab9a211eb73b9cca1c6e48f0642d3fba4..cbd557346f959fcdbf970922d45f343a5f68681a 100644 (file)
@@ -42,9 +42,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "splay-tree.h"
 #include "debug.h"
 
-/* The current line map.  */
-static const struct line_map *map;
-
 /* We may keep statistics about how long which files took to compile.  */
 static int header_time, body_time;
 static splay_tree file_info_tree;
@@ -194,28 +191,27 @@ static void
 cb_line_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const cpp_token *token,
                int parsing_args)
 {
-  if (token->type == CPP_EOF || parsing_args)
-    return;
-
-  input_line = SOURCE_LINE (map, token->line);
+  if (token->type != CPP_EOF && !parsing_args)
+    {
+      source_location loc = token->src_loc;
+      const struct line_map *map = linemap_lookup (&line_table, loc);
+      input_line = SOURCE_LINE (map, loc);
+    }
 }
 
 void
 fe_file_change (const struct line_map *new_map)
 {
   if (new_map == NULL)
-    {
-      map = NULL;
-      return;
-    }
+    return;
 
   if (new_map->reason == LC_ENTER)
     {
       /* Don't stack the main buffer on the input stack;
         we already did in compile_file.  */
-      if (map != NULL)
+      if (! MAIN_FILE_P (new_map))
        {
-          int included_at = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
+          int included_at = LAST_SOURCE_LINE (new_map - 1);
 
          input_line = included_at;
          push_srcloc (new_map->to_file, 1);
@@ -250,20 +246,20 @@ fe_file_change (const struct line_map *new_map)
   in_system_header = new_map->sysp != 0;
   input_filename = new_map->to_file;
   input_line = new_map->to_line;
-  map = new_map;
 
   /* Hook for C++.  */
   extract_interface_info ();
 }
 
 static void
-cb_def_pragma (cpp_reader *pfile, unsigned int line)
+cb_def_pragma (cpp_reader *pfile, source_location loc)
 {
   /* Issue a warning message if we have been asked to do so.  Ignore
      unknown pragmas in system headers unless an explicit
      -Wunknown-pragmas has been given.  */
   if (warn_unknown_pragmas > in_system_header)
     {
+      const struct line_map *map = linemap_lookup (&line_table, loc);
       const unsigned char *space, *name;
       const cpp_token *s;
 
@@ -277,25 +273,27 @@ cb_def_pragma (cpp_reader *pfile, unsigned int line)
            name = cpp_token_as_text (pfile, s);
        }
 
-      input_line = SOURCE_LINE (map, line);
+      input_line = SOURCE_LINE (map, loc);
       warning ("ignoring #pragma %s %s", space, name);
     }
 }
 
 /* #define callback for DWARF and DWARF2 debug info.  */
 static void
-cb_define (cpp_reader *pfile, unsigned int line, cpp_hashnode *node)
+cb_define (cpp_reader *pfile, source_location loc, cpp_hashnode *node)
 {
-  (*debug_hooks->define) (SOURCE_LINE (map, line),
+  const struct line_map *map = linemap_lookup (&line_table, loc);
+  (*debug_hooks->define) (SOURCE_LINE (map, loc),
                          (const char *) cpp_macro_definition (pfile, node));
 }
 
 /* #undef callback for DWARF and DWARF2 debug info.  */
 static void
-cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, unsigned int line,
+cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location loc,
          cpp_hashnode *node)
 {
-  (*debug_hooks->undef) (SOURCE_LINE (map, line),
+  const struct line_map *map = linemap_lookup (&line_table, loc);
+  (*debug_hooks->undef) (SOURCE_LINE (map, loc),
                         (const char *) NODE_NAME (node));
 }
 \f
index 6b5aa990ee01a915048fbdba6346b4b108f8e343..2d32445d4fe6b4363e44bae3caa6920f4cb02cc4 100644 (file)
@@ -32,10 +32,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 static struct
 {
   FILE *outf;                  /* Stream to write to.  */
-  const struct line_map *map;  /* Logical to physical line mappings.  */
   const cpp_token *prev;       /* Previous token.  */
   const cpp_token *source;     /* Source token for spacing.  */
-  fileline line;               /* Line currently being written.  */
+  int src_line;                        /* Line number currently being written.  */
   unsigned char printed;       /* Nonzero if something output at line.  */
 } print;
 
@@ -45,8 +44,8 @@ static void scan_translation_unit_trad (cpp_reader *);
 static void account_for_newlines (const unsigned char *, size_t);
 static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
 
-static void print_line (const struct line_map *, fileline, const char *);
-static void maybe_print_line (const struct line_map *, fileline);
+static void print_line (source_location, const char *);
+static void maybe_print_line (source_location);
 
 /* Callback routines for the parser.   Most of these are active only
    in specific modes.  */
@@ -112,13 +111,12 @@ init_pp_output (FILE *out_stream)
       cb->undef  = cb_undef;
     }
 
-  /* Initialize the print structure.  Setting print.line to -1 here is
+  /* Initialize the print structure.  Setting print.src_line to -1 here is
      a trick to guarantee that the first token of the file will cause
      a linemarker to be output by maybe_print_line.  */
-  print.line = (fileline) -1;
+  print.src_line = -1;
   print.printed = 0;
   print.prev = 0;
-  print.map = 0;
   print.outf = out_stream;
 }
 
@@ -171,13 +169,13 @@ scan_translation_unit (cpp_reader *pfile)
     }
 }
 
-/* Adjust print.line for newlines embedded in output.  */
+/* Adjust print.src_line for newlines embedded in output.  */
 static void
 account_for_newlines (const unsigned char *str, size_t len)
 {
   while (len--)
     if (*str++ == '\n')
-      print.line++;
+      print.src_line++;
 }
 
 /* Writes out a traditionally preprocessed file.  */
@@ -187,7 +185,7 @@ scan_translation_unit_trad (cpp_reader *pfile)
   while (_cpp_read_logical_line_trad (pfile))
     {
       size_t len = pfile->out.cur - pfile->out.base;
-      maybe_print_line (print.map, pfile->out.first_line);
+      maybe_print_line (pfile->out.first_line);
       fwrite (pfile->out.base, 1, len, print.outf);
       print.printed = 1;
       if (!CPP_OPTION (pfile, discard_comments))
@@ -199,52 +197,56 @@ scan_translation_unit_trad (cpp_reader *pfile)
    different line to the current one, output the required newlines or
    a line marker, and return 1.  Otherwise return 0.  */
 static void
-maybe_print_line (const struct line_map *map, fileline line)
+maybe_print_line (source_location src_loc)
 {
+  const struct line_map *map = linemap_lookup (&line_table, src_loc);
+  int src_line = SOURCE_LINE (map, src_loc);
   /* End the previous line of text.  */
   if (print.printed)
     {
       putc ('\n', print.outf);
-      print.line++;
+      print.src_line++;
       print.printed = 0;
     }
 
-  if (line >= print.line && line < print.line + 8)
+  if (src_line >= print.src_line && src_line < print.src_line + 8)
     {
-      while (line > print.line)
+      while (src_line > print.src_line)
        {
          putc ('\n', print.outf);
-         print.line++;
+         print.src_line++;
        }
     }
   else
-    print_line (map, line, "");
+    print_line (src_loc, "");
 }
 
 /* Output a line marker for logical line LINE.  Special flags are "1"
    or "2" indicating entering or leaving a file.  */
 static void
-print_line (const struct line_map *map, fileline line, const char *special_flags)
+print_line (source_location src_loc, const char *special_flags)
 {
   /* End any previous line of text.  */
   if (print.printed)
     putc ('\n', print.outf);
   print.printed = 0;
 
-  print.line = line;
   if (!flag_no_line_commands)
     {
+      const struct line_map *map = linemap_lookup (&line_table, src_loc);
+
       size_t to_file_len = strlen (map->to_file);
       unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
       unsigned char *p;
 
+      print.src_line = SOURCE_LINE (map, src_loc);
+
       /* cpp_quote_string does not nul-terminate, so we have to do it
         ourselves.  */
       p = cpp_quote_string (to_file_quoted,
                            (unsigned char *)map->to_file, to_file_len);
       *p = '\0';
-      fprintf (print.outf, "# %u \"%s\"%s",
-              SOURCE_LINE (map, print.line),
+      fprintf (print.outf, "# %u \"%s\"%s", print.src_line,
               to_file_quoted, special_flags);
 
       if (map->sysp == 2)
@@ -262,10 +264,12 @@ static void
 cb_line_change (cpp_reader *pfile, const cpp_token *token,
                int parsing_args)
 {
+  source_location src_loc = token->src_loc;
+
   if (token->type == CPP_EOF || parsing_args)
     return;
 
-  maybe_print_line (print.map, token->line);
+  maybe_print_line (src_loc);
   print.prev = 0;
   print.source = 0;
 
@@ -276,14 +280,12 @@ cb_line_change (cpp_reader *pfile, const cpp_token *token,
      ought to care.  Some things do care; the fault lies with them.  */
   if (!CPP_OPTION (pfile, traditional))
     {
+      const struct line_map *map = linemap_lookup (&line_table, src_loc);
+      int spaces = SOURCE_COLUMN (map, src_loc) - 2;
       print.printed = 1;
-      if (token->col > 2)
-       {
-         unsigned int spaces = token->col - 2;
 
-         while (spaces--)
-           putc (' ', print.outf);
-       }
+      while (-- spaces >= 0)
+       putc (' ', print.outf);
     }
 }
 
@@ -291,15 +293,15 @@ static void
 cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
          const cpp_string *str)
 {
-  maybe_print_line (print.map, line);
+  maybe_print_line (line);
   fprintf (print.outf, "#ident \"%s\"\n", str->text);
-  print.line++;
+  print.src_line++;
 }
 
 static void
 cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node)
 {
-  maybe_print_line (print.map, line);
+  maybe_print_line (line);
   fputs ("#define ", print.outf);
 
   /* 'D' is whole definition; 'N' is name only.  */
@@ -310,28 +312,28 @@ cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node)
     fputs ((const char *) NODE_NAME (node), print.outf);
 
   putc ('\n', print.outf);
-  print.line++;
+  print.src_line++;
 }
 
 static void
-cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
+cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
          cpp_hashnode *node)
 {
-  maybe_print_line (print.map, line);
+  maybe_print_line (line);
   fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
-  print.line++;
+  print.src_line++;
 }
 
 static void
-cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
+cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line,
            const unsigned char *dir, const char *header, int angle_brackets)
 {
-  maybe_print_line (print.map, line);
+  maybe_print_line (line);
   if (angle_brackets)
     fprintf (print.outf, "#%s <%s>\n", dir, header);
   else
     fprintf (print.outf, "#%s \"%s\"\n", dir, header);
-  print.line++;
+  print.src_line++;
 }
 
 /* Callback called when -fworking-director and -E to emit working
@@ -351,8 +353,7 @@ pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
 }
 
 /* The file name, line number or system header flags have changed, as
-   described in MAP.  From this point on, the old print.map might be
-   pointing to freed memory, and so must not be dereferenced.  */
+   described in MAP.  */
 
 void
 pp_file_change (const struct line_map *map)
@@ -365,37 +366,37 @@ pp_file_change (const struct line_map *map)
   if (map != NULL)
     {
       /* First time?  */
-      if (print.map == NULL)
+      if (MAIN_FILE_P (map))
        {
          /* Avoid printing foo.i when the main file is foo.c.  */
          if (!cpp_get_options (parse_in)->preprocessed)
-           print_line (map, map->from_line, flags);
+           print_line (map->start_location, flags);
        }
       else
        {
          /* Bring current file to correct line when entering a new file.  */
          if (map->reason == LC_ENTER)
-           maybe_print_line (map - 1, map->from_line - 1);
-
+           {
+             const struct line_map *from = INCLUDED_FROM (&line_table, map);
+             maybe_print_line (LAST_SOURCE_LINE_LOCATION (from));
+           }
          if (map->reason == LC_ENTER)
            flags = " 1";
          else if (map->reason == LC_LEAVE)
            flags = " 2";
-         print_line (map, map->from_line, flags);
+         print_line (map->start_location, flags);
        }
     }
-
-  print.map = map;
 }
 
 /* Copy a #pragma directive to the preprocessed output.  */
 static void
 cb_def_pragma (cpp_reader *pfile, fileline line)
 {
-  maybe_print_line (print.map, line);
+  maybe_print_line (line);
   fputs ("#pragma ", print.outf);
   cpp_output_line (pfile, print.outf);
-  print.line++;
+  print.src_line++;
 }
 
 /* Dump out the hash table.  */
@@ -408,7 +409,7 @@ dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
       fputs ((const char *) cpp_macro_definition (pfile, node),
             print.outf);
       putc ('\n', print.outf);
-      print.line++;
+      print.src_line++;
     }
 
   return 1;
index 776f6e87d0e3d4cb5e219c1cdfc2487d05bcae2c..d57238069d6574f9ea2dc05095e2dbd85f492d55 100644 (file)
@@ -29,14 +29,14 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 #include "cpphash.h"
 #include "intl.h"
 
-static void print_location (cpp_reader *, fileline, unsigned int);
+static void print_location (cpp_reader *, source_location, unsigned int);
 
 /* Print the logical file location (LINE, COL) in preparation for a
    diagnostic.  Outputs the #include chain if it has changed.  A line
    of zero suppresses the include stack, and outputs the program name
    instead.  */
 static void
-print_location (cpp_reader *pfile, fileline line, unsigned int col)
+print_location (cpp_reader *pfile, source_location line, unsigned int col)
 {
   if (line == 0)
     fprintf (stderr, "%s: ", progname);
@@ -50,7 +50,11 @@ print_location (cpp_reader *pfile, fileline line, unsigned int col)
 
       lin = SOURCE_LINE (map, line);
       if (col == 0)
-       col = 1;
+       {
+         col = SOURCE_COLUMN (map, line);
+         if (col == 0)
+           col = 1;
+       }
 
       if (lin == 0)
        fprintf (stderr, "%s:", map->to_file);
@@ -64,13 +68,18 @@ print_location (cpp_reader *pfile, fileline line, unsigned int col)
 }
 
 /* Set up for a diagnostic: print the file and line, bump the error
-   counter, etc.  LINE is the logical line number; zero means to print
+   counter, etc.  SRC_LOC is the logical line number; zero means to print
    at the location of the previously lexed token, which tends to be
-   the correct place by default.  Returns 0 if the error has been
-   suppressed.  */
+   the correct place by default.  The column number can be specified either
+   using COLUMN or (if COLUMN==0) extracting SOURCE_COLUMN from SRC_LOC.
+   (This may seem redundant, but is useful when pre-scanning (cleaning) a line,
+   when we haven't yet verified whether the current line_map has a
+   big enough max_column_hint.)
+
+   Returns 0 if the error has been suppressed.  */
 int
-_cpp_begin_message (cpp_reader *pfile, int code, fileline line,
-                   unsigned int column)
+_cpp_begin_message (cpp_reader *pfile, int code,
+                   source_location src_loc, unsigned int column)
 {
   int level = CPP_DL_EXTRACT (code);
 
@@ -78,7 +87,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line,
     {
     case CPP_DL_WARNING:
     case CPP_DL_PEDWARN:
-      if (CPP_IN_SYSTEM_HEADER (pfile)
+      if (cpp_in_system_header (pfile)
          && ! CPP_OPTION (pfile, warn_system_headers))
        return 0;
       /* Fall through.  */
@@ -105,7 +114,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line,
       break;
     }
 
-  print_location (pfile, line, column);
+  print_location (pfile, src_loc, column);
   if (CPP_DL_WARNING_P (level))
     fputs (_("warning: "), stderr);
   else if (level == CPP_DL_ICE)
@@ -125,8 +134,7 @@ _cpp_begin_message (cpp_reader *pfile, int code, fileline line,
 void
 cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
 {
-  fileline line;
-  unsigned int column;
+  source_location src_loc;
   va_list ap;
   
   va_start (ap, msgid);
@@ -134,18 +142,16 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
   if (CPP_OPTION (pfile, traditional))
     {
       if (pfile->state.in_directive)
-       line = pfile->directive_line;
+       src_loc = pfile->directive_line;
       else
-       line = pfile->line;
-      column = 0;
+       src_loc = pfile->line;
     }
   else
     {
-      line = pfile->cur_token[-1].line;
-      column = pfile->cur_token[-1].col;
+      src_loc = pfile->cur_token[-1].src_loc;
     }
 
-  if (_cpp_begin_message (pfile, level, line, column))
+  if (_cpp_begin_message (pfile, level, src_loc, 0))
     v_message (msgid, ap);
 
   va_end (ap);
@@ -154,14 +160,14 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
 /* Print an error at a specific location.  */
 void
 cpp_error_with_line (cpp_reader *pfile, int level,
-                    fileline line, unsigned int column,
+                    source_location src_loc, unsigned int column,
                     const char *msgid, ...)
 {
   va_list ap;
   
   va_start (ap, msgid);
 
-  if (_cpp_begin_message (pfile, level, line, column))
+  if (_cpp_begin_message (pfile, level, src_loc, column))
     v_message (msgid, ap);
 
   va_end (ap);
index c886c891681f3e3d23ee46ddd00b593f4b830187..862be9f61d2eb9820d4a7c566e5c80344872707e 100644 (file)
@@ -640,8 +640,10 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
   if (!should_stack_file (pfile, file, import))
       return false;
 
-  sysp = MAX ((pfile->map ? pfile->map->sysp : 0),
-             (file->dir ? file->dir->sysp : 0));
+  if (pfile->buffer == NULL || file->dir == NULL)
+    sysp = 0;
+  else
+    sysp = MAX (pfile->buffer->sysp,  file->dir->sysp);
 
   /* Add the file to the dependencies on its first inclusion.  */
   if (CPP_OPTION (pfile, deps.style) > !!sysp && !file->stack_count)
@@ -658,6 +660,7 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
   buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size,
                            CPP_OPTION (pfile, preprocessed));
   buffer->file = file;
+  buffer->sysp = sysp;
 
   /* Initialize controlling macro state.  */
   pfile->mi_valid = true;
@@ -707,7 +710,8 @@ search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets,
   else if (pfile->quote_ignores_source_dir)
     dir = pfile->quote_include;
   else
-    return make_cpp_dir (pfile, dir_name_of_file (file), pfile->map->sysp);
+    return make_cpp_dir (pfile, dir_name_of_file (file),
+                        pfile->buffer ? pfile->buffer->sysp : 0);
 
   if (dir == NULL)
     cpp_error (pfile, CPP_DL_ERROR,
@@ -756,7 +760,7 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
 static void
 open_file_failed (cpp_reader *pfile, _cpp_file *file)
 {
-  int sysp = pfile->map ? pfile->map->sysp: 0;
+  int sysp = pfile->line > 1 && pfile->buffer ? pfile->buffer->sysp : 0;
   bool print_dep = CPP_OPTION (pfile, deps.style) > !!sysp;
 
   errno = file->err_no;
@@ -936,12 +940,14 @@ void
 cpp_make_system_header (cpp_reader *pfile, int syshdr, int externc)
 {
   int flags = 0;
+  const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
 
   /* 1 = system header, 2 = system header to be treated as C.  */
   if (syshdr)
     flags = 1 + (externc != 0);
-  _cpp_do_file_change (pfile, LC_RENAME, pfile->map->to_file,
-                      SOURCE_LINE (pfile->map, pfile->line), flags);
+  pfile->buffer->sysp = flags;
+  _cpp_do_file_change (pfile, LC_RENAME, map->to_file,
+                      SOURCE_LINE (map, pfile->line), flags);
 }
 
 /* Allow the client to change the current file.  Used by the front end
index 660674671582b65d4d4d1bd139a6f1829545c413..d704c092d0f0617d09c6fd7afdfcb0c4d341a1c1 100644 (file)
@@ -64,6 +64,13 @@ typedef unsigned char uchar;
 #define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base)
 #define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur)
 
+#define CPP_INCREMENT_LINE(PFILE, COLS_HINT) do { \
+    const struct line_map *map \
+      = linemap_lookup (PFILE->line_table, PFILE->line); \
+    unsigned int line = SOURCE_LINE (map, PFILE->line) + 1; \
+    PFILE->line = linemap_line_start (PFILE->line_table, line, COLS_HINT); \
+  } while (0)
+
 /* Maximum nesting of cpp_buffers.  We use a static limit, partly for
    efficiency, and partly to limit runaway recursion.  */
 #define CPP_STACK_MAX 200
@@ -296,24 +303,25 @@ struct cpp_buffer
      The warning happens only for C89 extended mode with -pedantic on,
      or for -Wtraditional, and only once per file (otherwise it would
      be far too noisy).  */
-  unsigned char warned_cplusplus_comments;
+  unsigned int warned_cplusplus_comments : 1;
 
   /* True if we don't process trigraphs and escaped newlines.  True
      for preprocessed input, command line directives, and _Pragma
      buffers.  */
-  unsigned char from_stage3;
+  unsigned int from_stage3 : 1;
 
   /* Nonzero means that the directory to start searching for ""
      include files has been calculated and stored in "dir" below.  */
   unsigned char search_cached;
 
+  /* One for a system header, two for a C system header file that therefore
+     needs to be extern "C" protected in C++, and zero otherwise. */
+  unsigned char sysp;
+
   /* The directory of the this buffer's file.  Its NAME member is not
      allocated, so we don't need to worry about freeing it.  */
   struct cpp_dir dir;
 
-  /* Used for buffer overlays by cpptrad.c.  */
-  const uchar *saved_cur, *saved_rlimit;
-
   /* Descriptor for converting from the input character set to the
      source character set.  */
   struct cset_converter input_cset_desc;
@@ -335,7 +343,6 @@ struct cpp_reader
 
   /* Source line tracking.  */
   struct line_maps *line_table;
-  const struct line_map *map;
   fileline line;
 
   /* The line of the '#' of the current directive.  */
@@ -455,6 +462,9 @@ struct cpp_reader
     fileline first_line;
   } out;
 
+  /* Used for buffer overlays by cpptrad.c.  */
+  const uchar *saved_cur, *saved_rlimit, *saved_line_base;
+
   /* Used to save the original line number during traditional
      preprocessing.  */
   unsigned int saved_line;
@@ -493,12 +503,18 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1];
 
 /* Macros.  */
 
-#define CPP_IN_SYSTEM_HEADER(PFILE) ((PFILE)->map && (PFILE)->map->sysp)
+static inline int cpp_in_system_header (cpp_reader *);
+static inline int
+cpp_in_system_header (cpp_reader *pfile)
+{
+  return pfile->buffer ? pfile->buffer->sysp : 0;
+}
 #define CPP_PEDANTIC(PF) CPP_OPTION (PF, pedantic)
 #define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, warn_traditional)
 
 /* In cpperror.c  */
-extern int _cpp_begin_message (cpp_reader *, int, fileline, unsigned int);
+extern int _cpp_begin_message (cpp_reader *, int,
+                              source_location, unsigned int);
 
 /* In cppmacro.c */
 extern void _cpp_free_definition (cpp_hashnode *);
index 0fc9c682baf5ab113661eeed6fac90149eedd03e..ed91b0e6ea19f0311adecf02ec7050990f55ef66 100644 (file)
@@ -479,7 +479,7 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname)
   if (CPP_OPTION (pfile, preprocessed))
     {
       read_original_filename (pfile);
-      fname = pfile->map->to_file;
+      fname = pfile->line_table->maps[pfile->line_table->used-1].to_file;
     }
   return fname;
 }
index 783732fa444c6063ce8ab6b012c766f021b71e5a..c53a9965481f3d16b6379bbcf05185cb3283c28a 100644 (file)
@@ -282,7 +282,7 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment)
            }
 
          buffer->line_base = note->pos;
-         pfile->line++;
+         CPP_INCREMENT_LINE (pfile, 0);
        }
       else if (_cpp_trigraph_map[note->type])
        {
@@ -349,12 +349,16 @@ _cpp_skip_block_comment (cpp_reader *pfile)
        }
       else if (c == '\n')
        {
+         unsigned int cols;
          buffer->cur = cur - 1;
          _cpp_process_line_notes (pfile, true);
          if (buffer->next_line >= buffer->rlimit)
            return true;
          _cpp_clean_line (pfile);
-         pfile->line++;
+
+         cols = buffer->next_line - buffer->line_base;
+         CPP_INCREMENT_LINE (pfile, cols);
+
          cur = buffer->cur;
        }
     }
@@ -680,8 +684,7 @@ _cpp_temp_token (cpp_reader *pfile)
     }
 
   result = pfile->cur_token++;
-  result->line = old->line;
-  result->col = old->col;
+  result->src_loc = old->src_loc;
   return result;
 }
 
@@ -772,7 +775,7 @@ _cpp_get_fresh_line (cpp_reader *pfile)
        {
          /* Only warn once.  */
          buffer->next_line = buffer->rlimit;
-         cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line - 1,
+         cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line,
                               CPP_BUF_COLUMN (buffer, buffer->cur),
                               "no newline at end of file");
        }
@@ -822,7 +825,7 @@ _cpp_lex_direct (cpp_reader *pfile)
          if (!pfile->state.in_directive)
            {
              /* Tell the compiler the line number of the EOF token.  */
-             result->line = pfile->line;
+             result->src_loc = pfile->line;
              result->flags = BOL;
            }
          return result;
@@ -839,17 +842,19 @@ _cpp_lex_direct (cpp_reader *pfile)
     }
   buffer = pfile->buffer;
  update_tokens_line:
-  result->line = pfile->line;
+  result->src_loc = pfile->line;
 
  skipped_white:
   if (buffer->cur >= buffer->notes[buffer->cur_note].pos
       && !pfile->overlaid_buffer)
     {
       _cpp_process_line_notes (pfile, false);
-      result->line = pfile->line;
+      result->src_loc = pfile->line;
     }
   c = *buffer->cur++;
-  result->col = CPP_BUF_COLUMN (buffer, buffer->cur);
+
+  result->src_loc = linemap_position_for_column (pfile->line_table,
+                                                CPP_BUF_COLUMN (buffer, buffer->cur));
 
   switch (c)
     {
@@ -859,7 +864,8 @@ _cpp_lex_direct (cpp_reader *pfile)
       goto skipped_white;
 
     case '\n':
-      pfile->line++;
+      if (buffer->cur < buffer->rlimit)
+       CPP_INCREMENT_LINE (pfile, 0);
       buffer->need_line = true;
       goto fresh_line;
 
@@ -916,7 +922,7 @@ _cpp_lex_direct (cpp_reader *pfile)
            cpp_error (pfile, CPP_DL_ERROR, "unterminated comment");
        }
       else if (c == '/' && (CPP_OPTION (pfile, cplusplus_comments)
-                           || CPP_IN_SYSTEM_HEADER (pfile)))
+                           || cpp_in_system_header (pfile)))
        {
          /* Warn about comments only if pedantically GNUC89, and not
             in system headers.  */
index fa168594651aa0fe456a27297b24c655fff0c3c6..3165351f28d6f03eff0daff9f30916b817a40a74 100644 (file)
@@ -777,8 +777,9 @@ strtoul_for_line (const uchar *str, unsigned int len, long unsigned int *nump)
 static void
 do_line (cpp_reader *pfile)
 {
+  const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
   const cpp_token *token;
-  const char *new_file = pfile->map->to_file;
+  const char *new_file = map->to_file;
   unsigned long new_lineno;
 
   /* C99 raised the minimum limit on #line numbers.  */
@@ -816,7 +817,7 @@ do_line (cpp_reader *pfile)
 
   skip_rest_of_line (pfile);
   _cpp_do_file_change (pfile, LC_RENAME, new_file, new_lineno,
-                      pfile->map->sysp);
+                      map->sysp);
 }
 
 /* Interpret the # 44 "file" [flags] notation, which has slightly
@@ -825,10 +826,11 @@ do_line (cpp_reader *pfile)
 static void
 do_linemarker (cpp_reader *pfile)
 {
+  const struct line_map *map = linemap_lookup (pfile->line_table, pfile->line);
   const cpp_token *token;
-  const char *new_file = pfile->map->to_file;
+  const char *new_file = map->to_file;
   unsigned long new_lineno;
-  unsigned int new_sysp = pfile->map->sysp;
+  unsigned int new_sysp = map->sysp;
   enum lc_reason reason = LC_RENAME;
   int flag;
 
@@ -876,6 +878,7 @@ do_linemarker (cpp_reader *pfile)
          flag = read_flag (pfile, flag);
          if (flag == 4)
            new_sysp = 2;
+         pfile->buffer->sysp = new_sysp;
        }
 
       check_eol (pfile);
@@ -900,11 +903,15 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
                     const char *to_file, unsigned int file_line,
                     unsigned int sysp)
 {
-  pfile->map = linemap_add (pfile->line_table, reason, sysp,
-                           pfile->line, to_file, file_line);
+  const struct line_map *map = linemap_add (pfile->line_table, reason, sysp,
+                                           to_file, file_line);
+  if (map == NULL)
+    pfile->line = 0;
+  else
+    pfile->line = linemap_line_start (pfile->line_table, map->to_line, 127);
 
   if (pfile->cb.file_change)
-    pfile->cb.file_change (pfile, pfile->map);
+    pfile->cb.file_change (pfile, map);
 }
 
 /* Report a warning or error detected by the program we are
@@ -912,9 +919,7 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
 static void
 do_diagnostic (cpp_reader *pfile, int code, int print_dir)
 {
-  if (_cpp_begin_message (pfile, code,
-                         pfile->cur_token[-1].line,
-                         pfile->cur_token[-1].col))
+  if (_cpp_begin_message (pfile, code, pfile->cur_token[-1].src_loc, 0))
     {
       if (print_dir)
        fprintf (stderr, "#%s ", pfile->directive->name);
@@ -1340,7 +1345,6 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in)
     pfile->context = saved_context;
     pfile->cur_token = saved_cur_token;
     pfile->cur_run = saved_cur_run;
-    pfile->line--;
   }
 
   /* See above comment.  For the moment, we'd like
@@ -1903,13 +1907,6 @@ cpp_get_callbacks (cpp_reader *pfile)
   return &pfile->cb;
 }
 
-/* The line map set.  */
-const struct line_maps *
-cpp_get_line_maps (cpp_reader *pfile)
-{
-  return pfile->line_table;
-}
-
 /* Copy the given callbacks structure to our own.  */
 void
 cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb)
index fd512b6412c3b776e4733d98ab2993df49cab584..11838212ea51f9c541f6ea7d80ca1c8482fec3a0 100644 (file)
@@ -174,8 +174,7 @@ struct cpp_string
    occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts.  */
 struct cpp_token
 {
-  fileline line;               /* Logical line of first char of token.  */
-  unsigned short col;          /* Column of first char of token.  */
+  source_location src_loc;     /* Location of first char of token.  */
   ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT;  /* token type */
   unsigned char flags;         /* flags - see above */
 
@@ -527,7 +526,6 @@ extern void cpp_set_include_chains (cpp_reader *, cpp_dir *, cpp_dir *, int);
    through the pointer returned from cpp_get_callbacks, or set them
    with cpp_set_callbacks.  */
 extern cpp_options *cpp_get_options (cpp_reader *);
-extern const struct line_maps *cpp_get_line_maps (cpp_reader *);
 extern cpp_callbacks *cpp_get_callbacks (cpp_reader *);
 extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *);
 
@@ -685,7 +683,7 @@ extern void cpp_errno (cpp_reader *, int, const char *msgid);
 /* Same as cpp_error, except additionally specifies a position as a
    (translation unit) physical line and physical column.  If the line is
    zero, then no location is printed.  */
-extern void cpp_error_with_line (cpp_reader *, int, fileline, unsigned,
+extern void cpp_error_with_line (cpp_reader *, int, source_location, unsigned,
                                 const char *msgid, ...) ATTRIBUTE_PRINTF_5;
 
 /* In cpplex.c */
index c7971009e205718f61464755a5e8bc1a985b207c..f396a9dbec469c6181eb2fc21e70de94275d50ae 100644 (file)
@@ -116,6 +116,7 @@ static const char * const monthnames[] =
 const uchar *
 _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
 {
+  const struct line_map *map;
   const uchar *result = NULL;
   unsigned int number = 1;
 
@@ -132,7 +133,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
        unsigned int len;
        const char *name;
        uchar *buf;
-       const struct line_map *map = pfile->map;
+       map = linemap_lookup (pfile->line_table, pfile->line);
 
        if (node->value.builtin == BT_BASE_FILE)
          while (! MAIN_FILE_P (map))
@@ -157,14 +158,15 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
       break;
 
     case BT_SPECLINE:
+      map = linemap_lookup (pfile->line_table, pfile->line);
       /* If __LINE__ is embedded in a macro, it must expand to the
         line of the macro's invocation, not its definition.
         Otherwise things like assert() will not work properly.  */
       if (CPP_OPTION (pfile, traditional))
        number = pfile->line;
       else
-       number = pfile->cur_token[-1].line;
-      number = SOURCE_LINE (pfile->map, number);
+       number = pfile->cur_token[-1].src_loc;
+      number = SOURCE_LINE (map, number);
       break;
 
       /* __STDC__ has the value 1 under normal circumstances.
@@ -174,7 +176,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
         value 0.  */
     case BT_STDC:
       {
-       if (CPP_IN_SYSTEM_HEADER (pfile)
+       if (cpp_in_system_header (pfile)
            && CPP_OPTION (pfile, stdc_0_in_system_headers)
            && !CPP_OPTION (pfile,std))
          number = 0;
@@ -1488,7 +1490,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
   macro->count = 0;
   macro->fun_like = 0;
   /* To suppress some diagnostics.  */
-  macro->syshdr = pfile->map->sysp != 0;
+  macro->syshdr = pfile->buffer && pfile->buffer->sysp != 0;
 
   if (CPP_OPTION (pfile, traditional))
     ok = _cpp_create_trad_definition (pfile, macro);
index 6315b1074f5131599a0ff2cc47ff5a678767bb84..f6dc99d3fecf39b1e489a702b2c22ffba5c11af1 100644 (file)
@@ -148,7 +148,7 @@ static const uchar *
 copy_comment (cpp_reader *pfile, const uchar *cur, int in_define)
 {
   bool unterminated, copy = false;
-  unsigned int from_line = pfile->line;
+  source_location src_loc = pfile->line;
   cpp_buffer *buffer = pfile->buffer;
 
   buffer->cur = cur;
@@ -158,7 +158,7 @@ copy_comment (cpp_reader *pfile, const uchar *cur, int in_define)
     unterminated = _cpp_skip_block_comment (pfile);
     
   if (unterminated)
-    cpp_error_with_line (pfile, CPP_DL_ERROR, from_line, 0,
+    cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0,
                         "unterminated comment");
 
   /* Comments in directives become spaces so that tokens are properly
@@ -268,13 +268,14 @@ _cpp_overlay_buffer (cpp_reader *pfile, const uchar *start, size_t len)
   cpp_buffer *buffer = pfile->buffer;
 
   pfile->overlaid_buffer = buffer;
-  buffer->saved_cur = buffer->cur;
-  buffer->saved_rlimit = buffer->rlimit;
-  /* Prevent the ISO lexer from scanning a fresh line.  */
-  pfile->saved_line = pfile->line--;
+  pfile->saved_cur = buffer->cur;
+  pfile->saved_rlimit = buffer->rlimit;
+  pfile->saved_line_base = buffer->next_line;
+  pfile->saved_line = pfile->line;
   buffer->need_line = false;
 
   buffer->cur = start;
+  buffer->line_base = start;
   buffer->rlimit = start + len;
 }
 
@@ -284,12 +285,12 @@ _cpp_remove_overlay (cpp_reader *pfile)
 {
   cpp_buffer *buffer = pfile->overlaid_buffer;
 
-  buffer->cur = buffer->saved_cur;
-  buffer->rlimit = buffer->saved_rlimit;
+  buffer->cur = pfile->saved_cur;
+  buffer->rlimit = pfile->saved_rlimit;
+  buffer->line_base = pfile->saved_line_base;
   buffer->need_line = true;
 
   pfile->overlaid_buffer = NULL;
-  pfile->line = pfile->saved_line;
 }
 
 /* Reads a logical line into the output buffer.  Returns TRUE if there
@@ -404,7 +405,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro)
          pfile->out.cur = out - 1;
          pfile->buffer->cur = cur;
          pfile->buffer->need_line = true;
-         pfile->line++;
+         CPP_INCREMENT_LINE (pfile, 0);
 
          if ((lex_state == ls_fun_open || lex_state == ls_fun_close)
              && !pfile->state.in_directive
@@ -605,7 +606,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro)
                  /* Null directive.  Ignore it and don't invalidate
                     the MI optimization.  */
                  pfile->buffer->need_line = true;
-                 pfile->line++;
+                 CPP_INCREMENT_LINE (pfile, 0);
                  result = false;
                  goto done;
                }
index be8cf27cd72332d1a05144c4028638bb3026efc1..a7398bb98eeabc316dabd1954b3540b370260835 100644 (file)
@@ -39,8 +39,24 @@ linemap_init (struct line_maps *set)
   set->trace_includes = false;
   set->depth = 0;
   set->cache = 0;
+  set->highest_location = 0;
+  set->max_column_hint = 0;
 }
 
+/* Check for and warn about line_maps entered but not exited. */
+
+void
+linemap_check_files_exited (struct line_maps *set)
+{
+  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 = &set->maps[set->used - 1]; ! MAIN_FILE_P (map);
+       map = INCLUDED_FROM (set, map))
+    fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
+            map->to_file);
+}
 /* Free a line map set.  */
 
 void
@@ -48,14 +64,7 @@ linemap_free (struct line_maps *set)
 {
   if (set->maps)
     {
-      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);
+      linemap_check_files_exited (set);
 
       free (set->maps);
     }
@@ -72,16 +81,17 @@ linemap_free (struct line_maps *set)
 
    FROM_LINE should be monotonic increasing across calls to this
    function.  A call to this function can relocate the previous set of
+   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, source_location from_line,
-            const char *to_file, unsigned int to_line)
+            unsigned int sysp, const char *to_file, unsigned int to_line)
 {
   struct line_map *map;
+  source_location start_location = set->highest_location + 1;
 
-  if (set->used && from_line < set->maps[set->used - 1].from_line)
+  if (set->used && start_location < set->maps[set->used - 1].start_location)
     abort ();
 
   if (set->used == set->allocated)
@@ -131,17 +141,20 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
       if (error || to_file == NULL)
        {
          to_file = from->to_file;
-         to_line = LAST_SOURCE_LINE (from) + 1;
+         to_line = SOURCE_LINE (from, from[1].start_location);
          sysp = from->sysp;
        }
     }
 
   map->reason = reason;
   map->sysp = sysp;
-  map->from_line = from_line;
+  map->start_location = start_location;
   map->to_file = to_file;
   map->to_line = to_line;
   set->cache = set->used++;
+  map->column_bits = 0;
+  set->highest_location = start_location;
+  set->max_column_hint = 0;
 
   if (reason == LC_ENTER)
     {
@@ -161,6 +174,59 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
   return map;
 }
 
+source_location
+linemap_line_start (struct line_maps *set, unsigned int to_line,
+                   unsigned int max_column_hint)
+{
+  struct line_map *map = &set->maps[set->used - 1];
+  source_location highest = set->highest_location;
+  source_location r;
+  unsigned int last_line = SOURCE_LINE (map, highest);
+  int line_delta = to_line - last_line;
+  bool add_map = false;
+  if (line_delta < 0
+      || (line_delta > 10 && line_delta * map->column_bits > 1000)
+      || (max_column_hint >= (1U << map->column_bits))
+      || (max_column_hint <= 80 && map->column_bits >= 10))
+    {
+      add_map = true;
+    }
+  else
+    max_column_hint = set->max_column_hint;
+  if (add_map)
+    {
+      int column_bits;
+      if (max_column_hint > 1000000 || highest > 0xC0000000)
+       {
+         max_column_hint = 0;
+         if (highest >0xF0000000)
+           return 0;
+         column_bits = 0;
+       }
+      else
+       {
+         column_bits = 7;
+         while (max_column_hint >= (1U << column_bits))
+           column_bits++;
+         max_column_hint = 1U << column_bits;
+       }
+      if (line_delta < 0
+         || last_line != map->to_line
+         || SOURCE_COLUMN (map, highest) >= (1U << column_bits))
+       map = (struct line_map*) linemap_add (set, LC_RENAME, map->sysp,
+                                     map->to_file, to_line);
+      map->column_bits = column_bits;
+      r = map->start_location;
+    }
+  else
+    r = highest - SOURCE_COLUMN (map, highest)
+      + (line_delta << map->column_bits);
+  if (r > set->highest_location)
+    set->highest_location = r;
+  set->max_column_hint = max_column_hint;
+  return r;
+}
+
 /* Given a logical line, returns the map from which the corresponding
    (source file, line) pair can be deduced.  Since the set is built
    chronologically, the logical lines are monotonic increasing, and so
@@ -177,9 +243,9 @@ linemap_lookup (struct line_maps *set, source_location line)
   
   cached = &set->maps[mn];
   /* We should get a segfault if no line_maps have been added yet. */
-  if (line >= cached->from_line)
+  if (line >= cached->start_location)
     {
-      if (mn + 1 == mx || line < cached[1].from_line)
+      if (mn + 1 == mx || line < cached[1].start_location)
        return cached;
     }
   else
@@ -191,7 +257,7 @@ linemap_lookup (struct line_maps *set, source_location line)
   while (mx - mn > 1)
     {
       md = (mn + mx) / 2;
-      if (set->maps[md].from_line > line)
+      if (set->maps[md].start_location > line)
        mx = md;
       else
        mn = md;
index 2780583e10f3a55baaecdfcec64f746ace01b6ac..6f09fcfd3312347aba24966a583a776517fb4266 100644 (file)
@@ -30,28 +30,35 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    (e.g. a #line directive in C).  */
 enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME};
 
-/* A logical line number, i,e, an "index" into a line_map.  */
+/* A logical line/column number, i.e. an "index" into a line_map.  */
 /* Long-term, we want to use this to replace struct location_s (in input.h),
    and effectively typedef source_location location_t.  */
 typedef unsigned int source_location;
 typedef source_location fileline; /* deprecated name */
 
-/* The logical line FROM_LINE maps to physical source file TO_FILE at
-   line TO_LINE, and subsequently one-to-one until the next line_map
-   structure in the set.  INCLUDED_FROM is 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.
-   REASON is the reason for creation of this line map, SYSP is one for
-   a system header, two for a C system header file that therefore
-   needs to be extern "C" protected in C++, and zero otherwise.  */
+/* Physical source file TO_FILE at line TO_LINE at column 0 is represented
+   by the logical START_LOCATION.  TO_LINE+L at column C is represented by
+   START_LOCATION+(L*(1<<column_bits))+C, as long as C<(1<<column_bits),
+   and the result_location is less than the next line_map's start_location.
+   (The top line is line 1 and the leftmost column is column 1; line/column 0
+   means "entire file/line" or "unknown line/column" or "not applicable".)
+   INCLUDED_FROM is 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.  REASON is the reason for
+   creation of this line map, SYSP is one for a system header, two for
+   a C system header file that therefore needs to be extern "C"
+   protected in C++, and zero otherwise.  */
 struct line_map
 {
   const char *to_file;
   unsigned int to_line;
-  source_location from_line;
+  source_location start_location;
   int included_from;
   ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
+  /* The sysp field isn't really needed now that it's in cpp_buffer. */
   unsigned char sysp;
+  /* Number of the low-order source_location bits used for a column number. */
+  unsigned int column_bits : 8;
 };
 
 /* A set of chronological line_map structures.  */
@@ -73,6 +80,13 @@ struct line_maps
 
   /* If true, prints an include trace a la -H.  */
   bool trace_includes;
+
+  /* Highest source_location "given out". */
+  source_location highest_location;
+
+  /* The maximum column number we can quickly allocate.  Higher numbers
+     may require allocating a new line_map. */
+  unsigned int max_column_hint;
 };
 
 /* Initialize a line map set.  */
@@ -81,6 +95,19 @@ extern void linemap_init (struct line_maps *);
 /* Free a line map set.  */
 extern void linemap_free (struct line_maps *);
 
+/* Check for and warn about line_maps entered but not exited. */
+
+extern void linemap_check_files_exited (struct line_maps *);
+
+/* Return a source_location for the start (i.e. column==0) of
+   (physical) line TO_LINE in the current source file (as in the
+   most recent linemap_add).   MAX_COLUMN_HINT is the highest column
+   number we expect to use in this line (but it does not change
+   the highest_location). */
+
+extern source_location linemap_line_start
+(struct line_maps *, unsigned int,  unsigned int);
+
 /* Add a mapping of logical source line to physical source file and
    line number.
 
@@ -90,12 +117,12 @@ extern void linemap_free (struct line_maps *);
    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
+   START_LOCATION should be monotonic increasing across calls to this
    function.  A call to this function can relocate the previous set of
    maps, so any stored line_map pointers should not be used.  */
 extern const struct line_map *linemap_add
   (struct line_maps *, enum lc_reason, unsigned int sysp,
-   source_location from_line, const char *to_file, unsigned int to_line);
+   const char *to_file, unsigned int to_line);
 
 /* Given a logical line, returns the map from which the corresponding
    (source file, line) pair can be deduced.  */
@@ -108,12 +135,21 @@ extern const struct line_map *linemap_lookup
 extern void linemap_print_containing_files (struct line_maps *,
                                            const struct line_map *);
 
-/* Converts a map and logical line to source line.  */
-#define SOURCE_LINE(MAP, LINE) ((LINE) + (MAP)->to_line - (MAP)->from_line)
+/* Converts a map and a source_location to source line.  */
+#define SOURCE_LINE(MAP, LINE) \
+  ((((LINE) - (MAP)->start_location) >> (MAP)->column_bits) + (MAP)->to_line)
+
+#define SOURCE_COLUMN(MAP, LINE) \
+  (((LINE) - (MAP)->start_location) & ((1 << (MAP)->column_bits) - 1))
 
 /* Returns the last source line within a map.  This is the (last) line
    of the #include, or other directive, that caused a map change.  */
-#define LAST_SOURCE_LINE(MAP) SOURCE_LINE ((MAP), (MAP)[1].from_line - 1)
+#define LAST_SOURCE_LINE(MAP) \
+  SOURCE_LINE (MAP, LAST_SOURCE_LINE_LOCATION (MAP))
+#define LAST_SOURCE_LINE_LOCATION(MAP) \
+  ((((MAP)[1].start_location - 2 - (MAP)->start_location) \
+    & ~((1 << (MAP)->column_bits) - 1))                          \
+   + (MAP)->start_location)
 
 /* Returns the map a given map was included from.  */
 #define INCLUDED_FROM(SET, MAP) (&(SET)->maps[(MAP)->included_from])
@@ -121,8 +157,32 @@ extern void linemap_print_containing_files (struct line_maps *,
 /* Nonzero if the map is at the bottom of the include stack.  */
 #define MAIN_FILE_P(MAP) ((MAP)->included_from < 0)
 
-/* The current line map.  Saves a call to lookup_line if the caller is
-   sure he is in the scope of the current map.  */
-#define CURRENT_LINE_MAP(MAPS) ((MAPS)->maps + (MAPS)->used - 1)
+/* Get a source position that for the same line as the most recent
+   linemap_line_start, but with the specified TO_COLUMN column number. */
 
+static inline source_location
+linemap_position_for_column (struct line_maps *set, unsigned int to_column)
+{
+  struct line_map *map = &set->maps[set->used - 1];
+  source_location r = set->highest_location;
+  if (__builtin_expect (to_column > set->max_column_hint, 0))
+    {
+      if (r >= 0xC000000 || to_column > 1000000) /* FIXME */
+       {
+         /* Running low on source_locations - disable column numbers. */
+         return r - SOURCE_COLUMN (map, r);
+       }
+      else
+       {
+         r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
+         map = &set->maps[set->used - 1];
+         r = set->highest_location;
+       }
+    }
+  r = r - SOURCE_COLUMN (map, r) + to_column;
+  if (r >= set->highest_location)
+    set->highest_location = r;
+  return r;
+}
+                                                 
 #endif /* !GCC_LINE_MAP_H  */