summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cpplib.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cpplib.c')
-rw-r--r--contrib/gcc/cpplib.c432
1 files changed, 255 insertions, 177 deletions
diff --git a/contrib/gcc/cpplib.c b/contrib/gcc/cpplib.c
index 0f0063b..818451d 100644
--- a/contrib/gcc/cpplib.c
+++ b/contrib/gcc/cpplib.c
@@ -70,11 +70,14 @@ struct pragma_entry
conditional; IF_COND an opening conditional. INCL means to treat
"..." and <...> as q-char and h-char sequences respectively. IN_I
means this directive should be handled even if -fpreprocessed is in
- effect (these are the directives with callback hooks). */
+ effect (these are the directives with callback hooks).
+
+ EXPAND is set on directives that are always macro-expanded. */
#define COND (1 << 0)
#define IF_COND (1 << 1)
#define INCL (1 << 2)
#define IN_I (1 << 3)
+#define EXPAND (1 << 4)
/* Defines one #-directive, including how to handle it. */
typedef void (*directive_handler) PARAMS ((cpp_reader *));
@@ -82,7 +85,7 @@ typedef struct directive directive;
struct directive
{
directive_handler handler; /* Function to handle directive. */
- const U_CHAR *name; /* Name of directive. */
+ const uchar *name; /* Name of directive. */
unsigned short length; /* Length of name. */
unsigned char origin; /* Origin of directive. */
unsigned char flags; /* Flags describing this directive. */
@@ -93,6 +96,7 @@ struct directive
static void skip_rest_of_line PARAMS ((cpp_reader *));
static void check_eol PARAMS ((cpp_reader *));
static void start_directive PARAMS ((cpp_reader *));
+static void prepare_directive_trad PARAMS ((cpp_reader *));
static void end_directive PARAMS ((cpp_reader *, int));
static void directive_diagnostics
PARAMS ((cpp_reader *, const directive *, int));
@@ -103,11 +107,11 @@ static const cpp_token *parse_include PARAMS ((cpp_reader *));
static void push_conditional PARAMS ((cpp_reader *, int, int,
const cpp_hashnode *));
static unsigned int read_flag PARAMS ((cpp_reader *, unsigned int));
-static U_CHAR *dequote_string PARAMS ((cpp_reader *, const U_CHAR *,
+static uchar *dequote_string PARAMS ((cpp_reader *, const uchar *,
unsigned int));
-static int strtoul_for_line PARAMS ((const U_CHAR *, unsigned int,
+static int strtoul_for_line PARAMS ((const uchar *, unsigned int,
unsigned long *));
-static void do_diagnostic PARAMS ((cpp_reader *, enum error_type, int));
+static void do_diagnostic PARAMS ((cpp_reader *, int, int));
static cpp_hashnode *lex_macro_node PARAMS ((cpp_reader *));
static void do_include_common PARAMS ((cpp_reader *, enum include_type));
static struct pragma_entry *lookup_pragma_entry
@@ -141,31 +145,24 @@ static void handle_assertion PARAMS ((cpp_reader *, const char *, int));
#define DIRECTIVE_TABLE \
D(define, T_DEFINE = 0, KANDR, IN_I) /* 270554 */ \
-D(include, T_INCLUDE, KANDR, INCL) /* 52262 */ \
+D(include, T_INCLUDE, KANDR, INCL | EXPAND) /* 52262 */ \
D(endif, T_ENDIF, KANDR, COND) /* 45855 */ \
D(ifdef, T_IFDEF, KANDR, COND | IF_COND) /* 22000 */ \
-D(if, T_IF, KANDR, COND | IF_COND) /* 18162 */ \
+D(if, T_IF, KANDR, COND | IF_COND | EXPAND) /* 18162 */ \
D(else, T_ELSE, KANDR, COND) /* 9863 */ \
D(ifndef, T_IFNDEF, KANDR, COND | IF_COND) /* 9675 */ \
D(undef, T_UNDEF, KANDR, IN_I) /* 4837 */ \
-D(line, T_LINE, KANDR, 0) /* 2465 */ \
-D(elif, T_ELIF, STDC89, COND) /* 610 */ \
+D(line, T_LINE, KANDR, EXPAND) /* 2465 */ \
+D(elif, T_ELIF, STDC89, COND | EXPAND) /* 610 */ \
D(error, T_ERROR, STDC89, 0) /* 475 */ \
D(pragma, T_PRAGMA, STDC89, IN_I) /* 195 */ \
D(warning, T_WARNING, EXTENSION, 0) /* 22 */ \
-D(include_next, T_INCLUDE_NEXT, EXTENSION, INCL) /* 19 */ \
+D(include_next, T_INCLUDE_NEXT, EXTENSION, INCL | EXPAND) /* 19 */ \
D(ident, T_IDENT, EXTENSION, IN_I) /* 11 */ \
-D(import, T_IMPORT, EXTENSION, INCL) /* 0 ObjC */ \
+D(import, T_IMPORT, EXTENSION, INCL | EXPAND) /* 0 ObjC */ \
D(assert, T_ASSERT, EXTENSION, 0) /* 0 SVR4 */ \
D(unassert, T_UNASSERT, EXTENSION, 0) /* 0 SVR4 */ \
-SCCS_ENTRY /* 0 SVR4? */
-
-/* #sccs is not always recognized. */
-#ifdef SCCS_DIRECTIVE
-# define SCCS_ENTRY D(sccs, T_SCCS, EXTENSION, 0)
-#else
-# define SCCS_ENTRY /* nothing */
-#endif
+D(sccs, T_SCCS, EXTENSION, 0) /* 0 SVR4? */
/* Use the table to generate a series of prototypes, an enum for the
directive names, and an array of directive handlers. */
@@ -185,7 +182,7 @@ enum
/* Don't invoke CONCAT2 with any whitespace or K&R cc will fail. */
#define D(name, t, origin, flags) \
-{ CONCAT2(do_,name), (const U_CHAR *) STRINGX(name), \
+{ CONCAT2(do_,name), (const uchar *) STRINGX(name), \
sizeof STRINGX(name) - 1, origin, flags },
static const directive dtable[] =
{
@@ -225,8 +222,8 @@ check_eol (pfile)
cpp_reader *pfile;
{
if (! SEEN_EOL () && _cpp_lex_token (pfile)->type != CPP_EOF)
- cpp_pedwarn (pfile, "extra tokens at end of #%s directive",
- pfile->directive->name);
+ cpp_error (pfile, DL_PEDWARN, "extra tokens at end of #%s directive",
+ pfile->directive->name);
}
/* Called when entering a directive, _Pragma or command-line directive. */
@@ -248,8 +245,16 @@ end_directive (pfile, skip_line)
cpp_reader *pfile;
int skip_line;
{
+ if (CPP_OPTION (pfile, traditional))
+ {
+ /* Revert change of prepare_directive_trad. */
+ pfile->state.prevent_expansion--;
+
+ if (pfile->directive != &dtable[T_DEFINE])
+ _cpp_remove_overlay (pfile);
+ }
/* We don't skip for an assembler #. */
- if (skip_line)
+ else if (skip_line)
{
skip_rest_of_line (pfile);
if (!pfile->keep_tokens)
@@ -262,11 +267,40 @@ end_directive (pfile, skip_line)
/* Restore state. */
pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments);
pfile->state.in_directive = 0;
+ pfile->state.in_expression = 0;
pfile->state.angled_headers = 0;
pfile->directive = 0;
}
-/* Output diagnostics for a directive DIR. INDENTED is non-zero if
+/* Prepare to handle the directive in pfile->directive. */
+static void
+prepare_directive_trad (pfile)
+ cpp_reader *pfile;
+{
+ if (pfile->directive != &dtable[T_DEFINE])
+ {
+ bool no_expand = (pfile->directive
+ && ! (pfile->directive->flags & EXPAND));
+ bool was_skipping = pfile->state.skipping;
+
+ pfile->state.skipping = false;
+ pfile->state.in_expression = (pfile->directive == &dtable[T_IF]
+ || pfile->directive == &dtable[T_ELIF]);
+ if (no_expand)
+ pfile->state.prevent_expansion++;
+ _cpp_read_logical_line_trad (pfile);
+ if (no_expand)
+ pfile->state.prevent_expansion--;
+ pfile->state.skipping = was_skipping;
+ _cpp_overlay_buffer (pfile, pfile->out.base,
+ pfile->out.cur - pfile->out.base);
+ }
+
+ /* Stop ISO C from expanding anything. */
+ pfile->state.prevent_expansion++;
+}
+
+/* Output diagnostics for a directive DIR. INDENTED is nonzero if
the '#' was indented. */
static void
directive_diagnostics (pfile, dir, indented)
@@ -278,7 +312,7 @@ directive_diagnostics (pfile, dir, indented)
if (CPP_PEDANTIC (pfile)
&& ! pfile->state.skipping
&& dir->origin == EXTENSION)
- cpp_pedwarn (pfile, "#%s is a GCC extension", dir->name);
+ cpp_error (pfile, DL_PEDWARN, "#%s is a GCC extension", dir->name);
/* Traditionally, a directive is ignored unless its # is in
column 1. Therefore in code intended to work with K+R
@@ -289,22 +323,23 @@ directive_diagnostics (pfile, dir, indented)
if (CPP_WTRADITIONAL (pfile))
{
if (dir == &dtable[T_ELIF])
- cpp_warning (pfile, "suggest not using #elif in traditional C");
+ cpp_error (pfile, DL_WARNING,
+ "suggest not using #elif in traditional C");
else if (indented && dir->origin == KANDR)
- cpp_warning (pfile,
- "traditional C ignores #%s with the # indented",
- dir->name);
+ cpp_error (pfile, DL_WARNING,
+ "traditional C ignores #%s with the # indented",
+ dir->name);
else if (!indented && dir->origin != KANDR)
- cpp_warning (pfile,
- "suggest hiding #%s from traditional C with an indented #",
- dir->name);
+ cpp_error (pfile, DL_WARNING,
+ "suggest hiding #%s from traditional C with an indented #",
+ dir->name);
}
}
-/* Check if we have a known directive. INDENTED is non-zero if the
+/* Check if we have a known directive. INDENTED is nonzero if the
'#' of the directive was indented. This function is in this file
to save unnecessarily exporting dtable etc. to cpplex.c. Returns
- non-zero if the line of tokens has been handled, zero if we should
+ nonzero if the line of tokens has been handled, zero if we should
continue processing the line. */
int
_cpp_handle_directive (pfile, indented)
@@ -313,8 +348,17 @@ _cpp_handle_directive (pfile, indented)
{
const directive *dir = 0;
const cpp_token *dname;
+ bool was_parsing_args = pfile->state.parsing_args;
int skip = 1;
+ if (was_parsing_args)
+ {
+ if (CPP_OPTION (pfile, pedantic))
+ cpp_error (pfile, DL_PEDWARN,
+ "embedding a directive within macro arguments is not portable");
+ pfile->state.parsing_args = 0;
+ pfile->state.prevent_expansion = 0;
+ }
start_directive (pfile);
dname = _cpp_lex_token (pfile);
@@ -323,14 +367,15 @@ _cpp_handle_directive (pfile, indented)
if (dname->val.node->directive_index)
dir = &dtable[dname->val.node->directive_index - 1];
}
- /* We do not recognise the # followed by a number extension in
+ /* We do not recognize the # followed by a number extension in
assembler code. */
else if (dname->type == CPP_NUMBER && CPP_OPTION (pfile, lang) != CLK_ASM)
{
dir = &linemarker_dir;
if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed)
&& ! pfile->state.skipping)
- cpp_pedwarn (pfile, "style of line directive is a GCC extension");
+ cpp_error (pfile, DL_PEDWARN,
+ "style of line directive is a GCC extension");
}
if (dir)
@@ -362,6 +407,7 @@ _cpp_handle_directive (pfile, indented)
skipping or not, we should lex angle-bracketed headers
correctly, and maybe output some diagnostics. */
pfile->state.angled_headers = dir->flags & INCL;
+ pfile->state.directive_wants_padding = dir->flags & INCL;
if (! CPP_OPTION (pfile, preprocessed))
directive_diagnostics (pfile, dir, indented);
if (pfile->state.skipping && !(dir->flags & COND))
@@ -379,19 +425,27 @@ _cpp_handle_directive (pfile, indented)
if (CPP_OPTION (pfile, lang) == CLK_ASM)
skip = 0;
else if (!pfile->state.skipping)
- cpp_error (pfile, "invalid preprocessing directive #%s",
+ cpp_error (pfile, DL_ERROR, "invalid preprocessing directive #%s",
cpp_token_as_text (pfile, dname));
}
+ pfile->directive = dir;
+ if (CPP_OPTION (pfile, traditional))
+ prepare_directive_trad (pfile);
+
if (dir)
- {
- pfile->directive = dir;
- (*pfile->directive->handler) (pfile);
- }
+ (*pfile->directive->handler) (pfile);
else if (skip == 0)
_cpp_backup_tokens (pfile, 1);
end_directive (pfile, skip);
+ if (was_parsing_args)
+ {
+ /* Restore state when within macro args. */
+ pfile->state.parsing_args = 2;
+ pfile->state.prevent_expansion = 1;
+ pfile->buffer->saved_flags |= PREV_WHITE;
+ }
return skip;
}
@@ -404,7 +458,7 @@ run_directive (pfile, dir_no, buf, count)
const char *buf;
size_t count;
{
- cpp_push_buffer (pfile, (const U_CHAR *) buf, count,
+ cpp_push_buffer (pfile, (const uchar *) buf, count,
/* from_stage3 */ true, 1);
/* Disgusting hack. */
if (dir_no == T_PRAGMA)
@@ -413,6 +467,8 @@ run_directive (pfile, dir_no, buf, count)
/* We don't want a leading # to be interpreted as a directive. */
pfile->buffer->saved_flags = 0;
pfile->directive = &dtable[dir_no];
+ if (CPP_OPTION (pfile, traditional))
+ prepare_directive_trad (pfile);
(void) (*pfile->directive->handler) (pfile);
end_directive (pfile, 1);
if (dir_no == T_PRAGMA)
@@ -426,7 +482,6 @@ static cpp_hashnode *
lex_macro_node (pfile)
cpp_reader *pfile;
{
- cpp_hashnode *node;
const cpp_token *token = _cpp_lex_token (pfile);
/* The token immediately after #define must be an identifier. That
@@ -436,33 +491,27 @@ lex_macro_node (pfile)
Finally, the identifier may not have been poisoned. (In that case
the lexer has issued the error message for us.) */
- if (token->type != CPP_NAME)
+ if (token->type == CPP_NAME)
{
- if (token->type == CPP_EOF)
- cpp_error (pfile, "no macro name given in #%s directive",
- pfile->directive->name);
- else if (token->flags & NAMED_OP)
- cpp_error (pfile,
- "\"%s\" cannot be used as a macro name as it is an operator in C++",
- NODE_NAME (token->val.node));
- else
- cpp_error (pfile, "macro names must be identifiers");
-
- return 0;
- }
-
- node = token->val.node;
- if (node->flags & NODE_POISONED)
- return 0;
+ cpp_hashnode *node = token->val.node;
- if (node == pfile->spec_nodes.n_defined)
- {
- cpp_error (pfile, "\"%s\" cannot be used as a macro name",
- NODE_NAME (node));
- return 0;
+ if (node == pfile->spec_nodes.n_defined)
+ cpp_error (pfile, DL_ERROR,
+ "\"defined\" cannot be used as a macro name");
+ else if (! (node->flags & NODE_POISONED))
+ return node;
}
+ else if (token->flags & NAMED_OP)
+ cpp_error (pfile, DL_ERROR,
+ "\"%s\" cannot be used as a macro name as it is an operator in C++",
+ NODE_NAME (token->val.node));
+ else if (token->type == CPP_EOF)
+ cpp_error (pfile, DL_ERROR, "no macro name given in #%s directive",
+ pfile->directive->name);
+ else
+ cpp_error (pfile, DL_ERROR, "macro names must be identifiers");
- return node;
+ return NULL;
}
/* Process a #define directive. Most work is done in cppmacro.c. */
@@ -474,6 +523,11 @@ do_define (pfile)
if (node)
{
+ /* If we have been requested to expand comments into macros,
+ then re-enable saving of comments. */
+ pfile->state.save_comments =
+ ! CPP_OPTION (pfile, discard_comments_in_macro_exp);
+
if (_cpp_create_definition (pfile, node))
if (pfile->cb.define)
(*pfile->cb.define) (pfile, pfile->directive_line, node);
@@ -485,7 +539,7 @@ static void
do_undef (pfile)
cpp_reader *pfile;
{
- cpp_hashnode *node = lex_macro_node (pfile);
+ cpp_hashnode *node = lex_macro_node (pfile);
/* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified identifier
is not currently defined as a macro name. */
@@ -495,7 +549,10 @@ do_undef (pfile)
(*pfile->cb.undef) (pfile, pfile->directive_line, node);
if (node->flags & NODE_WARN)
- cpp_warning (pfile, "undefining \"%s\"", NODE_NAME (node));
+ cpp_error (pfile, DL_WARNING, "undefining \"%s\"", NODE_NAME (node));
+
+ if (CPP_OPTION (pfile, warn_unused_macros))
+ _cpp_warn_if_unused_macro (pfile, node, NULL);
_cpp_free_definition (node);
}
@@ -519,7 +576,7 @@ glue_header_name (pfile)
buffer = (unsigned char *) xmalloc (capacity);
for (;;)
{
- token = cpp_get_token (pfile);
+ token = get_token_no_padding (pfile);
if (token->type == CPP_GREATER || token->type == CPP_EOF)
break;
@@ -538,7 +595,7 @@ glue_header_name (pfile)
}
if (token->type == CPP_EOF)
- cpp_error (pfile, "missing terminating > character");
+ cpp_error (pfile, DL_ERROR, "missing terminating > character");
else
{
unsigned char *token_mem = _cpp_unaligned_alloc (pfile, total_len + 1);
@@ -571,12 +628,13 @@ parse_include (pfile)
dir = pfile->directive->name;
/* Allow macro expansion. */
- header = cpp_get_token (pfile);
+ header = get_token_no_padding (pfile);
if (header->type != CPP_STRING && header->type != CPP_HEADER_NAME)
{
if (header->type != CPP_LESS)
{
- cpp_error (pfile, "#%s expects \"FILENAME\" or <FILENAME>", dir);
+ cpp_error (pfile, DL_ERROR,
+ "#%s expects \"FILENAME\" or <FILENAME>", dir);
return NULL;
}
@@ -587,7 +645,7 @@ parse_include (pfile)
if (header->val.str.len == 0)
{
- cpp_error (pfile, "empty file name in #%s", dir);
+ cpp_error (pfile, DL_ERROR, "empty file name in #%s", dir);
return NULL;
}
@@ -606,13 +664,13 @@ do_include_common (pfile, type)
use the normal search logic. */
if (type == IT_INCLUDE_NEXT && ! pfile->buffer->prev)
{
- cpp_warning (pfile, "#include_next in primary source file");
+ cpp_error (pfile, DL_WARNING, "#include_next in primary source file");
type = IT_INCLUDE;
}
else if (type == IT_IMPORT && CPP_OPTION (pfile, warn_import))
{
CPP_OPTION (pfile, warn_import) = 0;
- cpp_warning (pfile,
+ cpp_error (pfile, DL_WARNING,
"#import is obsolete, use an #ifndef wrapper in the header file");
}
@@ -621,7 +679,7 @@ do_include_common (pfile, type)
{
/* Prevent #include recursion. */
if (pfile->line_maps.depth >= CPP_STACK_MAX)
- cpp_fatal (pfile, "#include nested too deeply");
+ cpp_error (pfile, DL_ERROR, "#include nested too deeply");
else
{
check_eol (pfile);
@@ -630,7 +688,6 @@ do_include_common (pfile, type)
if (pfile->cb.include)
(*pfile->cb.include) (pfile, pfile->directive_line,
pfile->directive->name, header);
-
_cpp_execute_include (pfile, header, type);
}
}
@@ -679,7 +736,7 @@ read_flag (pfile, last)
}
if (token->type != CPP_EOF)
- cpp_error (pfile, "invalid flag \"%s\" in line directive",
+ cpp_error (pfile, DL_ERROR, "invalid flag \"%s\" in line directive",
cpp_token_as_text (pfile, token));
return 0;
}
@@ -687,32 +744,24 @@ read_flag (pfile, last)
/* Subroutine of do_line and do_linemarker. Returns a version of STR
which has a NUL terminator and all escape sequences converted to
their equivalents. Temporary, hopefully. */
-static U_CHAR *
+static uchar *
dequote_string (pfile, str, len)
cpp_reader *pfile;
- const U_CHAR *str;
+ const uchar *str;
unsigned int len;
{
- U_CHAR *result = _cpp_unaligned_alloc (pfile, len + 1);
- U_CHAR *dst = result;
- const U_CHAR *limit = str + len;
- unsigned int c;
- unsigned HOST_WIDE_INT mask;
+ uchar *result = _cpp_unaligned_alloc (pfile, len + 1);
+ uchar *dst = result;
+ const uchar *limit = str + len;
+ cppchar_t c;
- /* We need the mask to match the host's 'unsigned char', not the
- target's. */
- if (CHAR_BIT < HOST_BITS_PER_WIDE_INT)
- mask = ((unsigned HOST_WIDE_INT) 1 << CHAR_BIT) - 1;
- else
- mask = ~(unsigned HOST_WIDE_INT)0;
-
while (str < limit)
{
c = *str++;
if (c != '\\')
*dst++ = c;
else
- *dst++ = cpp_parse_escape (pfile, (const U_CHAR **)&str, limit, mask, 0);
+ *dst++ = cpp_parse_escape (pfile, &str, limit, 0);
}
*dst++ = '\0';
return result;
@@ -723,12 +772,12 @@ dequote_string (pfile, str, len)
number was well-formed, 1 if not. Temporary, hopefully. */
static int
strtoul_for_line (str, len, nump)
- const U_CHAR *str;
+ const uchar *str;
unsigned int len;
unsigned long *nump;
{
unsigned long reg = 0;
- U_CHAR c;
+ uchar c;
while (len--)
{
c = *str++;
@@ -761,13 +810,14 @@ do_line (pfile)
|| strtoul_for_line (token->val.str.text, token->val.str.len,
&new_lineno))
{
- cpp_error (pfile, "\"%s\" after #line is not a positive integer",
+ cpp_error (pfile, DL_ERROR,
+ "\"%s\" after #line is not a positive integer",
cpp_token_as_text (pfile, token));
return;
- }
+ }
if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap))
- cpp_pedwarn (pfile, "line number out of range");
+ cpp_error (pfile, DL_PEDWARN, "line number out of range");
token = cpp_get_token (pfile);
if (token->type == CPP_STRING)
@@ -778,7 +828,7 @@ do_line (pfile)
}
else if (token->type != CPP_EOF)
{
- cpp_error (pfile, "\"%s\" is not a valid filename",
+ cpp_error (pfile, DL_ERROR, "\"%s\" is not a valid filename",
cpp_token_as_text (pfile, token));
return;
}
@@ -813,10 +863,10 @@ do_linemarker (pfile)
|| strtoul_for_line (token->val.str.text, token->val.str.len,
&new_lineno))
{
- cpp_error (pfile, "\"%s\" after # is not a positive integer",
+ cpp_error (pfile, DL_ERROR, "\"%s\" after # is not a positive integer",
cpp_token_as_text (pfile, token));
return;
- }
+ }
token = cpp_get_token (pfile);
if (token->type == CPP_STRING)
@@ -849,7 +899,7 @@ do_linemarker (pfile)
}
else if (token->type != CPP_EOF)
{
- cpp_error (pfile, "\"%s\" is not a valid filename",
+ cpp_error (pfile, DL_ERROR, "\"%s\" is not a valid filename",
cpp_token_as_text (pfile, token));
return;
}
@@ -882,10 +932,12 @@ _cpp_do_file_change (pfile, reason, to_file, file_line, sysp)
static void
do_diagnostic (pfile, code, print_dir)
cpp_reader *pfile;
- enum error_type code;
+ int code;
int print_dir;
{
- if (_cpp_begin_message (pfile, code, 0, 0))
+ if (_cpp_begin_message (pfile, code,
+ pfile->cur_token[-1].line,
+ pfile->cur_token[-1].col))
{
if (print_dir)
fprintf (stderr, "#%s ", pfile->directive->name);
@@ -899,7 +951,7 @@ static void
do_error (pfile)
cpp_reader *pfile;
{
- do_diagnostic (pfile, ERROR, 1);
+ do_diagnostic (pfile, DL_ERROR, 1);
}
static void
@@ -907,7 +959,7 @@ do_warning (pfile)
cpp_reader *pfile;
{
/* We want #warning diagnostics to be emitted in system headers too. */
- do_diagnostic (pfile, WARNING_SYSHDR, 1);
+ do_diagnostic (pfile, DL_WARNING_SYSHDR, 1);
}
/* Report program identification. */
@@ -918,7 +970,7 @@ do_ident (pfile)
const cpp_token *str = cpp_get_token (pfile);
if (str->type != CPP_STRING)
- cpp_error (pfile, "invalid #ident directive");
+ cpp_error (pfile, DL_ERROR, "invalid #ident directive");
else if (pfile->cb.ident)
(*pfile->cb.ident) (pfile, pfile->directive_line, &str->val.str);
@@ -1005,13 +1057,14 @@ cpp_register_pragma (pfile, space, name, handler)
{
if (entry->is_nspace)
clash:
- cpp_ice (pfile,
+ cpp_error (pfile, DL_ICE,
"registering \"%s\" as both a pragma and a pragma namespace",
NODE_NAME (node));
else if (space)
- cpp_ice (pfile, "#pragma %s %s is already registered", space, name);
+ cpp_error (pfile, DL_ICE, "#pragma %s %s is already registered",
+ space, name);
else
- cpp_ice (pfile, "#pragma %s is already registered", name);
+ cpp_error (pfile, DL_ICE, "#pragma %s is already registered", name);
}
else
insert_pragma_entry (pfile, chain, node, handler);
@@ -1023,7 +1076,6 @@ _cpp_init_internal_pragmas (pfile)
cpp_reader *pfile;
{
/* Pragmas in the global namespace. */
- cpp_register_pragma (pfile, 0, "poison", do_pragma_poison);
cpp_register_pragma (pfile, 0, "once", do_pragma_once);
/* New GCC-specific pragmas should be put in the GCC namespace. */
@@ -1086,18 +1138,18 @@ static void
do_pragma_once (pfile)
cpp_reader *pfile;
{
- cpp_warning (pfile, "#pragma once is obsolete");
-
+ cpp_error (pfile, DL_WARNING, "#pragma once is obsolete");
+
if (pfile->buffer->prev == NULL)
- cpp_warning (pfile, "#pragma once in main file");
+ cpp_error (pfile, DL_WARNING, "#pragma once in main file");
else
_cpp_never_reread (pfile->buffer->inc);
check_eol (pfile);
}
-/* Handle #pragma poison, to poison one or more identifiers so that
- the lexer produces a hard error for each subsequent usage. */
+/* Handle #pragma GCC poison, to poison one or more identifiers so
+ that the lexer produces a hard error for each subsequent usage. */
static void
do_pragma_poison (pfile)
cpp_reader *pfile;
@@ -1113,7 +1165,7 @@ do_pragma_poison (pfile)
break;
if (tok->type != CPP_NAME)
{
- cpp_error (pfile, "invalid #pragma GCC poison directive");
+ cpp_error (pfile, DL_ERROR, "invalid #pragma GCC poison directive");
break;
}
@@ -1122,7 +1174,8 @@ do_pragma_poison (pfile)
continue;
if (hp->type == NT_MACRO)
- cpp_warning (pfile, "poisoning existing macro \"%s\"", NODE_NAME (hp));
+ cpp_error (pfile, DL_WARNING, "poisoning existing macro \"%s\"",
+ NODE_NAME (hp));
_cpp_free_definition (hp);
hp->flags |= NODE_POISONED | NODE_DIAGNOSTIC;
}
@@ -1142,7 +1195,8 @@ do_pragma_system_header (pfile)
cpp_buffer *buffer = pfile->buffer;
if (buffer->prev == 0)
- cpp_warning (pfile, "#pragma system_header ignored outside include file");
+ cpp_error (pfile, DL_WARNING,
+ "#pragma system_header ignored outside include file");
else
{
check_eol (pfile);
@@ -1160,23 +1214,23 @@ do_pragma_dependency (pfile)
{
const cpp_token *header;
int ordering;
-
+
header = parse_include (pfile);
if (!header)
return;
ordering = _cpp_compare_file_date (pfile, header);
if (ordering < 0)
- cpp_warning (pfile, "cannot find source %s",
- cpp_token_as_text (pfile, header));
+ cpp_error (pfile, DL_WARNING, "cannot find source %s",
+ cpp_token_as_text (pfile, header));
else if (ordering > 0)
{
- cpp_warning (pfile, "current file is older than %s",
- cpp_token_as_text (pfile, header));
+ cpp_error (pfile, DL_WARNING, "current file is older than %s",
+ cpp_token_as_text (pfile, header));
if (cpp_get_token (pfile)->type != CPP_EOF)
{
_cpp_backup_tokens (pfile, 1);
- do_diagnostic (pfile, WARNING, 0);
+ do_diagnostic (pfile, DL_WARNING, 0);
}
}
}
@@ -1256,6 +1310,7 @@ destringize_and_run (pfile, in)
pfile->context = saved_context;
pfile->cur_token = saved_cur_token;
pfile->cur_run = saved_cur_run;
+ pfile->line--;
}
/* See above comment. For the moment, we'd like
@@ -1264,11 +1319,11 @@ destringize_and_run (pfile, in)
to be output as
- token1
- # 7 "file.c"
- #pragma foo
- # 7 "file.c"
- token2
+ token1
+ # 7 "file.c"
+ #pragma foo
+ # 7 "file.c"
+ token2
Getting the line markers is a little tricky. */
if (pfile->cb.line_change)
@@ -1285,17 +1340,16 @@ _cpp_do__Pragma (pfile)
if (string)
destringize_and_run (pfile, &string->val.str);
else
- cpp_error (pfile, "_Pragma takes a parenthesized string literal");
+ cpp_error (pfile, DL_ERROR,
+ "_Pragma takes a parenthesized string literal");
}
-/* Just ignore #sccs, on systems where we define it at all. */
-#ifdef SCCS_DIRECTIVE
+/* Just ignore #sccs on all systems. */
static void
do_sccs (pfile)
cpp_reader *pfile ATTRIBUTE_UNUSED;
{
}
-#endif
/* Handle #ifdef. */
static void
@@ -1309,10 +1363,11 @@ do_ifdef (pfile)
const cpp_hashnode *node = lex_macro_node (pfile);
if (node)
- skip = node->type != NT_MACRO;
-
- if (node)
- check_eol (pfile);
+ {
+ skip = node->type != NT_MACRO;
+ _cpp_mark_macro_used (node);
+ check_eol (pfile);
+ }
}
push_conditional (pfile, skip, T_IFDEF, 0);
@@ -1329,11 +1384,13 @@ do_ifndef (pfile)
if (! pfile->state.skipping)
{
node = lex_macro_node (pfile);
- if (node)
- skip = node->type == NT_MACRO;
if (node)
- check_eol (pfile);
+ {
+ skip = node->type == NT_MACRO;
+ _cpp_mark_macro_used (node);
+ check_eol (pfile);
+ }
}
push_conditional (pfile, skip, T_IFNDEF, node);
@@ -1351,7 +1408,7 @@ do_if (pfile)
int skip = 1;
if (! pfile->state.skipping)
- skip = _cpp_parse_expr (pfile) == 0;
+ skip = _cpp_parse_expr (pfile) == false;
push_conditional (pfile, skip, T_IF, pfile->mi_ind_cmacro);
}
@@ -1367,13 +1424,13 @@ do_else (pfile)
struct if_stack *ifs = buffer->if_stack;
if (ifs == NULL)
- cpp_error (pfile, "#else without #if");
+ cpp_error (pfile, DL_ERROR, "#else without #if");
else
{
if (ifs->type == T_ELSE)
{
- cpp_error (pfile, "#else after #else");
- cpp_error_with_line (pfile, ifs->line, 0,
+ cpp_error (pfile, DL_ERROR, "#else after #else");
+ cpp_error_with_line (pfile, DL_ERROR, ifs->line, 0,
"the conditional began here");
}
ifs->type = T_ELSE;
@@ -1386,7 +1443,7 @@ do_else (pfile)
ifs->mi_cmacro = 0;
/* Only check EOL if was not originally skipping. */
- if (!ifs->was_skipping)
+ if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels))
check_eol (pfile);
}
}
@@ -1401,13 +1458,13 @@ do_elif (pfile)
struct if_stack *ifs = buffer->if_stack;
if (ifs == NULL)
- cpp_error (pfile, "#elif without #if");
+ cpp_error (pfile, DL_ERROR, "#elif without #if");
else
{
if (ifs->type == T_ELSE)
{
- cpp_error (pfile, "#elif after #else");
- cpp_error_with_line (pfile, ifs->line, 0,
+ cpp_error (pfile, DL_ERROR, "#elif after #else");
+ cpp_error_with_line (pfile, DL_ERROR, ifs->line, 0,
"the conditional began here");
}
ifs->type = T_ELIF;
@@ -1437,11 +1494,11 @@ do_endif (pfile)
struct if_stack *ifs = buffer->if_stack;
if (ifs == NULL)
- cpp_error (pfile, "#endif without #if");
+ cpp_error (pfile, DL_ERROR, "#endif without #if");
else
{
/* Only check EOL if was not originally skipping. */
- if (!ifs->was_skipping)
+ if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels))
check_eol (pfile);
/* If potential control macro, we go back outside again. */
@@ -1520,7 +1577,7 @@ parse_answer (pfile, answerp, type)
if (type == T_UNASSERT && paren->type == CPP_EOF)
return 0;
- cpp_error (pfile, "missing '(' after predicate");
+ cpp_error (pfile, DL_ERROR, "missing '(' after predicate");
return 1;
}
@@ -1535,7 +1592,7 @@ parse_answer (pfile, answerp, type)
if (token->type == CPP_EOF)
{
- cpp_error (pfile, "missing ')' to complete answer");
+ cpp_error (pfile, DL_ERROR, "missing ')' to complete answer");
return 1;
}
@@ -1555,7 +1612,7 @@ parse_answer (pfile, answerp, type)
if (acount == 0)
{
- cpp_error (pfile, "predicate's answer is empty");
+ cpp_error (pfile, DL_ERROR, "predicate's answer is empty");
return 1;
}
@@ -1585,9 +1642,9 @@ parse_assertion (pfile, answerp, type)
*answerp = 0;
predicate = cpp_get_token (pfile);
if (predicate->type == CPP_EOF)
- cpp_error (pfile, "assertion without predicate");
+ cpp_error (pfile, DL_ERROR, "assertion without predicate");
else if (predicate->type != CPP_NAME)
- cpp_error (pfile, "predicate must be an identifier");
+ cpp_error (pfile, DL_ERROR, "predicate must be an identifier");
else if (parse_answer (pfile, answerp, type) == 0)
{
unsigned int len = NODE_LEN (predicate->val.node);
@@ -1632,20 +1689,27 @@ find_answer (node, candidate)
}
/* Test an assertion within a preprocessor conditional. Returns
- non-zero on failure, zero on success. On success, the result of
- the test is written into VALUE. */
+ nonzero on failure, zero on success. On success, the result of
+ the test is written into VALUE, otherwise the value 0. */
int
_cpp_test_assertion (pfile, value)
cpp_reader *pfile;
- int *value;
+ unsigned int *value;
{
struct answer *answer;
cpp_hashnode *node;
node = parse_assertion (pfile, &answer, T_IF);
+
+ /* For recovery, an erroneous assertion expression is handled as a
+ failing assertion. */
+ *value = 0;
+
if (node)
*value = (node->type == NT_ASSERTION &&
(answer == 0 || *find_answer (node, answer) != 0));
+ else if (pfile->cur_token[-1].type == CPP_EOF)
+ _cpp_backup_tokens (pfile, 1);
/* We don't commit the memory for the answer - it's temporary only. */
return node == 0;
@@ -1658,7 +1722,7 @@ do_assert (pfile)
{
struct answer *new_answer;
cpp_hashnode *node;
-
+
node = parse_assertion (pfile, &new_answer, T_ASSERT);
if (node)
{
@@ -1669,7 +1733,8 @@ do_assert (pfile)
{
if (*find_answer (node, new_answer))
{
- cpp_warning (pfile, "\"%s\" re-asserted", NODE_NAME (node) + 1);
+ cpp_error (pfile, DL_WARNING, "\"%s\" re-asserted",
+ NODE_NAME (node) + 1);
return;
}
new_answer->next = node->value.answers;
@@ -1691,7 +1756,7 @@ do_unassert (pfile)
{
cpp_hashnode *node;
struct answer *answer;
-
+
node = parse_assertion (pfile, &answer, T_UNASSERT);
/* It isn't an error to #unassert something that isn't asserted. */
if (node && node->type == NT_ASSERTION)
@@ -1732,7 +1797,7 @@ cpp_define (pfile, str)
char *buf, *p;
size_t count;
- /* Copy the entire option so we can modify it.
+ /* Copy the entire option so we can modify it.
Change the first "=" in the string to a space. If there is none,
tack " 1" on the end. */
@@ -1787,7 +1852,7 @@ cpp_unassert (pfile, str)
const char *str;
{
handle_assertion (pfile, str, T_UNASSERT);
-}
+}
/* Common code for cpp_assert (-A) and cpp_unassert (-A-). */
static void
@@ -1862,7 +1927,7 @@ cpp_set_callbacks (pfile, cb)
cpp_buffer *
cpp_push_buffer (pfile, buffer, len, from_stage3, return_at_eof)
cpp_reader *pfile;
- const U_CHAR *buffer;
+ const uchar *buffer;
size_t len;
int from_stage3;
int return_at_eof;
@@ -1874,7 +1939,7 @@ cpp_push_buffer (pfile, buffer, len, from_stage3, return_at_eof)
new->line_base = new->buf = new->cur = buffer;
new->rlimit = buffer + len;
- new->from_stage3 = from_stage3;
+ new->from_stage3 = from_stage3 || CPP_OPTION (pfile, traditional);
new->prev = pfile->buffer;
new->return_at_eof = return_at_eof;
new->saved_flags = BOL;
@@ -1884,37 +1949,50 @@ cpp_push_buffer (pfile, buffer, len, from_stage3, return_at_eof)
return new;
}
-/* If called from do_line, pops a single buffer. Otherwise pops all
- buffers until a real file is reached. Generates appropriate
- call-backs. */
+/* Pops a single buffer, with a file change call-back if appropriate.
+ Then pushes the next -include file, if any remain. */
void
_cpp_pop_buffer (pfile)
cpp_reader *pfile;
{
cpp_buffer *buffer = pfile->buffer;
+ struct include_file *inc = buffer->inc;
struct if_stack *ifs;
- bool pushed = false;
/* Walk back up the conditional stack till we reach its level at
entry to this file, issuing error messages. */
for (ifs = buffer->if_stack; ifs; ifs = ifs->next)
- cpp_error_with_line (pfile, ifs->line, 0,
+ cpp_error_with_line (pfile, DL_ERROR, ifs->line, 0,
"unterminated #%s", dtable[ifs->type].name);
/* In case of a missing #endif. */
pfile->state.skipping = 0;
- /* Update the reader's buffer before _cpp_do_file_change. */
+ /* _cpp_do_file_change expects pfile->buffer to be the new one. */
pfile->buffer = buffer->prev;
- if (buffer->inc)
- pushed = _cpp_pop_file_buffer (pfile, buffer->inc);
+ /* Free the buffer object now; we may want to push a new buffer
+ in _cpp_push_next_include_file. */
+ obstack_free (&pfile->buffer_ob, buffer);
+
+ if (inc)
+ {
+ _cpp_pop_file_buffer (pfile, inc);
+
+ /* Don't generate a callback for popping the main file. */
+ if (pfile->buffer)
+ {
+ _cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0);
- if (!pushed)
- obstack_free (&pfile->buffer_ob, buffer);
+ /* If this is the main file, there may be some -include
+ files left to push. */
+ if (!pfile->buffer->prev)
+ _cpp_maybe_push_include_file (pfile);
+ }
+ }
}
-/* Enter all recognised directives in the hash table. */
+/* Enter all recognized directives in the hash table. */
void
_cpp_init_directives (pfile)
cpp_reader *pfile;
OpenPOWER on IntegriCloud