cpphash.c (macarg): Hoist all the flag diddling out of the function...
* 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. From-SVN: r31879
This commit is contained in:
parent
3a75e42e81
commit
564ad5f49e
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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. */
|
||||
|
125
gcc/cpplib.c
125
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;
|
||||
|
@ -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. */
|
||||
|
||||
|
34
gcc/testsuite/gcc.dg/20000209-1.c
Normal file
34
gcc/testsuite/gcc.dg/20000209-1.c
Normal file
@ -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" } */
|
17
gcc/testsuite/gcc.dg/20000209-2.c
Normal file
17
gcc/testsuite/gcc.dg/20000209-2.c
Normal file
@ -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));
|
Loading…
Reference in New Issue
Block a user