]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR preprocessor/3081 (Preprocessor merges 2 first lines when -imacros is being...
authorNeil Booth <neil@daikokuya.demon.co.uk>
Sun, 5 Aug 2001 17:31:25 +0000 (17:31 +0000)
committerNeil Booth <neil@gcc.gnu.org>
Sun, 5 Aug 2001 17:31:25 +0000 (17:31 +0000)
PR preprocessor/3081
* c-lex.c (map): New.
(cb_file_change): Update map and use it.
(cb_def_pragma, cb_define, cb_undef): Use map and line.
(c_lex): Update to use map.
* cpperror.c (print_location): Move to using logical line numbers.
* cppfiles.c (stack_include_file): Update for new _cpp_do_file_change.
(cpp_make_system_header): Similarly.
(_cpp_execute_include): Stop line numbering hacks.  Store the
line we will return to.
* cpphash.h (CPP_BUF_LINE): Remove.
(struct cpp_buffer): Remove lineno and pseudo_newlines.
Add map and return_to_line.
(_cpp_do_file_change): Update.
* cppinit.c (cpp_start_read): Update line kludge.
* cpplex.c (handle_newline): Don't update lineno and pseudo_newlines.
(trigraph_ok): Use logical line numbers for diagnostics.
(skip_block_comment): Likewise.
(skip_whitespace): Likewise.
(skip_line_comment): Use pfile->line instead.
(_cpp_lex_token): Update to use logical line numbering exclusively.
Handle BOL locally.  Accept new lines in directives, but keep
pfile->line decremented.  Diagnostics use logical lines.  Update
directive handling.
* cpplib.c (SEEN_EOL): New.
(skip_rest_of_line, check_eol): Use it.
(end_directive): Increase line number when accepting the newline
at the end of a directive.
(run_directive): Simplify.
(do_line): Bad LC_LEAVEs become LC_RENAMEs.  Update.
(_cpp_do_file_change): Update to take buffer line number as an
argument, and store the current map in the cpp_reader.  Remove
line number kludges.
(_cpp_do__Pragma): Restore output position after a _Pragma.
(cpp_push_buffer): Don't set output line or lineno.
(_cpp_pop_buffer): Transfer more info from a faked buffer.
Remove line kludge.  Set output_line.
* cppmacro.c (builtin_macro): Update handling of __LINE__.
(parse_arg): Use logical lines.
(save_lookahead_token): Save EOFs too now.
* cppmain.c (struct printer): Fix comments.
(printer_init): Simplify, let caller do errors.
(scan_translation_unit, check_multiline_token, dump_macro): Update.
(maybe_print_line): Simplify.
(print_line): Don't print a linemarker if -P.
(cb_define, cb_undef, cb_def_pragma, cb_ident, cb_include): Update.
(cb_file_change): Simplify.
* line-map.h (LAST_SOURCE_LINE): Fix.
(CURRENT_LINE_MAP): New.

* gcc.dg/cpp/19951025-1.c: Revert.
* gcc.dg/cpp/directiv.c: We no longer process directives that
interrupt macro arguments.

From-SVN: r44650

14 files changed:
gcc/ChangeLog
gcc/c-lex.c
gcc/cpperror.c
gcc/cppfiles.c
gcc/cpphash.h
gcc/cppinit.c
gcc/cpplex.c
gcc/cpplib.c
gcc/cppmacro.c
gcc/cppmain.c
gcc/line-map.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cpp/19951025-1.c
gcc/testsuite/gcc.dg/cpp/directiv.c

index 5679160c2d35aed74fd4ffcc5fb4a5cfe2e60700..70f07e38545819c9ff8d834d85dbb5d453f3110b 100644 (file)
@@ -1,3 +1,55 @@
+2001-08-05  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       PR preprocessor/3081
+       * c-lex.c (map): New.
+       (cb_file_change): Update map and use it.
+       (cb_def_pragma, cb_define, cb_undef): Use map and line.
+       (c_lex): Update to use map.
+       * cpperror.c (print_location): Move to using logical line numbers.
+       * cppfiles.c (stack_include_file): Update for new _cpp_do_file_change.
+       (cpp_make_system_header): Similarly.
+       (_cpp_execute_include): Stop line numbering hacks.  Store the
+       line we will return to.
+       * cpphash.h (CPP_BUF_LINE): Remove.
+       (struct cpp_buffer): Remove lineno and pseudo_newlines.
+       Add map and return_to_line.
+       (_cpp_do_file_change): Update.
+       * cppinit.c (cpp_start_read): Update line kludge.
+       * cpplex.c (handle_newline): Don't update lineno and pseudo_newlines.
+       (trigraph_ok): Use logical line numbers for diagnostics.
+       (skip_block_comment): Likewise.
+       (skip_whitespace): Likewise.
+       (skip_line_comment): Use pfile->line instead.
+       (_cpp_lex_token): Update to use logical line numbering exclusively.
+       Handle BOL locally.  Accept new lines in directives, but keep
+       pfile->line decremented.  Diagnostics use logical lines.  Update
+       directive handling.
+       * cpplib.c (SEEN_EOL): New.
+       (skip_rest_of_line, check_eol): Use it.
+       (end_directive): Increase line number when accepting the newline
+       at the end of a directive.
+       (run_directive): Simplify.
+       (do_line): Bad LC_LEAVEs become LC_RENAMEs.  Update.
+       (_cpp_do_file_change): Update to take buffer line number as an
+       argument, and store the current map in the cpp_reader.  Remove
+       line number kludges.
+       (_cpp_do__Pragma): Restore output position after a _Pragma.
+       (cpp_push_buffer): Don't set output line or lineno.
+       (_cpp_pop_buffer): Transfer more info from a faked buffer.
+       Remove line kludge.  Set output_line.
+       * cppmacro.c (builtin_macro): Update handling of __LINE__.
+       (parse_arg): Use logical lines.
+       (save_lookahead_token): Save EOFs too now.
+       * cppmain.c (struct printer): Fix comments.
+       (printer_init): Simplify, let caller do errors.
+       (scan_translation_unit, check_multiline_token, dump_macro): Update.
+       (maybe_print_line): Simplify.
+       (print_line): Don't print a linemarker if -P.
+       (cb_define, cb_undef, cb_def_pragma, cb_ident, cb_include): Update.
+       (cb_file_change): Simplify.
+       * line-map.h (LAST_SOURCE_LINE): Fix.
+       (CURRENT_LINE_MAP): New.
+
 2001-08-05  Bernd Schmidt  <bernds@redhat.com>
 
        * doloop.c (doloop_modify_runtime): Properly compute number of
index 89e17021facfc1857198973cdb9f81485d914d9f..971d9cd14a7e997cbbe5d0b7a93302af290ec517 100644 (file)
@@ -57,6 +57,9 @@ Boston, MA 02111-1307, USA.  */
 /* The input filename as understood by CPP, where "" represents stdin.  */
 static const char *cpp_filename;
 
+/* The current line map.  */
+static 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;
@@ -301,9 +304,10 @@ cb_file_change (pfile, fc)
     }
 
   update_header_times (fc->map->to_file);
