aboutsummaryrefslogtreecommitdiff
path: root/gcc/cppmacro.c
diff options
context:
space:
mode:
authorNeil Booth <neil@daikokuya.demon.co.uk>2002-06-09 20:04:17 +0000
committerNeil Booth <neil@gcc.gnu.org>2002-06-09 20:04:17 +0000
commit1ce676a061d91b434a62d90d7a2f5d8fdf07e8af (patch)
treea2b5349f1ee2ab348cfc3c37c8f4c9a4ca8a6b1b /gcc/cppmacro.c
parent25f2e176414291186a206bb5f7cdc3e98563b38b (diff)
downloadgcc-1ce676a061d91b434a62d90d7a2f5d8fdf07e8af.zip
gcc-1ce676a061d91b434a62d90d7a2f5d8fdf07e8af.tar.gz
gcc-1ce676a061d91b434a62d90d7a2f5d8fdf07e8af.tar.bz2
cpphash.h (_cpp_push_text_context): Update.
* cpphash.h (_cpp_push_text_context): Update. (_cpp_arguments_ok): New. * cppmacro.c (_cpp_arguments_ok): New, split out from... (collect_args): ...here. (_cpp_push_text_context): Change inputs. * cpptrad.c (struct fun_macro, maybe_start_funlike, save_argument, replace_args_and_push): New. (lex_identifier, _cpp_lex_identifier_trad, scan_parameters): Don't use IS macros directly. (scan_out_logical_line): Handle function-like macro argument collection. (push_replacement_text): Update. (replacement_length): Remove. (_cpp_create_trad_definition): Don't skip whitespace before checking for '('. From-SVN: r54412
Diffstat (limited to 'gcc/cppmacro.c')
-rw-r--r--gcc/cppmacro.c98
1 files changed, 57 insertions, 41 deletions
diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c
index 5e954d4..d517948 100644
--- a/gcc/cppmacro.c
+++ b/gcc/cppmacro.c
@@ -451,6 +451,52 @@ paste_all_tokens (pfile, lhs)
push_token_context (pfile, NULL, lhs, 1);
}
+/* Returns TRUE if the number of arguments ARGC supplied in an
+ invocation of the MACRO referenced by NODE is valid. An empty
+ invocation to a macro with no parameters should pass ARGC as zero.
+
+ Note that MACRO cannot necessarily be deduced from NODE, in case
+ NODE was redefined whilst collecting arguments. */
+bool
+_cpp_arguments_ok (pfile, macro, node, argc)
+ cpp_reader *pfile;
+ cpp_macro *macro;
+ const cpp_hashnode *node;
+ unsigned int argc;
+{
+ if (argc == macro->paramc)
+ return true;
+
+ if (argc < macro->paramc)
+ {
+ /* As an extension, a rest argument is allowed to not appear in
+ the invocation at all.
+ e.g. #define debug(format, args...) something
+ debug("string");
+
+ This is exactly the same as if there had been an empty rest
+ argument - debug("string", ). */
+
+ if (argc + 1 == macro->paramc && macro->variadic)
+ {
+ if (CPP_PEDANTIC (pfile) && ! macro->syshdr)
+ cpp_error (pfile, DL_PEDWARN,
+ "ISO C99 requires rest arguments to be used");
+ return true;
+ }
+
+ cpp_error (pfile, DL_ERROR,
+ "macro \"%s\" requires %u arguments, but only %u given",
+ NODE_NAME (node), macro->paramc, argc);
+ }
+ else
+ cpp_error (pfile, DL_ERROR,
+ "macro \"%s\" passed %u arguments, but takes just %u",
+ NODE_NAME (node), argc, macro->paramc);
+
+ return false;
+}
+
/* Reads and returns the arguments to a function-like macro
invocation. Assumes the opening parenthesis has been processed.
If there is an error, emits an appropriate diagnostic and returns
@@ -466,7 +512,6 @@ collect_args (pfile, node)
macro_arg *args, *arg;
const cpp_token *token;
unsigned int argc;
- bool error = false;
macro = node->value.macro;
if (macro->paramc)
@@ -561,47 +606,17 @@ collect_args (pfile, node)
cpp_error (pfile, DL_ERROR,
"unterminated argument list invoking macro \"%s\"",
NODE_NAME (node));
- error = true;
- }
- else if (argc < macro->paramc)
- {
- /* As an extension, a rest argument is allowed to not appear in
- the invocation at all.
- e.g. #define debug(format, args...) something
- debug("string");
-
- This is exactly the same as if there had been an empty rest
- argument - debug("string", ). */
-
- if (argc + 1 == macro->paramc && macro->variadic)
- {
- if (CPP_PEDANTIC (pfile) && ! macro->syshdr)
- cpp_error (pfile, DL_PEDWARN,
- "ISO C99 requires rest arguments to be used");
- }
- else
- {
- cpp_error (pfile, DL_ERROR,
- "macro \"%s\" requires %u arguments, but only %u given",
- NODE_NAME (node), macro->paramc, argc);
- error = true;
- }
}
- else if (argc > macro->paramc)
+ else
{
- /* Empty argument to a macro taking no arguments is OK. */
- if (argc != 1 || arg->count)
- {
- cpp_error (pfile, DL_ERROR,
- "macro \"%s\" passed %u arguments, but takes just %u",
- NODE_NAME (node), argc, macro->paramc);
- error = true;
- }
+ /* A single empty argument is counted as no argument. */
+ if (argc == 1 && macro->paramc == 0 && args[0].count == 0)
+ argc = 0;
+ if (_cpp_arguments_ok (pfile, macro, node, argc))
+ return base_buff;
}
- if (!error)
- return base_buff;
-
+ /* An error occurred. */
_cpp_release_buff (pfile, base_buff);
return NULL;
}
@@ -919,10 +934,11 @@ push_token_context (pfile, macro, first, count)
/* Push a traditional macro's replacement text. */
void
-_cpp_push_text_context (pfile, macro, start, end)
+_cpp_push_text_context (pfile, macro, start, len)
cpp_reader *pfile;
cpp_hashnode *macro;
- const uchar *start, *end;
+ const uchar *start;
+ size_t len;
{
cpp_context *context = next_context (pfile);
@@ -930,7 +946,7 @@ _cpp_push_text_context (pfile, macro, start, end)
context->macro = macro;
context->buff = NULL;
CUR (context) = start;
- RLIMIT (context) = end;
+ RLIMIT (context) = start + len;
}
/* Expand an argument ARG before replacing parameters in a