diff options
author | kan <kan@FreeBSD.org> | 2003-07-11 03:40:53 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2003-07-11 03:40:53 +0000 |
commit | b2a8872fbe1ec1c49094559ac7b78e6ea4ab7180 (patch) | |
tree | f6b0610f4a17fd26aa234354f050080f789861a4 /contrib/gcc/cpplib.c | |
parent | 52e69d78eee5612ac195e0701a5cebe40d1ab0e1 (diff) | |
download | FreeBSD-src-b2a8872fbe1ec1c49094559ac7b78e6ea4ab7180.zip FreeBSD-src-b2a8872fbe1ec1c49094559ac7b78e6ea4ab7180.tar.gz |
Gcc 3.3.1-pre as of 2003-07-11.
Diffstat (limited to 'contrib/gcc/cpplib.c')
-rw-r--r-- | contrib/gcc/cpplib.c | 432 |
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; |