+  map = fc->map;
   in_system_header = fc->sysp != 0;
-  input_filename = fc->map->to_file;
-  lineno = SOURCE_LINE (fc->map, fc->line); /* Do we need this?  */
+  input_filename = map->to_file;
+  lineno = SOURCE_LINE (map, fc->line);
 
   /* Hook for C++.  */
   extract_interface_info ();
@@ -312,7 +316,7 @@ cb_file_change (pfile, fc)
 static void
 cb_def_pragma (pfile, line)
      cpp_reader *pfile;
-     unsigned int line ATTRIBUTE_UNUSED;
+     unsigned int line;
 {
   /* Issue a warning message if we have been asked to do so.  Ignore
      unknown pragmas in system headers unless an explicit
@@ -328,7 +332,7 @@ cb_def_pragma (pfile, line)
       if (s.type == CPP_NAME)
        name = cpp_token_as_text (pfile, &s);
 
-      lineno = cpp_get_line (parse_in)->line;
+      lineno = SOURCE_LINE (map, line);
       if (name)
        warning ("ignoring #pragma %s %s", space, name);
       else
@@ -340,21 +344,21 @@ cb_def_pragma (pfile, line)
 static void
 cb_define (pfile, line, node)
      cpp_reader *pfile;
-     unsigned int line ATTRIBUTE_UNUSED;
+     unsigned int line;
      cpp_hashnode *node;
 {
-  (*debug_hooks->define) (cpp_get_line (pfile)->line,
+  (*debug_hooks->define) (SOURCE_LINE (map, line),
                          (const char *) cpp_macro_definition (pfile, node));
 }
 
 /* #undef callback for DWARF and DWARF2 debug info.  */
 static void
 cb_undef (pfile, line, node)
-     cpp_reader *pfile;
-     unsigned int line ATTRIBUTE_UNUSED;
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+     unsigned int line;
      cpp_hashnode *node;
 {
-  (*debug_hooks->undef) (cpp_get_line (pfile)->line,
+  (*debug_hooks->undef) (SOURCE_LINE (map, line),
                         (const char *) NODE_NAME (node));
 }
 
@@ -763,7 +767,7 @@ c_lex (value)
   /* The C++ front end does horrible things with the current line
      number.  To ensure an accurate line number, we must reset it
      every time we return a token.  */
-  lineno = cpp_get_line (parse_in)->line;
+  lineno = SOURCE_LINE (map, cpp_get_line (parse_in)->line);
 
   *value = NULL_TREE;
   type = tok.type;
index f10198288f097da13ef4ce41f59dfeaf9d51fffa..4ed4de6273ac8fc86adfece01bcc0273593a49bc 100644 (file)
@@ -108,23 +108,17 @@ print_location (pfile, filename, pos)
        {
          struct line_map *map;
 
-         line = pfile->line;
          if (type == BUF_PRAGMA)
-           {
-             buffer = buffer->prev;
-             col = CPP_BUF_COL (buffer);
-           }
+           buffer = buffer->prev;
 
-         map = lookup_line (&pfile->line_maps, line);
          if (pos == 0)
-           {
-             pos = cpp_get_line (pfile);
-             line = SOURCE_LINE (map, line);
-           }
-         else
-           line = pos->line;
-         col = pos->col;
+           pos = cpp_get_line (pfile);
+         map = lookup_line (&pfile->line_maps, pos->line);
+         line = SOURCE_LINE (map, pos->line);
+         if (filename == 0)
+           filename = map->to_file;
 
+         col = pos->col;
          if (col == 0)
            col = 1;
 
index fb01145d8cd06ecb4a9461d8075d51399d9af236..8af65c8925f19619029eccc6bfd5058c7c0ef1e9 100644 (file)
@@ -337,9 +337,7 @@ stack_include_file (pfile, inc)
   pfile->include_depth++;
 
   /* Generate the call back.  */
-  fp->lineno = 0;
-  _cpp_do_file_change (pfile, LC_ENTER);
-  fp->lineno = 1;
+  _cpp_do_file_change (pfile, LC_ENTER, 1);
 }
 
 /* Read the file referenced by INC into the file cache.
@@ -579,7 +577,8 @@ cpp_make_system_header (pfile, syshdr, externc)
   if (syshdr)
     flags = 1 + (externc != 0);
   pfile->buffer->sysp = flags;
-  _cpp_do_file_change (pfile, LC_RENAME);
+  _cpp_do_file_change (pfile, LC_RENAME,
+                      SOURCE_LINE (pfile->map, pfile->line));
 }
 
 /* Report on all files that might benefit from a multiple include guard.
@@ -679,8 +678,8 @@ _cpp_execute_include (pfile, header, type)
       if (header->type == CPP_HEADER_NAME)
        pfile->system_include_depth++;
 
+      pfile->buffer->return_to_line = SOURCE_LINE (pfile->map, pfile->line);
       stack_include_file (pfile, inc);
-      pfile->line++;           /* Fake the '\n' at the end of #include.  */
 
       if (type == IT_IMPORT)
        _cpp_never_reread (inc);
index 1abeb57499013f6d1b9ce6053aa81e3b4b2f7242..1ba4282561b857aed95211ce270c0aaf142588db 100644 (file)
@@ -35,7 +35,6 @@ struct directive;             /* Deliberately incomplete.  */
 
 #define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION)
 #define CPP_BUFFER(PFILE) ((PFILE)->buffer)
-#define CPP_BUF_LINE(BUF) ((BUF)->lineno)
 #define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base + (BUF)->col_adjust)
 #define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur)
 
@@ -194,8 +193,10 @@ struct cpp_buffer
   /* Token column position adjustment owing to tabs in whitespace.  */
   unsigned int col_adjust;
 
-  /* Line number at line_base (above). */
-  unsigned int lineno;
+  /* The line of the buffer that we return to after a #include.
+     Strictly this is redundant, since it can be calculated from the
+     line maps, but it is clearest to save it here.  */
+  unsigned int return_to_line;
 
   /* Contains PREV_WHITE and/or AVOID_LPASTE.  */
   unsigned char saved_flags;
@@ -251,12 +252,10 @@ struct cpp_reader
   /* Lexer state.  */
   struct lexer_state state;
 
-  /* Source line tracking.  Subtract pseudo_newlines from the actual
-     line number to get the line number of preprocessed output.  Used
-     for escaped newlines and macro args that cross multiple lines.  */
+  /* Source line tracking.  */
   struct line_maps line_maps;
+  struct line_map *map;
   unsigned int line;
-  unsigned int pseudo_newlines;
 
   /* The position of the last lexed token and last lexed directive.  */
   cpp_lexer_pos lexer_pos;
@@ -446,7 +445,8 @@ extern void _cpp_define_builtin     PARAMS ((cpp_reader *, const char *));
 extern void _cpp_do__Pragma    PARAMS ((cpp_reader *));
 extern void _cpp_init_directives PARAMS ((cpp_reader *));
 extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *));
