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:
Zack Weinberg 2000-02-10 00:26:47 +00:00 committed by Zack Weinberg
parent 3a75e42e81
commit 564ad5f49e
7 changed files with 172 additions and 94 deletions

View 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

View 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;
}
@ -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)

View 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. */

View 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;

View 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. */

View 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" } */

View 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));