* cpphash.c (macarg): Hoist all the flag diddling out of the
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 10 Feb 2000 00:26:47 +0000 (00:26 +0000)
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 10 Feb 2000 00:26:47 +0000 (00:26 +0000)
function...
(macroexpand): ... and out of the loop that calls macarg.
Skip over the initial paren before macro arguments with
cpp_get_non_space_token; point may be some distance before
that paren.  Abort if it's not there.

* cpplib.c (parse_clear_mark): Delete function.
(parse_set_mark, parse_goto_mark): Make static.
(ACTIVE_MARK_P): New macro.
(skip_block_comment, skip_line_comment): Do not bump the line
if ACTIVE_MARK_P is true.
(cpp_pop_buffer): The buffer to be popped may not have an
active mark.
(cpp_get_token): When looking for the initial paren before
macro arguments, only set a mark in a file buffer, Always
return to that mark before proceeding to call macroexpand or
return a NAME token.

* cpplib.h: Remove prototypes of parse_set_mark,
parse_clear_mark, parse_goto_mark.
(struct cpp_options): Rename 'put_out_comments' to
'discard_comments' and invert its sense.
* cppinit.c, cpphash.c, cpplib.c: All users of
put_out_comments changed to use discard_comments, with
opposite sense.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31879 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cpphash.c
gcc/cppinit.c
gcc/cpplib.c
gcc/cpplib.h
gcc/testsuite/gcc.dg/20000209-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/20000209-2.c [new file with mode: 0644]

index 42cc6b6..3e6a9a5 100644 (file)
@@ -1,3 +1,32 @@
+2000-02-09  Zack Weinberg  <zack@wolery.cumb.org>
+
+       * cpphash.c (macarg): Hoist all the flag diddling out of the
+       function...
+       (macroexpand): ... and out of the loop that calls macarg.
+       Skip over the initial paren before macro arguments with
+       cpp_get_non_space_token; point may be some distance before
+       that paren.  Abort if it's not there.
+
+       * cpplib.c (parse_clear_mark): Delete function.
+       (parse_set_mark, parse_goto_mark): Make static.
+       (ACTIVE_MARK_P): New macro.
+       (skip_block_comment, skip_line_comment): Do not bump the line
+       if ACTIVE_MARK_P is true.
+       (cpp_pop_buffer): The buffer to be popped may not have an
+       active mark.
+       (cpp_get_token): When looking for the initial paren before
+       macro arguments, only set a mark in a file buffer, Always
+       return to that mark before proceeding to call macroexpand or
+       return a NAME token.
+
+       * cpplib.h: Remove prototypes of parse_set_mark,
+       parse_clear_mark, parse_goto_mark.
+       (struct cpp_options): Rename 'put_out_comments' to
+       'discard_comments' and invert its sense.
+       * cppinit.c, cpphash.c, cpplib.c: All users of
+       put_out_comments changed to use discard_comments, with
+       opposite sense.
+
 2000-02-09  Clinton Popetz  <cpopetz@cygnus.com>
 
        * function.c (thread_prologue_and_epilogue_insns): Don't delete