-extern void _cpp_do_file_change PARAMS ((cpp_reader *, enum lc_reason));
+extern void _cpp_do_file_change PARAMS ((cpp_reader *, enum lc_reason,
+                                        unsigned int));
 extern void _cpp_pop_buffer PARAMS ((cpp_reader *));
 
 /* Utility routines and macros.  */
index 6d4c7a0aa3420d46eb2b7f54b8902742397d6f94..f1b6b24f0aa9b56751f326a230ac800a9a635eff 100644 (file)
@@ -949,10 +949,10 @@ cpp_start_read (pfile, fname)
       p = q;
     }
 
-  /* This was zero when the initial buffer was stacked; so we must
-     make up for a non-existent new line, as well as the intervening
-     macro definitions, by setting it to 1.  */
-  pfile->line = 1;
+  /* Hopefully a short-term kludge.  We stacked the main file at line
+     zero.  The intervening macro definitions have messed up line
+     numbering, so we need to restore it.  */
+  pfile->lexer_pos.output_line = pfile->line = 0;
 
   /* The -imacros files can be scanned now, but the -include files
      have to be pushed onto the buffer stack and processed later,
index e0002beac4566c5f0bf6f695a6c0b691f15a0478..f9c4bb9ab0cb040a3998fb7229a464e59e2abd7a 100644 (file)
@@ -132,11 +132,8 @@ handle_newline (pfile, newline_char)
   cppchar_t next = EOF;
 
   pfile->line++;
-  pfile->pseudo_newlines++;
-
   buffer = pfile->buffer;
   buffer->col_adjust = 0;
-  buffer->lineno++;
   buffer->line_base = buffer->cur;
 
   /* Handle CR-LF and LF-CR combinations, get the next character.  */
