From: zack Date: Thu, 10 Feb 2000 00:26:47 +0000 (+0000) Subject: * cpphash.c (macarg): Hoist all the flag diddling out of the X-Git-Tag: upstream/4.9.2~103314 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0f0b378982ad0ca24ac9b4dd2e72861333e01bff;p=platform%2Fupstream%2Flinaro-gcc.git * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31879 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 42cc6b6..3e6a9a5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2000-02-09 Zack Weinberg + + * 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 * function.c (thread_prologue_and_epilogue_insns): Don't delete diff --git a/gcc/cpphash.c b/gcc/cpphash.c index 9da1daa..8a178f3 100644 --- a/gcc/cpphash.c +++ b/gcc/cpphash.c @@ -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; } @@ -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) diff --git a/gcc/cppinit.c b/gcc/cppinit.c index 102e815..fa67ee2 100644 --- a/gcc/cppinit.c +++ b/gcc/cppinit.c @@ -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. */ diff --git a/gcc/cpplib.c b/gcc/cpplib.c index e1061f1..7abb331 100644 --- a/gcc/cpplib.c +++ b/gcc/cpplib.c @@ -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; diff --git a/gcc/cpplib.h b/gcc/cpplib.h index fc85a02..e0bf7ae 100644 --- a/gcc/cpplib.h +++ b/gcc/cpplib.h @@ -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 index 0000000..fe71058 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20000209-1.c @@ -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 index 0000000..621a00b --- /dev/null +++ b/gcc/testsuite/gcc.dg/20000209-2.c @@ -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));