/* CPP Library. (Directive handling.)
- Copyright (C) 1986-2022 Free Software Foundation, Inc.
+ Copyright (C) 1986-2023 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
D(elifndef, T_ELIFNDEF, STDC2X, COND | ELIFDEF) \
D(error, T_ERROR, STDC89, 0) \
D(pragma, T_PRAGMA, STDC89, IN_I) \
- D(warning, T_WARNING, EXTENSION, 0) \
+ D(warning, T_WARNING, STDC2X, 0) \
D(include_next, T_INCLUDE_NEXT, EXTENSION, INCL | EXPAND) \
D(ident, T_IDENT, EXTENSION, IN_I) \
D(import, T_IMPORT, EXTENSION, INCL | EXPAND) /* ObjC */ \
&& !(dir == &dtable[T_IMPORT] && CPP_OPTION (pfile, objc))
&& CPP_PEDANTIC (pfile))
cpp_error (pfile, CPP_DL_PEDWARN, "#%s is a GCC extension", dir->name);
+ else if (dir == &dtable[T_WARNING])
+ {
+ if (CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, warning_directive))
+ {
+ if (CPP_OPTION (pfile, cplusplus))
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "#%s before C++23 is a GCC extension", dir->name);
+ else
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "#%s before C2X is a GCC extension", dir->name);
+ }
+ else if (CPP_OPTION (pfile, cpp_warn_c11_c2x_compat) > 0)
+ cpp_warning (pfile, CPP_W_C11_C2X_COMPAT,
+ "#%s before C2X is a GCC extension", dir->name);
+ }
else if (((dir->flags & DEPRECATED) != 0
|| (dir == &dtable[T_IMPORT] && !CPP_OPTION (pfile, objc)))
&& CPP_OPTION (pfile, cpp_warn_deprecated))
/* Check if we have a known directive. INDENTED is true if the
'#' of the directive was indented. This function is in this file
- to save unnecessarily exporting dtable etc. to lex.c. Returns
+ to save unnecessarily exporting dtable etc. to lex.cc. Returns
nonzero if the line of tokens has been handled, zero if we should
continue processing the line. */
int
does not cause '#define foo bar' to get executed when
compiled with -save-temps, we recognize directives in
- -fpreprocessed mode only if the # is in column 1. macro.c
+ -fpreprocessed mode only if the # is in column 1. macro.cc
puts a space in front of any '#' at the start of a macro.
We exclude the -fdirectives-only case because macro expansion
return NULL;
}
-/* Process a #define directive. Most work is done in macro.c. */
+/* Process a #define directive. Most work is done in macro.cc. */
static void
do_define (cpp_reader *pfile)
{
if (node)
{
+ /* This is a better location than pfile->directive_line to store
+ as the macro location. */
+ const location_t name_loc = cpp_diagnostic_get_current_location (pfile);
+
/* If we have been requested to expand comments into macros,
then re-enable saving of comments. */
pfile->state.save_comments =
if (pfile->cb.before_define)
pfile->cb.before_define (pfile);
- if (_cpp_create_definition (pfile, node))
+ if (_cpp_create_definition (pfile, node, name_loc))
if (pfile->cb.define)
pfile->cb.define (pfile, pfile->directive_line, node);
"undefining \"%s\"", NODE_NAME (node));
else if (cpp_builtin_macro_p (node)
&& CPP_OPTION (pfile, warn_builtin_macro_redefined))
- cpp_warning_with_line (pfile, CPP_W_BUILTIN_MACRO_REDEFINED,
- pfile->directive_line, 0,
- "undefining \"%s\"", NODE_NAME (node));
+ cpp_warning (pfile, CPP_W_BUILTIN_MACRO_REDEFINED,
+ "undefining \"%s\"", NODE_NAME (node));
if (node->value.macro
&& CPP_OPTION (pfile, warn_unused_macros))
{
/* Invalid name comes from macro expansion, _cpp_backup_tokens
won't allow backing 2 tokens. */
- /* ??? The token buffer is leaked. Perhaps if def_pragma hook
- reads both tokens, we could perhaps free it, but if it doesn't,
- we don't know the exact lifespan. */
- cpp_token *toks = XNEWVEC (cpp_token, 2);
+ const auto tok_buff = _cpp_get_buff (pfile, 2 * sizeof (cpp_token));
+ const auto toks = (cpp_token *)tok_buff->base;
toks[0] = ns_token;
toks[0].flags |= NO_EXPAND;
toks[1] = *token;
- toks[1].flags |= NO_EXPAND;
+ toks[1].flags |= NO_EXPAND | PREV_WHITE;
_cpp_push_token_context (pfile, NULL, toks, 2);
+ /* Arrange to free this buffer when no longer needed. */
+ pfile->context->buff = tok_buff;
}
pfile->cb.def_pragma (pfile, pfile->directive_line);
}
maxcount = 50;
toks = XNEWVEC (cpp_token, maxcount);
toks[0] = pfile->directive_result;
+ toks[0].src_loc = expansion_loc;
do
{
else
{
count = 1;
- toks = XNEW (cpp_token);
- toks[0] = pfile->directive_result;
+ toks = &pfile->avoid_paste;
/* If we handled the entire pragma internally, make sure we get the
line number correct for the next token. */
int
_cpp_do__Pragma (cpp_reader *pfile, location_t expansion_loc)
{
+ /* Make sure we don't invalidate the string token, if the closing parenthesis
+ ended up on a different line. */
+ ++pfile->keep_tokens;
const cpp_token *string = get__Pragma_string (pfile);
+ --pfile->keep_tokens;
+
pfile->directive_result.type = CPP_PADDING;
if (string)
{
_cpp_clean_line (pfile);
nbuf->sysp = 1;
- if (!_cpp_create_definition (pfile, h))
+ if (!_cpp_create_definition (pfile, h, 0))
abort ();
_cpp_pop_buffer (pfile);
}