@@ -173,15 +170,16 @@ trigraph_ok (pfile, from_char)
   if (CPP_OPTION (pfile, warn_trigraphs) && !pfile->state.lexing_comment)
     {
       cpp_buffer *buffer = pfile->buffer;
+
       if (accept)
-       cpp_warning_with_line (pfile, buffer->lineno, CPP_BUF_COL (buffer) - 2,
+       cpp_warning_with_line (pfile, pfile->line, CPP_BUF_COL (buffer) - 2,
                               "trigraph ??%c converted to %c",
                               (int) from_char,
                               (int) _cpp_trigraph_map[from_char]);
       else if (buffer->cur != buffer->last_Wtrigraphs)
        {
          buffer->last_Wtrigraphs = buffer->cur;
-         cpp_warning_with_line (pfile, buffer->lineno,
+         cpp_warning_with_line (pfile, pfile->line,
                                 CPP_BUF_COL (buffer) - 2,
                                 "trigraph ??%c ignored", (int) from_char);
        }
@@ -344,8 +342,8 @@ skip_block_comment (pfile)
                {
                  prevc = c, c = *buffer->cur++;
                  if (c != '/') 
-                   cpp_warning_with_line (pfile, CPP_BUF_LINE (buffer),
-                                          CPP_BUF_COL (buffer),
+                   cpp_warning_with_line (pfile, pfile->line,
+                                          CPP_BUF_COL (buffer) - 2,
                                           "\"/*\" within comment");
                }
              goto next_char;
@@ -373,7 +371,7 @@ skip_line_comment (pfile)
      cpp_reader *pfile;
 {
   cpp_buffer *buffer = pfile->buffer;
-  unsigned int orig_lineno = buffer->lineno;
+  unsigned int orig_line = pfile->line;
   cppchar_t c;
 
   pfile->state.lexing_comment = 1;
@@ -391,7 +389,7 @@ skip_line_comment (pfile)
 
   pfile->state.lexing_comment = 0;
   buffer->read_ahead = c;      /* Leave any newline for caller.  */
-  return orig_lineno != buffer->lineno;
+  return orig_line != pfile->line;
 }
 
 /* pfile->buffer->cur is one beyond the \t character.  Update
@@ -437,7 +435,7 @@ skip_whitespace (pfile, c)
            }
        }
       else if (pfile->state.in_directive && CPP_PEDANTIC (pfile))
-       cpp_pedwarn_with_line (pfile, CPP_BUF_LINE (buffer),
+       cpp_pedwarn_with_line (pfile, pfile->line,
                               CPP_BUF_COL (buffer),
                               "%s in preprocessing directive",
                               c == '\f' ? "form feed" : "vertical tab");
@@ -865,17 +863,16 @@ _cpp_lex_token (pfile, result)
   cppchar_t c;
   cpp_buffer *buffer;
   const unsigned char *comment_start;
-  unsigned char bol;
+  int bol;
 
- skip:
-  bol = pfile->state.next_bol;
- done_directive:
+ next_token:
   buffer = pfile->buffer;
-  pfile->state.next_bol = 0;
   result->flags = buffer->saved_flags;
   buffer->saved_flags = 0;
+  bol = (buffer->cur <= buffer->line_base + 1
+        && pfile->lexer_pos.output_line == pfile->line);
  next_char:
-  pfile->lexer_pos.line = buffer->lineno;
+  pfile->lexer_pos.line = pfile->line;
   result->line = pfile->line;
  next_char2:
   pfile->lexer_pos.col = CPP_BUF_COLUMN (buffer, buffer->cur);
@@ -893,22 +890,29 @@ _cpp_lex_token (pfile, result)
   switch (c)
     {
     case EOF:
-      if (!pfile->state.in_directive)
+      /* To prevent bogus diagnostics, only pop the buffer when
+        in-progress directives and arguments have been taken care of.
+        Decrement the line to terminate an in-progress directive.  */
+      if (pfile->state.in_directive)
+       pfile->line--;
+      else if (! pfile->state.parsing_args)
        {
          unsigned char ret = pfile->buffer->return_at_eof;
 
          /* Non-empty files should end in a newline.  Don't warn for
             command line and _Pragma buffers.  */
-         if (pfile->lexer_pos.col != 0 && !buffer->from_stage3)
-           cpp_pedwarn (pfile, "no newline at end of file");
-         _cpp_pop_buffer (pfile);
-         if (pfile->buffer && !ret)
+         if (pfile->lexer_pos.col != 0)
            {
-             bol = 1;
-             goto done_directive;
+             /* Account for the missing \n.  */
+             pfile->line++;
+             if (!buffer->from_stage3)
+               cpp_pedwarn (pfile, "no newline at end of file");
            }
+
+         _cpp_pop_buffer (pfile);
+         if (pfile->buffer && !ret)
+           goto next_token;
        }
-      pfile->state.next_bol = 1;
       result->type = CPP_EOF;
       return;
 
@@ -918,36 +922,41 @@ _cpp_lex_token (pfile, result)
       goto next_char2;
 
     case '\n': case '\r':
-      if (!pfile->state.in_directive)
+      if (pfile->state.in_directive)
        {
-         handle_newline (pfile, c);
-         if (!pfile->state.parsing_args)
-           pfile->pseudo_newlines = 0;
-         bol = 1;
-         pfile->lexer_pos.output_line = buffer->lineno;
-         /* This is a new line, so clear any white space flag.
-                 Newlines in arguments are white space (6.10.3.10);
-                 parse_arg takes care of that.  */
-         result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
-         goto next_char;
+         result->type = CPP_EOF;
+         if (pfile->state.parsing_args)
+           buffer->read_ahead = c;
+         else
+           {
+             handle_newline (pfile, c);
+             /* Decrementing pfile->line allows directives to
+                recognise that the newline has been seen, and also
+                means that diagnostics don't point to the next line.  */
+             pfile->lexer_pos.output_line = pfile->line--;
+           }
+         return;
        }
 
-      /* Don't let directives spill over to the next line.  */
-      buffer->read_ahead = c;
-      pfile->state.next_bol = 1;
-      result->type = CPP_EOF;
-      /* Don't break; pfile->state.skipping might be true.  */
-      return;
+      handle_newline (pfile, c);
+      /* This is a new line, so clear any white space flag.  Newlines
+        in arguments are white space (6.10.3.10); parse_arg takes
+        care of that.  */
+      result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
+      bol = 1;
+      if (pfile->state.parsing_args != 2)
+       pfile->lexer_pos.output_line = pfile->line;
+      goto next_char;
 
     case '?':
     case '\\':
       /* These could start an escaped newline, or '?' a trigraph.  Let
         skip_escaped_newlines do all the work.  */
       {
-       unsigned int lineno = buffer->lineno;
+       unsigned int line = pfile->line;
 
        c = skip_escaped_newlines (buffer, c);
-       if (lineno != buffer->lineno)
+       if (line != pfile->line)
          /* We had at least one escaped newline of some sort, and the
             next character is in buffer->read_ahead.  Update the
             token's line and column.  */
@@ -1026,9 +1035,7 @@ _cpp_lex_token (pfile, result)
       if (c == '*')
        {
          if (skip_block_comment (pfile))
-           cpp_error_with_line (pfile, pfile->lexer_pos.line,
-                                pfile->lexer_pos.col,
-                                "unterminated comment");
+           cpp_error (pfile, "unterminated comment");
        }
       else
        {
@@ -1212,26 +1219,21 @@ _cpp_lex_token (pfile, result)
         macro invocation, and proceed to process the directive.  */
       if (pfile->state.parsing_args)
        {
+         pfile->lexer_pos.output_line = pfile->line;
          if (pfile->state.parsing_args == 2)
-           cpp_error (pfile,
-                      "directives may not be used inside a macro argument");
-
-         /* Put a '#' in lookahead, return CPP_EOF for parse_arg.  */
-         buffer->extra_char = buffer->read_ahead;
-         buffer->read_ahead = '#';
-         pfile->state.next_bol = 1;
-         result->type = CPP_EOF;
-
-         /* Get whitespace right - newline_in_args sets it.  */
-         if (pfile->lexer_pos.col == 1)
-           result->flags &= ~(PREV_WHITE | AVOID_LPASTE);
+           {
+             cpp_error (pfile,
+                        "directives may not be used inside a macro argument");
+             result->type = CPP_EOF;
+           }
        }
-      else
+      /* in_directive can be true inside a _Pragma.  */
+      else if (!pfile->state.in_directive)
        {
-         /* This is the hash introducing a directive.  */
+         /* This is the hash introducing a directive.  If the return
+            value is false, it is an assembler #.  */
          if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE))
-           goto done_directive; /* bol still 1.  */
-         /* This is in fact an assembler #.  */
+           goto next_token;
        }
       break;
 
@@ -1283,7 +1285,7 @@ _cpp_lex_token (pfile, result)
     }
 
   if (!pfile->state.in_directive && pfile->state.skipping)
-    goto skip;
+    goto next_char;
 
   /* If not in a directive, this token invalidates controlling macros.  */
   if (!pfile->state.in_directive)
index d46fb93154d503d7a3c8ec8f212f1c1c7760689c..5932a44d1d5bc2e6a87138f37f12cf2af1151378 100644 (file)
@@ -178,6 +178,8 @@ DIRECTIVE_TABLE
 #undef D
 #undef DIRECTIVE_TABLE
 
+#define SEEN_EOL() (pfile->lexer_pos.output_line > pfile->line)
+
 /* Skip any remaining tokens in a directive.  */
 static void
 skip_rest_of_line (pfile)
@@ -194,7 +196,7 @@ skip_rest_of_line (pfile)
     _cpp_pop_context (pfile);
 
   /* Sweep up all tokens remaining on the line.  */
-  while (!pfile->state.next_bol)
+  while (! SEEN_EOL ())
     _cpp_lex_token (pfile, &token);
 }
 
@@ -203,7 +205,7 @@ static void
 check_eol (pfile)
      cpp_reader *pfile;
 {
-  if (!pfile->state.next_bol)
+  if (! SEEN_EOL ())
     {
       cpp_token token;
 
@@ -240,7 +242,11 @@ end_directive (pfile, skip_line)
 {
   /* We don't skip for an assembler #.  */
   if (skip_line)
-    skip_rest_of_line (pfile);
+    {
+      skip_rest_of_line (pfile);
+      /*  "Accept" the newline now.  */
+      pfile->line++;
+    }
 
   /* Restore state.  */
   pfile->la_write = pfile->la_saved;
@@ -395,19 +401,9 @@ run_directive (pfile, dir_no, type, buf, count)
      const char *buf;
      size_t count;
 {
-  unsigned int output_line = pfile->lexer_pos.output_line;
   cpp_buffer *buffer;
 
   buffer = cpp_push_buffer (pfile, (const U_CHAR *) buf, count, type, 0, 1);
-
-  if (dir_no == T_PRAGMA)
-    {
-      /* A kludge to avoid line markers for _Pragma.  */
-      pfile->lexer_pos.output_line = output_line;
-      /* Avoid interpretation of directives in a _Pragma string.  */
-      pfile->state.next_bol = 0;
-    }
-
   start_directive (pfile);
   pfile->state.prevent_expansion++;
   pfile->directive = &dtable[dir_no];
@@ -779,8 +775,11 @@ do_line (pfile)
          else if (reason == LC_LEAVE)
            {
              if (buffer->type != BUF_FAKE)
-               cpp_warning (pfile, "file \"%s\" left but not entered",
-                            buffer->nominal_fname);
+               {
+                 cpp_warning (pfile, "file \"%s\" left but not entered",
+                              buffer->nominal_fname);
+                 reason = LC_RENAME;
+               }
              else
                {
                  _cpp_pop_buffer (pfile);
@@ -789,9 +788,6 @@ do_line (pfile)
                  if (strcmp (buffer->nominal_fname, fname))
                    cpp_warning (pfile, "expected to return to file \"%s\"",
                                 buffer->nominal_fname);
-                 if (buffer->lineno + 1 != new_lineno)
-                   cpp_warning (pfile, "expected to return to line number %u",
-                                buffer->lineno + 1);
                  if (buffer->sysp != sysp)
                    cpp_warning (pfile, "header flags for \"%s\" have changed",
                                 buffer->nominal_fname);
@@ -810,30 +806,29 @@ do_line (pfile)
     }
 
   end_directive (pfile, 1);
-  buffer->lineno = new_lineno - 1;
-  _cpp_do_file_change (pfile, reason);
+  _cpp_do_file_change (pfile, reason, new_lineno);
 }
 
-/* Arrange the file_change callback.  It is assumed that the next line
-   is given by incrementing buffer->lineno and pfile->line.  */
+/* Arrange the file_change callback.  pfile->line has changed to
+   FILE_LINE of the current buffer, for reason REASON.  */
 void
-_cpp_do_file_change (pfile, reason)
+_cpp_do_file_change (pfile, reason, file_line)
      cpp_reader *pfile;
      enum lc_reason reason;
+     unsigned int file_line;
 {
   cpp_buffer *buffer;
-  struct line_map *map;
 
   buffer = pfile->buffer;
-  map = add_line_map (&pfile->line_maps, reason,
-                     pfile->line + 1, buffer->nominal_fname, buffer->lineno + 1);
+  pfile->map = add_line_map (&pfile->line_maps, reason,
+                            pfile->line, buffer->nominal_fname, file_line);
 
   if (pfile->cb.file_change)
     {
       cpp_file_change fc;
       
-      fc.map = map;
-      fc.line = pfile->line + 1;
+      fc.map = pfile->map;
+      fc.line = pfile->line;
       fc.reason = reason;
       fc.sysp = buffer->sysp;
       fc.externc = CPP_OPTION (pfile, cplusplus) && buffer->sysp == 2;
@@ -1195,16 +1190,19 @@ _cpp_do__Pragma (pfile)
   cpp_token string;
   unsigned char *buffer;
   unsigned int len;
+  cpp_lexer_pos orig_pos;
 
+  orig_pos = pfile->lexer_pos;
   if (get__Pragma_string (pfile, &string))
+    cpp_error (pfile, "_Pragma takes a parenthesized string literal");
+  else
     {
-      cpp_error (pfile, "_Pragma takes a parenthesized string literal");
-      return;
+      buffer = destringize (&string.val.str, &len);
+      run_directive (pfile, T_PRAGMA, BUF_PRAGMA, (char *) buffer, len);
+      free ((PTR) buffer);
+      pfile->lexer_pos = orig_pos;
+      pfile->line = pfile->lexer_pos.line;
     }
-
-  buffer = destringize (&string.val.str, &len);
-  run_directive (pfile, T_PRAGMA, BUF_PRAGMA, (char *) buffer, len);
-  free ((PTR) buffer);
 }
 
 /* Just ignore #sccs, on systems where we define it at all.  */
@@ -1815,8 +1813,6 @@ cpp_push_buffer (pfile, buffer, len, type, filename, return_at_eof)
       /* Preprocessed files, builtins, _Pragma and command line
         options don't do trigraph and escaped newline processing.  */
       new->from_stage3 = type != BUF_FILE || CPP_OPTION (pfile, preprocessed);
-
-      pfile->lexer_pos.output_line = 1;
     }
 
   if (*filename == '\0')
@@ -1827,7 +1823,6 @@ cpp_push_buffer (pfile, buffer, len, type, filename, return_at_eof)
   new->prev = pfile->buffer;
   new->pfile = pfile;
   new->include_stack_listed = 0;
-  new->lineno = 1;
   new->return_at_eof = return_at_eof;
 
   pfile->state.next_bol = 1;
@@ -1857,7 +1852,11 @@ _cpp_pop_buffer (pfile)
                             "unterminated #%s", dtable[ifs->type].name);
 
       if (buffer->type == BUF_FAKE)
-       buffer->prev->cur = buffer->cur;
+       {
+         buffer->prev->cur = buffer->cur;
+         buffer->prev->line_base = buffer->line_base;
+         buffer->prev->read_ahead = buffer->read_ahead;
+       }
       else if (buffer->type == BUF_FILE)
        _cpp_pop_file_buffer (pfile, buffer);
 
@@ -1877,8 +1876,7 @@ _cpp_pop_buffer (pfile)
       if (pfile->directive == &dtable[T_LINE])
        break;
 
-      pfile->line--;           /* We have a '\n' at the end of #include.  */
-      _cpp_do_file_change (pfile, LC_LEAVE);
+      _cpp_do_file_change (pfile, LC_LEAVE, pfile->buffer->return_to_line);
       if (pfile->buffer->type == BUF_FILE)
        break;
 
@@ -1888,7 +1886,12 @@ _cpp_pop_buffer (pfile)
 
   obstack_free (&pfile->buffer_ob, buffer);
 
-  pfile->state.skipping = 0;   /* In case missing #endif.  */
+  /* The output line can fall out of sync if we missed the final
+     newline from the previous buffer, for example because of an
+     unterminated comment.  Similarly, skipping needs to be cleared in
+     case of a missing #endif.  */
+  pfile->lexer_pos.output_line = pfile->line;
+  pfile->state.skipping = 0;
 }
 
 void
index d45a949c6290b443cfc959ff82dddaa357e9834b..1618e7e102fb2821869d5bd2a1f7166973bee04c 100644 (file)
@@ -175,7 +175,8 @@ builtin_macro (pfile, token)
       /* 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.  */
-      make_number_token (pfile, token, cpp_get_line (pfile)->line);
+      make_number_token (pfile, token,
+                        SOURCE_LINE (pfile->map, cpp_get_line (pfile)->line));
       break;
 
     case BT_STDC:
@@ -484,9 +485,9 @@ parse_arg (pfile, arg, variadic)
        }
 
       /* Newlines in arguments are white space (6.10.3.10).  */
-      line = pfile->lexer_pos.output_line;
+      line = pfile->line;
       cpp_get_token (pfile, token);
-      if (line != pfile->lexer_pos.output_line)
+      if (line != pfile->line)
        token->flags |= PREV_WHITE;
 
       result = token->type;
@@ -1027,22 +1028,19 @@ save_lookahead_token (pfile, token)
      cpp_reader *pfile;
      const cpp_token *token;
 {
-  if (token->type != CPP_EOF)
-    {
-      cpp_lookahead *la = pfile->la_write;
-      cpp_token_with_pos *twp;
-
-      if (la->count == la->cap)
-       {
-         la->cap += la->cap + 8;
-         la->tokens = (cpp_token_with_pos *)
-           xrealloc (la->tokens, la->cap * sizeof (cpp_token_with_pos));
-       }
+  cpp_lookahead *la = pfile->la_write;
+  cpp_token_with_pos *twp;
 
-      twp = &la->tokens[la->count++];
-      twp->token = *token;
-      twp->pos = *cpp_get_line (pfile);
+  if (la->count == la->cap)
+    {
+      la->cap += la->cap + 8;
+      la->tokens = (cpp_token_with_pos *)
+       xrealloc (la->tokens, la->cap * sizeof (cpp_token_with_pos));
     }
+
+  twp = &la->tokens[la->count++];
+  twp->token = *token;
+  twp->pos = *cpp_get_line (pfile);
 }
 
 static void
index 63026102600c6478c6a458addcef2d08b323f44e..86d245ab9f110a1296ac33e75e5511c376a5f9b3 100644 (file)
@@ -30,12 +30,12 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    cpp_get_token back into a text file.  */
 struct printer
 {
-  FILE *outf;                  /* stream to write to.  */
-  const char *last_fname;      /* previous file name.  */
-  const char *syshdr_flags;    /* system header flags, if any.  */
-  unsigned int lineno;         /* line currently being written.  */
-  unsigned char printed;       /* nonzero if something output at lineno.  */
-  struct line_map *map;                /* logical to physical line mappings.  */
+  FILE *outf;                  /* Stream to write to.  */
+  const char *filename;                /* Name of current file.  */
+  const char *syshdr_flags;    /* System header flags, if any.  */
+  unsigned int line;           /* Line currently being written.  */
+  unsigned char printed;       /* Nonzero if something output at line.  */
+  struct line_map *map;                /* Logical to physical line mappings.  */
 };
 
 int main               PARAMS ((int, char **));
@@ -46,10 +46,10 @@ static void setup_callbacks PARAMS ((void));
 /* General output routines.  */
 static void scan_translation_unit PARAMS ((cpp_reader *));
 static void check_multiline_token PARAMS ((cpp_string *));
-static int printer_init PARAMS ((cpp_reader *));
+static void printer_init PARAMS ((void));
 static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
 
-static void print_line PARAMS ((const char *));
+static void print_line PARAMS ((unsigned int, const char *));
 static void maybe_print_line PARAMS ((unsigned int));
 
 /* Callback routines for the parser.   Most of these are active only
@@ -144,8 +144,12 @@ do_preprocessing (argc, argv)
   /* Open the output now.  We must do so even if no_output is on,
      because there may be other output than from the actual
      preprocessing (e.g. from -dM).  */
-  if (printer_init (pfile))
-    return;
+  printer_init ();
+  if (print.outf == NULL)
+    {
+      cpp_notice_from_errno (pfile, options->out_fname);
+      return;
+    }
 
   setup_callbacks ();
 
@@ -216,7 +220,7 @@ scan_translation_unit (pfile)
        break;
 
       line = cpp_get_line (pfile)->output_line;
-      if (print.lineno != line)
+      if (print.line != line)
        {
          unsigned int col = cpp_get_line (pfile)->col;
 
@@ -253,7 +257,7 @@ scan_translation_unit (pfile)
     }
 }
 
-/* Adjust print.lineno for newlines embedded in tokens.  */
+/* Adjust print.line for newlines embedded in tokens.  */
 static void
 check_multiline_token (str)
      cpp_string *str;
@@ -262,85 +266,69 @@ check_multiline_token (str)
 
   for (i = 0; i < str->len; i++)
     if (str->text[i] == '\n')
-      print.lineno++;
+      print.line++;
 }
 
 /* Initialize a cpp_printer structure.  As a side effect, open the
-   output file.  */
-static int
-printer_init (pfile)
-     cpp_reader *pfile;
+   output file.  If print.outf is NULL an error occurred.  */
+static void
+printer_init ()
 {
-  print.last_fname = 0;
-  print.lineno = 0;
+  /* Setting print.line to -1 here guarantees that the first token of
+     the file will cause a linemarker to be output by maybe_print_line.  */
+  print.line = (unsigned int) -1;
   print.printed = 0;
+  print.map = 0;
 
   if (options->out_fname[0] == '\0')
     print.outf = stdout;
   else
-    {
-      print.outf = fopen (options->out_fname, "w");
-      if (! print.outf)
-       {
-         cpp_notice_from_errno (pfile, options->out_fname);
-         return 1;
-       }
-    }
-
-  return 0;
+    print.outf = fopen (options->out_fname, "w");
 }
 
-/* Newline-terminate any output line currently in progress.  If
-   appropriate, write the current line number to the output, or pad
-   with newlines so the output line matches the current line.  */
+/* If the token read on logical line LINE needs to be output on a
+   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 (line)
      unsigned int line;
 {
-  /* End the previous line of text (probably only needed until we get
-     multi-line tokens fixed).  */
+  /* End the previous line of text.  */
   if (print.printed)
     {
       putc ('\n', print.outf);
-      print.lineno++;
+      print.line++;
       print.printed = 0;
     }
 
-  if (options->no_line_commands)
+  if (line >= print.line && line < print.line + 8)
     {
-      print.lineno = line;
-      return;
-    }
-
-  /* print.lineno is zero if this is the first token of the file.  We
-     handle this specially, so that a first line of "# 1 "foo.c" in
-     file foo.i outputs just the foo.c line, and not a foo.i line.  */
-  if (line >= print.lineno && line < print.lineno + 8 && print.lineno)
-    {
-      while (line > print.lineno)
+      while (line > print.line)
        {
          putc ('\n', print.outf);
-         print.lineno++;
+         print.line++;
        }
     }
   else
-    {
-      print.lineno = line;
-      print_line ("");
-    }
+    print_line (line, "");
 }
 
 static void
-print_line (special_flags)
-  const char *special_flags;
+print_line (line, special_flags)
+     unsigned int line;
+     const char *special_flags;
 {
   /* End any previous line of text.  */
   if (print.printed)
     putc ('\n', print.outf);
   print.printed = 0;
 
-  fprintf (print.outf, "# %u \"%s\"%s%s\n",
-          print.lineno, print.last_fname, special_flags, print.syshdr_flags);
+  print.line = line;
+  if (! options->no_line_commands)
+    fprintf (print.outf, "# %u \"%s\"%s%s\n",
+            SOURCE_LINE (print.map, print.line),
+            print.filename, special_flags, print.syshdr_flags);
 }
 
 /* Callbacks.  */
@@ -348,21 +336,21 @@ print_line (special_flags)
 static void
 cb_ident (pfile, line, str)
      cpp_reader *pfile ATTRIBUTE_UNUSED;
-     unsigned int line ATTRIBUTE_UNUSED;
+     unsigned int line;
      const cpp_string * str;
 {
-  maybe_print_line (cpp_get_line (pfile)->output_line);
+  maybe_print_line (line);
   fprintf (print.outf, "#ident \"%s\"\n", str->text);
-  print.lineno++;
+  print.line++;
 }
 
 static void
 cb_define (pfile, line, node)
      cpp_reader *pfile;
-     unsigned int line ATTRIBUTE_UNUSED;
+     unsigned int line;
      cpp_hashnode *node;
 {
-  maybe_print_line (cpp_get_line (pfile)->output_line);
+  maybe_print_line (line);
   fputs ("#define ", print.outf);
 
   /* -dD command line option.  */
@@ -372,30 +360,30 @@ cb_define (pfile, line, node)
     fputs ((const char *) NODE_NAME (node), print.outf);
 
   putc ('\n', print.outf);
-  print.lineno++;
+  print.line++;
 }
 
 static void
 cb_undef (pfile, line, node)
-     cpp_reader *pfile;
-     unsigned int line ATTRIBUTE_UNUSED;
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+     unsigned int line;
      cpp_hashnode *node;
 {
-  maybe_print_line (cpp_get_line (pfile)->output_line);
+  maybe_print_line (line);
   fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
-  print.lineno++;
+  print.line++;
 }
 
 static void
 cb_include (pfile, line, dir, header)
-     cpp_reader *pfile ATTRIBUTE_UNUSED;
-     unsigned int line ATTRIBUTE_UNUSED;
+     cpp_reader *pfile;
+     unsigned int line;
      const unsigned char *dir;
      const cpp_token *header;
 {
-  maybe_print_line (cpp_get_line (pfile)->output_line);
+  maybe_print_line (line);
   fprintf (print.outf, "#%s %s\n", dir, cpp_token_as_text (pfile, header));
-  print.lineno++;
+  print.line++;
 }
 
 static void
@@ -403,12 +391,16 @@ cb_file_change (pfile, fc)
      cpp_reader *pfile ATTRIBUTE_UNUSED;
      const cpp_file_change *fc;
 {
-  /* Bring current file to correct line (except first file).  */
-  if (fc->reason == LC_ENTER && !MAIN_FILE_P (fc->map))
-    maybe_print_line (SOURCE_LINE (fc->map - 1, fc->line - 1));
+  bool first_time = print.map == NULL;
+
+  /* Bring current file to correct line.  We handle the first file
+     change callback specially, so that a first line of "# 1 "foo.c"
+     in file foo.i outputs just the foo.c line, and not a foo.i line.  */
+  if (fc->reason == LC_ENTER && !first_time)
+    maybe_print_line (fc->line - 1);
 
   print.map = fc->map;
-  print.last_fname = fc->map->to_file;
+  print.filename = fc->map->to_file;
   if (fc->externc)
     print.syshdr_flags = " 3 4";
   else if (fc->sysp)
@@ -416,18 +408,16 @@ cb_file_change (pfile, fc)
   else
     print.syshdr_flags = "";
 
-  if (print.lineno)
+  if (!first_time)
     {
       const char *flags = "";
 
-      print.lineno = SOURCE_LINE (fc->map, fc->line);
       if (fc->reason == LC_ENTER)
        flags = " 1";
       else if (fc->reason == LC_LEAVE)
        flags = " 2";
 
-      if (! options->no_line_commands)
-       print_line (flags);
+      print_line (fc->line, flags);
     }
 }
 
@@ -436,12 +426,12 @@ cb_file_change (pfile, fc)
 static void
 cb_def_pragma (pfile, line)
      cpp_reader *pfile;
-     unsigned int line ATTRIBUTE_UNUSED;
+     unsigned int line;
 {
-  maybe_print_line (cpp_get_line (pfile)->output_line);
+  maybe_print_line (line);
   fputs ("#pragma ", print.outf);
   cpp_output_line (pfile, print.outf);
-  print.lineno++;
+  print.line++;
 }
 
 /* Dump out the hash table.  */
@@ -456,7 +446,7 @@ dump_macro (pfile, node, v)
       fputs ("#define ", print.outf);
       fputs ((const char *) cpp_macro_definition (pfile, node), print.outf);
       putc ('\n', print.outf);
-      print.lineno++;
+      print.line++;
     }
 
   return 1;
