#define CONTEXT_PASTER (1 << 1) /* An argument context on RHS of ##. */
#define CONTEXT_RAW (1 << 2) /* If argument tokens already expanded. */
#define CONTEXT_ARG (1 << 3) /* If an argument context. */
+#define CONTEXT_VARARGS (1 << 4) /* If a varargs argument context. */
typedef struct cpp_context cpp_context;
struct cpp_context
#define IS_ARG_CONTEXT(c) ((c)->flags & CONTEXT_ARG)
#define CURRENT_CONTEXT(pfile) ((pfile)->contexts + (pfile)->cur_context)
-#define ON_REST_ARG(c) \
- (((c)->u.list->flags & VAR_ARGS) \
- && (c)->u.list->tokens[(c)->posn - 1].val.aux \
- == (unsigned int) ((c)->u.list->paramc - 1))
#define ASSIGN_FLAGS_AND_POS(d, s) \
do {(d)->flags = (s)->flags & (PREV_WHITE | BOL | PASTE_LEFT); \
cpp_reader *pfile;
{
cpp_buffer *buffer = pfile->buffer;
- cppchar_t c = EOF, prevc;
+ cppchar_t c = EOF, prevc = EOF;
pfile->state.lexing_comment = 1;
while (buffer->cur != buffer->rlimit)
irrespective of conformance mode, because lots of
broken systems do that and trying to clean it up in
fixincludes is a nightmare. */
- if (!CPP_IN_SYSTEM_HEADER (pfile)
- && CPP_OPTION (pfile, c89) && CPP_PEDANTIC (pfile)
- && !buffer->warned_cplusplus_comments)
+ if (CPP_OPTION (pfile, c89) && CPP_PEDANTIC (pfile)
+ && ! buffer->warned_cplusplus_comments)
{
cpp_pedwarn (pfile,
"C++ style comments are not allowed in ISO C89");
buffer->warned_cplusplus_comments = 1;
}
+ /* Skip_line_comment updates buffer->read_ahead. */
if (skip_line_comment (pfile))
cpp_warning_with_line (pfile, result->line, result->col,
"multi-line comment");
pfile->no_expand_level = context - pfile->contexts;
next = _cpp_get_token (pfile);
restore_macro_expansion (pfile, prev_nme);
+
if (next->type != CPP_OPEN_PAREN)
{
_cpp_push_token (pfile, next);
{
/* Duplicate the placemarker. Then we can set its flags and
position and safely be using more than one. */
- cpp_token *pm = duplicate_token (pfile, &placemarker_token);
- pm->flags = VOID_REST;
- save_token (args, pm);
+ save_token (args, duplicate_token (pfile, &placemarker_token));
args->ends[argc] = total + 1;
if (CPP_OPTION (pfile, c99) && CPP_PEDANTIC (pfile))
}
else
{
- cpp_error (pfile, "not enough arguments for macro \"%s\"", hp->name);
+ cpp_error (pfile, "%u arguments is not enough for macro \"%s\"",
+ argc, hp->name);
return 1;
}
}
else if (argc > macro->paramc
&& !(macro->paramc == 0 && argc == 1 && empty_argument (args, 0)))
{
- cpp_error (pfile, "too many arguments for macro \"%s\"", hp->name);
+ cpp_error (pfile, "%u arguments is too many for macro \"%s\"",
+ argc, hp->name);
return 1;
}
pfile->paste_level = pfile->cur_context;
second = _cpp_get_token (pfile);
pfile->paste_level = 0;
+ context = CURRENT_CONTEXT (pfile);
/* Ignore placemarker argument tokens (cannot be from an empty
macro since macros are not expanded). */
a varargs parameter: the comma disappears if b was given
no actual arguments (not merely if b is an empty
argument). */
- if (token->type == CPP_COMMA && second->flags & VOID_REST)
+ if (token->type == CPP_COMMA && (context->flags & CONTEXT_VARARGS))
pasted = duplicate_token (pfile, second);
else
pasted = duplicate_token (pfile, token);
the author probably intended the ## to trigger
the special extended semantics (see above). */
if (token->type == CPP_COMMA
- && IS_ARG_CONTEXT (CURRENT_CONTEXT (pfile))
- && ON_REST_ARG (CURRENT_CONTEXT (pfile) - 1))
+ && (context->flags & CONTEXT_VARARGS))
/* no warning */;
else
cpp_warning (pfile,
/* See if there is another token to be pasted onto the one we just
constructed. */
token = pasted;
- context = CURRENT_CONTEXT (pfile);
/* and loop */
}
return token;
context->posn = 0;
context->level = args->level;
context->flags = CONTEXT_ARG | CONTEXT_RAW;
+ if ((context[-1].u.list->flags & VAR_ARGS)
+ && token->val.aux + 1 == (unsigned) context[-1].u.list->paramc)
+ context->flags |= CONTEXT_VARARGS;
context->pushed_token = 0;
/* Set the flags of the first token. There is one. */