/* CPP Library. (Directive handling.)
- Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1986-2015 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
struct if_stack
{
struct if_stack *next;
- linenum_type line; /* Line where condition started. */
+ source_location line; /* Line where condition started. */
const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */
bool skip_elses; /* Can future #else / #elif be skipped? */
bool was_skipping; /* If were skipping on entry. */
static void do_pragma_poison (cpp_reader *);
static void do_pragma_system_header (cpp_reader *);
static void do_pragma_dependency (cpp_reader *);
+static void do_pragma_warning_or_error (cpp_reader *, bool error);
+static void do_pragma_warning (cpp_reader *);
+static void do_pragma_error (cpp_reader *);
static void do_linemarker (cpp_reader *);
static const cpp_token *get_token_no_padding (cpp_reader *);
static const cpp_token *get__Pragma_string (cpp_reader *);
;
}
-/* Ensure there are no stray tokens at the end of a directive. If
- EXPAND is true, tokens macro-expanding to nothing are allowed. */
+/* Helper function for check_oel. */
+
static void
-check_eol (cpp_reader *pfile, bool expand)
+check_eol_1 (cpp_reader *pfile, bool expand, int reason)
{
if (! SEEN_EOL () && (expand
? cpp_get_token (pfile)
: _cpp_lex_token (pfile))->type != CPP_EOF)
- cpp_error (pfile, CPP_DL_PEDWARN, "extra tokens at end of #%s directive",
- pfile->directive->name);
+ cpp_pedwarning (pfile, reason, "extra tokens at end of #%s directive",
+ pfile->directive->name);
+}
+
+/* Variant of check_eol used for Wendif-labels warnings. */
+
+static void
+check_eol_endif_labels (cpp_reader *pfile)
+{
+ check_eol_1 (pfile, false, CPP_W_ENDIF_LABELS);
+}
+
+/* Ensure there are no stray tokens at the end of a directive. If
+ EXPAND is true, tokens macro-expanding to nothing are allowed. */
+
+static void
+check_eol (cpp_reader *pfile, bool expand)
+{
+ check_eol_1 (pfile, expand, CPP_W_NONE);
}
/* Ensure there are no stray tokens other than comments at the end of
if (no_expand)
pfile->state.prevent_expansion++;
- _cpp_scan_out_logical_line (pfile, NULL);
+ _cpp_scan_out_logical_line (pfile, NULL, false);
if (no_expand)
pfile->state.prevent_expansion--;
We exclude the -fdirectives-only case because macro expansion
has not been performed yet, and block comments can cause spaces
- to preceed the directive. */
+ to precede the directive. */
if (CPP_OPTION (pfile, preprocessed)
&& !CPP_OPTION (pfile, directives_only)
&& (indented || !(dir->flags & IN_I)))
if (is_def_or_undef && node == pfile->spec_nodes.n_defined)
cpp_error (pfile, CPP_DL_ERROR,
"\"defined\" cannot be used as a macro name");
+ else if (is_def_or_undef
+ && (node == pfile->spec_nodes.n__has_include__
+ || node == pfile->spec_nodes.n__has_include_next__))
+ cpp_error (pfile, CPP_DL_ERROR,
+ "\"__has_include__\" cannot be used as a macro name");
else if (! (node->flags & NODE_POISONED))
return node;
}
if (node->flags & NODE_WARN)
cpp_error (pfile, CPP_DL_WARNING,
"undefining \"%s\"", NODE_NAME (node));
+ else if ((node->flags & NODE_BUILTIN)
+ && 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));
if (CPP_OPTION (pfile, warn_unused_macros))
_cpp_warn_if_unused_macro (pfile, node, NULL);
static void
do_line (cpp_reader *pfile)
{
- const struct line_maps *line_table = pfile->line_table;
- const struct line_map *map = &line_table->maps[line_table->used - 1];
+ struct line_maps *line_table = pfile->line_table;
+ const struct line_map *map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
/* skip_rest_of_line() may cause line table to be realloc()ed so note down
sysp right now. */
- unsigned char map_sysp = map->sysp;
+ unsigned char map_sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (map);
const cpp_token *token;
- const char *new_file = map->to_file;
+ const char *new_file = ORDINARY_MAP_FILE_NAME (map);
linenum_type new_lineno;
/* C99 raised the minimum limit on #line numbers. */
skip_rest_of_line (pfile);
_cpp_do_file_change (pfile, LC_RENAME_VERBATIM, new_file, new_lineno,
map_sysp);
+ line_table->seen_line_directive = true;
}
/* Interpret the # 44 "file" [flags] notation, which has slightly
static void
do_linemarker (cpp_reader *pfile)
{
- const struct line_maps *line_table = pfile->line_table;
- const struct line_map *map = &line_table->maps[line_table->used - 1];
+ struct line_maps *line_table = pfile->line_table;
+ const struct line_map *map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
const cpp_token *token;
- const char *new_file = map->to_file;
+ const char *new_file = ORDINARY_MAP_FILE_NAME (map);
linenum_type new_lineno;
- unsigned int new_sysp = map->sysp;
+ unsigned int new_sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (map);
enum lc_reason reason = LC_RENAME_VERBATIM;
int flag;
bool wrapped;
pfile->line_table->highest_location--;
_cpp_do_file_change (pfile, reason, new_file, new_lineno, new_sysp);
+ line_table->seen_line_directive = true;
}
/* Arrange the file_change callback. pfile->line has changed to
const struct line_map *map = linemap_add (pfile->line_table, reason, sysp,
to_file, file_line);
if (map != NULL)
- linemap_line_start (pfile->line_table, map->to_line, 127);
+ linemap_line_start (pfile->line_table,
+ ORDINARY_MAP_STARTING_LINE_NUMBER (map),
+ 127);
if (pfile->cb.file_change)
pfile->cb.file_change (pfile, map);
register_pragma_internal (pfile, "GCC", "system_header",
do_pragma_system_header);
register_pragma_internal (pfile, "GCC", "dependency", do_pragma_dependency);
+ register_pragma_internal (pfile, "GCC", "warning", do_pragma_warning);
+ register_pragma_internal (pfile, "GCC", "error", do_pragma_error);
}
/* Return the number of registered pragmas in PE. */
do_pragma (cpp_reader *pfile)
{
const struct pragma_entry *p = NULL;
- const cpp_token *token, *pragma_token = pfile->cur_token;
+ const cpp_token *token, *pragma_token;
+ source_location pragma_token_virt_loc = 0;
cpp_token ns_token;
unsigned int count = 1;
pfile->state.prevent_expansion++;
- token = cpp_get_token (pfile);
+ pragma_token = token = cpp_get_token_with_location (pfile,
+ &pragma_token_virt_loc);
ns_token = *token;
if (token->type == CPP_NAME)
{
bool allow_name_expansion = p->allow_expansion;
if (allow_name_expansion)
pfile->state.prevent_expansion--;
+
token = cpp_get_token (pfile);
if (token->type == CPP_NAME)
p = lookup_pragma_entry (p->u.space, token->val.node.node);
{
if (p->is_deferred)
{
- pfile->directive_result.src_loc = pragma_token->src_loc;
+ pfile->directive_result.src_loc = pragma_token_virt_loc;
pfile->directive_result.type = CPP_PRAGMA;
pfile->directive_result.flags = pragma_token->flags;
pfile->directive_result.val.pragma = p->u.ident;
free ((void *) fname);
}
+/* Issue a diagnostic with the message taken from the pragma. If
+ ERROR is true, the diagnostic is a warning, otherwise, it is an
+ error. */
+static void
+do_pragma_warning_or_error (cpp_reader *pfile, bool error)
+{
+ const cpp_token *tok = _cpp_lex_token (pfile);
+ cpp_string str;
+ if (tok->type != CPP_STRING
+ || !cpp_interpret_string_notranslate (pfile, &tok->val.str, 1, &str,
+ CPP_STRING)
+ || str.len == 0)
+ {
+ cpp_error (pfile, CPP_DL_ERROR, "invalid \"#pragma GCC %s\" directive",
+ error ? "error" : "warning");
+ return;
+ }
+ cpp_error (pfile, error ? CPP_DL_ERROR : CPP_DL_WARNING,
+ "%s", str.text);
+ free ((void *)str.text);
+}
+
+/* Issue a warning diagnostic. */
+static void
+do_pragma_warning (cpp_reader *pfile)
+{
+ do_pragma_warning_or_error (pfile, false);
+}
+
+/* Issue an error diagnostic. */
+static void
+do_pragma_error (cpp_reader *pfile)
+{
+ do_pragma_warning_or_error (pfile, true);
+}
+
/* Get a token but skip padding. */
static const cpp_token *
get_token_no_padding (cpp_reader *pfile)
saved_cur_token = pfile->cur_token;
saved_cur_run = pfile->cur_run;
- pfile->context = XNEW (cpp_context);
- pfile->context->macro = 0;
- pfile->context->prev = 0;
- pfile->context->next = 0;
+ pfile->context = XCNEW (cpp_context);
/* Inline run_directive, since we need to delay the _cpp_pop_buffer
until we've read all of the tokens that we want. */
/* Only check EOL if was not originally skipping. */
if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels))
- check_eol (pfile, false);
+ check_eol_endif_labels (pfile);
}
}
}
ifs->type = T_ELIF;
- if (! ifs->was_skipping)
+ /* See DR#412: "Only the first group whose control condition
+ evaluates to true (nonzero) is processed; any following groups
+ are skipped and their controlling directives are processed as
+ if they were in a group that is skipped." */
+ if (ifs->skip_elses)
+ pfile->state.skipping = 1;
+ else
{
- bool value;
- /* The standard mandates that the expression be parsed even
- if we are skipping elses at this point -- the lexical
- restrictions on #elif only apply to skipped groups, but
- this group is not being skipped. Temporarily set
- skipping to false to get lexer warnings. */
- pfile->state.skipping = 0;
- value = _cpp_parse_expr (pfile, false);
- if (ifs->skip_elses)
- pfile->state.skipping = 1;
- else
- {
- pfile->state.skipping = ! value;
- ifs->skip_elses = value;
- }
+ pfile->state.skipping = ! _cpp_parse_expr (pfile, false);
+ ifs->skip_elses = ! pfile->state.skipping;
}
/* Invalidate any controlling macro. */
{
/* Only check EOL if was not originally skipping. */
if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels))
- check_eol (pfile, false);
+ check_eol_endif_labels (pfile);
/* If potential control macro, we go back outside again. */
if (ifs->next == 0 && ifs->mi_cmacro)
void
cpp_define_formatted (cpp_reader *pfile, const char *fmt, ...)
{
- char *ptr = NULL;
+ char *ptr;
va_list ap;
va_start (ap, fmt);
- vasprintf (&ptr, fmt, ap);
+ ptr = xvasprintf (fmt, ap);
va_end (ap);
cpp_define (pfile, ptr);
cpp_buffer *buffer = pfile->buffer;
struct _cpp_file *inc = buffer->file;
struct if_stack *ifs;
+ const unsigned char *to_free;
/* Walk back up the conditional stack till we reach its level at
entry to this file, issuing error messages. */
/* _cpp_do_file_change expects pfile->buffer to be the new one. */
pfile->buffer = buffer->prev;
+ to_free = buffer->to_free;
free (buffer->notes);
/* Free the buffer object now; we may want to push a new buffer
if (inc)
{
- _cpp_pop_file_buffer (pfile, inc);
+ _cpp_pop_file_buffer (pfile, inc, to_free);
_cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0);
}
node->directive_index = i;
}
}
+
+/* Extract header file from a bracket include. Parsing starts after '<'.
+ The string is malloced and must be freed by the caller. */
+char *
+_cpp_bracket_include(cpp_reader *pfile)
+{
+ return glue_header_name (pfile);
+}
+