index 1f9a47da42a5cc60e4cdc2e84937200f25e6e43e..b6c934435d3912a6d649db5d08c9e452d55fe96b 100644 (file)
@@ -75,9 +75,12 @@ extern struct line_map *lookup_line
 
 /* 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), (MAP)[1].from_line - 1)
 
 /* Non-zero if the map is at the bottom of the include stack.  */
 #define MAIN_FILE_P(MAP) ((MAP)->included_from < 0)
 
+/* The current line map.  */
+#define CURRENT_LINE_MAP(MAPS) ((MAPS)->maps + (MAPS)->used - 1)
+
 #endif /* !GCC_LINE_MAP_H  */
index d0813ca70bea541e24fb6d1a4e4f0f5fa57d82d8..512f539381384a644a515ccf4b65fc0bcad02b18 100644 (file)
@@ -1,3 +1,9 @@
+2001-08-05  Neil Booth  <neil@daikokuya.demon.co.uk>
+
+       * gcc.dg/cpp/19951025-1.c: Revert.
+       * gcc.dg/cpp/directiv.c: We no longer process directives that
+       interrupt macro arguments.
+
 2001-08-03  Zack Weinberg  <zackw@stanford.edu>
 
        * gcc.dg/bconstp-1.c: New test.
index ca21a227c13b16c7ca61f6031e94b1cc7673b01d..283b5f53f1abaaee40c164ebcdc31aee6f6ecf9b 100644 (file)
@@ -1,4 +1,4 @@
 /* { dg-do preprocess } */
-/* { dg-error "include expects" "" { target *-*-* } 5 } */
-/* { dg-error "newline at end" "" { target *-*-* } 5 } */
+/* { dg-error "include expects" "" { target *-*-* } 4 } */
+/* { dg-error "newline at end" "" { target *-*-* } 4 } */
 #include /\
index 2cb772d123300e156c1f3d7248b0bf7bedbc4fcd..622f7a3471a370950b2fb91a1130c55a3c816863 100644 (file)
@@ -31,13 +31,6 @@ EMPTY #define bar
 func (2                /* { dg-error "unterminated" "" { target *-*-* } 32 } */
 #define foobar /* { dg-error "directives may not" } */
 
-/* For tidiness, I think the directive should still be processed
-   above.  Certainly, continuing to try to find the closing ')' can
-   lead to some really confusing error messages.  Hence this test.  */
-#ifndef foobar
-#error It is nice if the directive is processed!
-#endif
-
 /* Check newlines end directives, even in function-like macro
    invocations.  6.10 paragraph 1.