index 9da1daa..8a178f3 100644 (file)
@@ -773,27 +773,22 @@ macarg (pfile, rest_args)
 {
   int paren = 0;
   enum cpp_token token;
-  char save_put_out_comments = CPP_OPTIONS (pfile)->put_out_comments;
-  CPP_OPTIONS (pfile)->put_out_comments = 0;
 
   /* Try to parse as much of the argument as exists at this
      input stack level.  */
-  pfile->no_macro_expand++;
-  pfile->no_directives++;
-  CPP_OPTIONS (pfile)->no_line_commands++;
   for (;;)
     {
       token = cpp_get_token (pfile);
       switch (token)
        {
        case CPP_EOF:
-         goto done;
+         return token;
        case CPP_POP:
          /* If we've hit end of file, it's an error (reported by caller).
             Ditto if it's the end of cpp_expand_to_buffer text.
             If we've hit end of macro, just continue.  */
          if (!CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
-           goto done;
+           return token;
          break;
        case CPP_LPAREN:
          paren++;
@@ -811,18 +806,10 @@ macarg (pfile, rest_args)
        found:
          /* Remove ',' or ')' from argument buffer.  */
          CPP_ADJUST_WRITTEN (pfile, -1);
-         goto done;
+         return token;
        default:;
        }
     }
-
-done:
-  CPP_OPTIONS (pfile)->put_out_comments = save_put_out_comments;
-  CPP_OPTIONS (pfile)->no_line_commands--;
-  pfile->no_macro_expand--;
-  pfile->no_directives--;
-
-  return token;
 }
 \f
 
@@ -1023,7 +1010,7 @@ macroexpand (pfile, hp)
 
   if (nargs >= 0)
     {
-      enum cpp_token token = CPP_EOF;
+      enum cpp_token token;
 
       args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
 
@@ -1040,8 +1027,20 @@ macroexpand (pfile, hp)
          macarg absorbed the rest of the args.  */
       i = 0;
       rest_args = 0;
-      rest_args = 0;
-      FORWARD (1);     /* Discard open-parenthesis before first arg.  */
+
+      /* Skip over the opening parenthesis.  */
+      CPP_OPTIONS (pfile)->discard_comments++;
+      CPP_OPTIONS (pfile)->no_line_commands++;
+      pfile->no_macro_expand++;
+      pfile->no_directives++;
+
+      token = cpp_get_non_space_token (pfile);
+      if (token != CPP_LPAREN)
+       cpp_ice (pfile, "macroexpand: unexpected token %d (wanted LPAREN)",
+                token);
+      CPP_ADJUST_WRITTEN (pfile, -1);
+
+      token = CPP_EOF;
       do
        {
          if (rest_args)
@@ -1058,14 +1057,17 @@ macroexpand (pfile, hp)
          else
            token = macarg (pfile, 0);
          if (token == CPP_EOF || token == CPP_POP)
-           {
-             cpp_error_with_line (pfile, start_line, start_column,
-                                  "unterminated macro call");
-             return;
-           }
+           cpp_error_with_line (pfile, start_line, start_column,
+                                "unterminated macro call");
          i++;
        }
       while (token == CPP_COMMA);
+      CPP_OPTIONS (pfile)->discard_comments--;
+      CPP_OPTIONS (pfile)->no_line_commands--;
+      pfile->no_macro_expand--;
+      pfile->no_directives--;
+      if (token != CPP_RPAREN)
+       return;
 
       /* If we got one arg but it was just whitespace, call that 0 args.  */
       if (i == 1)
index 102e815..fa67ee2 100644 (file)
@@ -408,6 +408,7 @@ cpp_options_init (opts)
   opts->dollars_in_ident = 1;
   opts->cplusplus_comments = 1;
   opts->warn_import = 1;
+  opts->discard_comments = 1;
 
   opts->pending =
     (struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending));
@@ -1600,7 +1601,7 @@ cpp_handle_option (pfile, argc, argv)
        break;
       
       case 'C':
-       opts->put_out_comments = 1;
+       opts->discard_comments = 0;
        break;
       
       case 'E':                        /* -E comes from cc -E; ignore it.  */
index e1061f1..7abb331 100644 (file)
@@ -35,6 +35,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
    (Note that it is false while we're expanding macro *arguments*.) */
 #define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->data != NULL)
 
+/* ACTIVE_MARK_P is true if there's a live mark in the buffer, in which
+   case CPP_BUMP_LINE must not be called.  */
+#define ACTIVE_MARK_P() (CPP_BUFFER (pfile)->mark != -1)
+
 /* External declarations.  */
 
 extern HOST_WIDEST_INT cpp_parse_expr PARAMS ((cpp_reader *));
@@ -100,6 +104,8 @@ static int consider_directive_while_skipping PARAMS ((cpp_reader *,
                                                      IF_STACK_FRAME *));
 static void skip_block_comment         PARAMS ((cpp_reader *));
 static void skip_line_comment          PARAMS ((cpp_reader *));
+static void parse_set_mark             PARAMS ((cpp_reader *));
+static void parse_goto_mark            PARAMS ((cpp_reader *));
 
 /* Here is the actual list of #-directives.
    This table is ordered by frequency of occurrence; the numbers
@@ -282,8 +288,11 @@ skip_block_comment (pfile)
          return;
        }
       else if (c == '\n' || c == '\r')
-       /* \r cannot be a macro escape marker here. */
-       CPP_BUMP_LINE (pfile);
+       {
+         /* \r cannot be a macro escape marker here. */
+         if (!ACTIVE_MARK_P())
+           CPP_BUMP_LINE (pfile);
+       }
       else if (c == '/' && prev_c == '*')
        return;
       else if (c == '*' && prev_c == '/'
@@ -315,7 +324,8 @@ skip_line_comment (pfile)
       else if (c == '\r')
        {
          /* \r cannot be a macro escape marker here. */
-         CPP_BUMP_LINE (pfile);
+         if (!ACTIVE_MARK_P())
+           CPP_BUMP_LINE (pfile);
          if (CPP_OPTIONS (pfile)->warn_comments)
            cpp_warning (pfile, "backslash-newline within line comment");
        }
@@ -376,7 +386,7 @@ skip_comment (pfile, m)
 }
 
 /* Identical to skip_comment except that it copies the comment into the
-   token_buffer.  This is used if put_out_comments.  */
+   token_buffer.  This is used if !discard_comments.  */
 static int
 copy_comment (pfile, m)
      cpp_reader *pfile;
@@ -764,6 +774,8 @@ cpp_pop_buffer (pfile)
      cpp_reader *pfile;
 {
   cpp_buffer *buf = CPP_BUFFER (pfile);
+  if (ACTIVE_MARK_P())
+    cpp_ice (pfile, "mark active in cpp_pop_buffer");
   (*buf->cleanup) (buf, pfile);
   CPP_BUFFER (pfile) = CPP_PREV_BUFFER (buf);
   free (buf);
@@ -2337,16 +2349,16 @@ cpp_get_token (pfile)
            goto op2;
 
        comment:
-         if (opts->put_out_comments)
-           c = copy_comment (pfile, c);
-         else
+         if (opts->discard_comments)
            c = skip_comment (pfile, c);
+         else
+           c = copy_comment (pfile, c);
          if (c != ' ')
            goto randomchar;
          
          /* Comments are equivalent to spaces.
             For -traditional, a comment is equivalent to nothing.  */
-         if (opts->traditional || opts->put_out_comments)
+         if (opts->traditional || !opts->discard_comments)
            return CPP_COMMENT;
          else
            {
@@ -2629,50 +2641,50 @@ cpp_get_token (pfile)
               decide this is not a macro call and leave things that way.  */
            if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
            {
-             int is_macro_call, macbuf_whitespace = 0;
+             int macbuf_whitespace = 0;
+
+             while (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
+               {
+                 U_CHAR *point = CPP_BUFFER (pfile)->cur;
+                 for (;;)
+                   {
+                     cpp_skip_hspace (pfile);
+                     c = PEEKC ();
+                     if (c == '\n')
+                       FORWARD(1);
+                     else
+                       break;
+                   }
+                 if (point != CPP_BUFFER (pfile)->cur)
+                   macbuf_whitespace = 1;
+                 if (c == '(')
+                   goto is_macro_call;
+                 else if (c != EOF)
+                   goto not_macro_call;
+                 cpp_pop_buffer (pfile);
+               }
 
              parse_set_mark (pfile);
              for (;;)
                {
                  cpp_skip_hspace (pfile);
                  c = PEEKC ();
-                 is_macro_call = c == '(';
-                 if (c != EOF)
-                   {
-                     if (c != '\n')
-                       break;
-                     CPP_BUMP_LINE (pfile);
-                     FORWARD (1);
-                   }
-                  else
-                    {
-                      if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
-                        {
-                          if (CPP_BUFFER (pfile)->mark !=
-                              (CPP_BUFFER (pfile)->cur
-                               - CPP_BUFFER (pfile)->buf))
-                             macbuf_whitespace = 1;
-
-                         /* The mark goes away automatically when
-                            the buffer is popped. */
-                          cpp_pop_buffer (pfile);
-                          parse_set_mark (pfile);
-                        }
-                      else
-                        break;
-                    }
+                 if (c == '\n')
+                   FORWARD(1);
+                 else
+                   break;
                }
-             if (!is_macro_call)
-                {
-                  parse_goto_mark (pfile);
-                  if (macbuf_whitespace)
-                    CPP_PUTC (pfile, ' ');
-                }
-             else
-               parse_clear_mark (pfile);
-             if (!is_macro_call)
-               return CPP_NAME;
+             parse_goto_mark (pfile);
+
+             if (c == '(')
+               goto is_macro_call;
+
+           not_macro_call:
+             if (macbuf_whitespace)
+               CPP_PUTC (pfile, ' ');
+             return CPP_NAME;
            }
+         is_macro_call:
            /* This is now known to be a macro call.
               Expand the macro, reading arguments as needed,
               and push the expansion on the input stack.  */
@@ -3142,40 +3154,27 @@ cpp_read_check_assertion (pfile)
 
 /* Remember the current position of PFILE.  */
 
-void
+static void
 parse_set_mark (pfile)
      cpp_reader *pfile;
 {
   cpp_buffer *ip = CPP_BUFFER (pfile);
-  if (ip->mark != -1)
-      cpp_ice (pfile, "ip->mark != -1 in parse_set_mark");
+  if (ACTIVE_MARK_P())
+      cpp_ice (pfile, "mark active in parse_set_mark");
 
   ip->mark = ip->cur - ip->buf;
 }
 
-/* Clear the current mark - we no longer need it.  */
-
-void
-parse_clear_mark (pfile)
-     cpp_reader *pfile;
-{
-  cpp_buffer *ip = CPP_BUFFER (pfile);
-  if (ip->mark == -1)
-      cpp_ice (pfile, "ip->mark == -1 in parse_clear_mark");
-
-  ip->mark = -1;
-}
-
 /* Backup the current position of PFILE to that saved in its mark,
    and clear the mark.  */
 
-void
+static void
 parse_goto_mark (pfile)
      cpp_reader *pfile;
 {
   cpp_buffer *ip = CPP_BUFFER (pfile);
-  if (ip->mark == -1)
-      cpp_ice (pfile, "ip->mark == -1 in parse_goto_mark");
+  if (!ACTIVE_MARK_P())
+      cpp_ice (pfile, "mark not active in parse_goto_mark");
 
   ip->cur = ip->buf + ip->mark;
   ip->mark = -1;
index fc85a02..e0bf7ae 100644 (file)
@@ -59,10 +59,6 @@ enum cpp_token {
 typedef enum cpp_token (*parse_underflow_t) PARAMS((cpp_reader *));
 typedef int (*parse_cleanup_t) PARAMS((cpp_buffer *, cpp_reader *));
 
-extern void parse_set_mark     PARAMS ((cpp_reader *));
-extern void parse_clear_mark   PARAMS ((cpp_reader *));
-extern void parse_goto_mark    PARAMS ((cpp_reader *));
-
 extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **));
 extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
 extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *));
@@ -356,9 +352,9 @@ struct cpp_options {
 
   char chill;
 
-  /* Nonzero means copy comments into the output file.  */
+  /* Nonzero means don't copy comments into the output file.  */
 
-  char put_out_comments;
+  char discard_comments;
 
   /* Nonzero means process the ANSI trigraph sequences.  */
 
diff --git a/gcc/testsuite/gcc.dg/20000209-1.c b/gcc/testsuite/gcc.dg/20000209-1.c
new file mode 100644 (file)
index 0000000..fe71058
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do preprocess } */
+
+/* Tests for line numbering around function-like macro calls.
+   Bug found by Mark Mitchell.  */
+
+#define f(x) x
+#define g f
+
+f (3);
+#error here    /* { dg-error "here" "case 0" } */
+
+f
+  (3);
+#error here    /* { dg-error "here" "case 1" } */
+
+(f
+  )(3);
+#error here    /* { dg-error "here" "case 2" } */
+
+g
+  (3);
+#error here    /* { dg-error "here" "case 3" } */
+
+(g
+  )(3);
+#error here    /* { dg-error "here" "case 4" } */
+
+f /* some
+     text */  (3);
+#error here    /* { dg-error "here" "case 5" } */
+
+(g /* some
+      text */ )(3);
+#error here    /* { dg-error "here" "case 6" } */
diff --git a/gcc/testsuite/gcc.dg/20000209-2.c b/gcc/testsuite/gcc.dg/20000209-2.c
new file mode 100644 (file)
index 0000000..621a00b
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* Distilled from glibc sources.  Tests preprocessor corner cases.  */
+
+#define NO_PAREN(rest...) rest
+#define DEFINE_CATEGORY(category, items) \
+const int _nl_value_type_##category[] = { NO_PAREN items }
+
+DEFINE_CATEGORY
+(
+ LC_COLLATE,
+ (
+   1,
+   2,
+   3,
+  ));
+
+DEFINE_CATEGORY(LC_CTYPE, (1, 2, 3));