From b528a07e0e5693ec33b7e77c600c0b32117f7742 Mon Sep 17 00:00:00 2001 From: Neil Booth Date: Sun, 12 Nov 2000 11:46:21 +0000 Subject: [PATCH] cppexp.c: Don't worry about pfile->skipping. * cppexp.c: Don't worry about pfile->skipping. * cpplib.c (struct if_stack): Make was_skipping unsigned char. (cpp_handle_directive): Save pfile->skipping in struct cpp_buffer for handled directives. (skip_rest_of_line): Use _cpp_lex_token after popping contexts and releasing lookaheads. (do_ifdef, do_ifndef, do_if): Use buffer->was_skipping. (do_else, do_elif, push_conditional): Update logic. (do_endif): Set buffer->was_skipping rather than pfile->skipping. (unwind_if_stack): Inline into cpp_pop_buffer. (cpp_push_buffer): Clear ifs->was_skipping for cpp_handle_directive. * cpplex.c (_cpp_lex_token): Clear skipping on EOF. Handle multiple-include optimisation. * cpplib.h (struct cpp_buffer): New member was_skipping. * cppmacro.c (_cpp_get_token): Loop whilst pfile->skipping. This works because skipping == 0 in directives. (_cpp_release_lookahead): Renamed from release_lookahead. (cpp_get_token): No need to check skipping as _cpp_get_token does this for us. No need to handle MI optimisation. From-SVN: r37404 --- gcc/ChangeLog | 22 +++++++ gcc/cppexp.c | 5 -- gcc/cpphash.h | 1 + gcc/cpplex.c | 7 +++ gcc/cpplib.c | 166 +++++++++++++++++++++++-------------------------- gcc/cpplib.h | 3 + gcc/cppmacro.c | 40 +++--------- 7 files changed, 120 insertions(+), 124 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c4060f3bd97..b255253a79d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2000-11-12 Neil Booth + + * cppexp.c: Don't worry about pfile->skipping. + * cpplib.c (struct if_stack): Make was_skipping unsigned char. + (cpp_handle_directive): Save pfile->skipping in struct cpp_buffer + for handled directives. + (skip_rest_of_line): Use _cpp_lex_token after popping contexts + and releasing lookaheads. + (do_ifdef, do_ifndef, do_if): Use buffer->was_skipping. + (do_else, do_elif, push_conditional): Update logic. + (do_endif): Set buffer->was_skipping rather than pfile->skipping. + (unwind_if_stack): Inline into cpp_pop_buffer. + (cpp_push_buffer): Clear ifs->was_skipping for cpp_handle_directive. + * cpplex.c (_cpp_lex_token): Clear skipping on EOF. Handle + multiple-include optimisation. + * cpplib.h (struct cpp_buffer): New member was_skipping. + * cppmacro.c (_cpp_get_token): Loop whilst pfile->skipping. This + works because skipping == 0 in directives. + (_cpp_release_lookahead): Renamed from release_lookahead. + (cpp_get_token): No need to check skipping as _cpp_get_token does + this for us. No need to handle MI optimisation. + Sat Nov 11 21:14:02 2000 Mark P Mitchell * fixinc/inclhack.def (sunos_matherr_decl): Bypass matherr diff --git a/gcc/cppexp.c b/gcc/cppexp.c index 4814868e2da..82f8aab580f 100644 --- a/gcc/cppexp.c +++ b/gcc/cppexp.c @@ -752,10 +752,6 @@ _cpp_parse_expr (pfile) int skip_evaluation = 0; int result; - /* Save parser state and set it to something sane. */ - int save_skipping = pfile->skipping; - pfile->skipping = 0; - /* Set up detection of #if ! defined(). */ pfile->mi_lexed = 0; pfile->mi_if_not_defined = MI_IND_NONE; @@ -1039,7 +1035,6 @@ _cpp_parse_expr (pfile) /* Free dynamic stack if we allocated one. */ if (stack != init_stack) free (stack); - pfile->skipping = save_skipping; return result; } diff --git a/gcc/cpphash.h b/gcc/cpphash.h index a1c859de66a..ebccda6080c 100644 --- a/gcc/cpphash.h +++ b/gcc/cpphash.h @@ -160,6 +160,7 @@ extern int _cpp_create_definition PARAMS ((cpp_reader *, cpp_hashnode *)); extern void _cpp_pop_context PARAMS ((cpp_reader *)); extern void _cpp_get_token PARAMS ((cpp_reader *, cpp_token *)); extern void _cpp_free_lookaheads PARAMS ((cpp_reader *)); +extern void _cpp_release_lookahead PARAMS ((cpp_reader *)); extern void _cpp_push_token PARAMS ((cpp_reader *, const cpp_token *, const cpp_lexer_pos *)); diff --git a/gcc/cpplex.c b/gcc/cpplex.c index 5c7edcd40fe..75d094d21c0 100644 --- a/gcc/cpplex.c +++ b/gcc/cpplex.c @@ -874,6 +874,7 @@ _cpp_lex_token (pfile, result) if (pfile->lexer_pos.col != 0 && !buffer->from_stage3) cpp_pedwarn (pfile, "no newline at end of file"); pfile->state.next_bol = 1; + pfile->skipping = 0; /* In case missing #endif. */ result->type = CPP_EOF; break; @@ -1270,6 +1271,12 @@ _cpp_lex_token (pfile, result) result->val.c = c; break; } + + /* Non-comment tokens invalidate any controlling macros. */ + if (result->type != CPP_COMMENT + && result->type != CPP_EOF + && !pfile->state.in_directive) + pfile->mi_state = MI_FAILED; } /* An upper bound on the number of bytes needed to spell a token, diff --git a/gcc/cpplib.c b/gcc/cpplib.c index d70e6ec2b3f..159c3db85f5 100644 --- a/gcc/cpplib.c +++ b/gcc/cpplib.c @@ -44,7 +44,7 @@ struct if_stack struct if_stack *next; cpp_lexer_pos pos; /* line and column where condition started */ const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */ - int was_skipping; /* value of pfile->skipping before this if */ + unsigned char was_skipping; /* Value of pfile->skipping before this if. */ int type; /* type of last directive seen in this group */ }; @@ -92,9 +92,7 @@ static int read_line_number PARAMS ((cpp_reader *, int *)); static int strtoul_for_line PARAMS ((const U_CHAR *, unsigned int, unsigned long *)); static void do_diagnostic PARAMS ((cpp_reader *, enum error_type)); -static cpp_hashnode * - lex_macro_node PARAMS ((cpp_reader *)); -static void unwind_if_stack PARAMS ((cpp_reader *, cpp_buffer *)); +static cpp_hashnode *lex_macro_node PARAMS ((cpp_reader *)); static void do_pragma_once PARAMS ((cpp_reader *)); static void do_pragma_poison PARAMS ((cpp_reader *)); static void do_pragma_system_header PARAMS ((cpp_reader *)); @@ -185,17 +183,18 @@ skip_rest_of_line (pfile) { cpp_token token; + /* Discard all lookaheads. */ + while (pfile->la_read) + _cpp_release_lookahead (pfile); + /* Discard all stacked contexts. */ while (pfile->context != &pfile->base_context) _cpp_pop_context (pfile); - /* Sweep up all tokens remaining on the line. We need to read - tokens from lookahead, but cannot just drop the lookahead buffers - because they may be saving tokens prior to this directive for an - external client. So we use _cpp_get_token, with macros disabled. */ + /* Sweep up all tokens remaining on the line. */ pfile->state.prevent_expansion++; while (!pfile->state.next_bol) - _cpp_get_token (pfile, &token); + _cpp_lex_token (pfile, &token); pfile->state.prevent_expansion--; } @@ -222,6 +221,7 @@ _cpp_handle_directive (pfile, indented) cpp_reader *pfile; int indented; { + cpp_buffer *buffer = pfile->buffer; const directive *dir = 0; cpp_token dname; int not_asm = 1; @@ -250,11 +250,11 @@ _cpp_handle_directive (pfile, indented) skipped conditional groups. Complain about this form if we're being pedantic, but not if this is regurgitated input (preprocessed or fed back in by the C++ frontend). */ - if (!pfile->skipping && !CPP_OPTION (pfile, lang_asm)) + if (! pfile->skipping && !CPP_OPTION (pfile, lang_asm)) { dir = &dtable[T_LINE]; _cpp_push_token (pfile, &dname, &pfile->directive_pos); - if (CPP_PEDANTIC (pfile) && CPP_BUFFER (pfile)->inc + if (CPP_PEDANTIC (pfile) && buffer->inc && ! CPP_OPTION (pfile, preprocessed)) cpp_pedwarn (pfile, "# followed by integer"); } @@ -290,7 +290,7 @@ _cpp_handle_directive (pfile, indented) /* If we are skipping a failed conditional group, all non-conditional directives are ignored. */ - if (!pfile->skipping || (dir->flags & COND)) + if (! pfile->skipping || (dir->flags & COND)) { /* Issue -pedantic warnings for extensions. */ if (CPP_PEDANTIC (pfile) && dir->origin == EXTENSION) @@ -301,7 +301,10 @@ _cpp_handle_directive (pfile, indented) if (! (dir->flags & IF_COND)) pfile->mi_state = MI_FAILED; + buffer->was_skipping = pfile->skipping; + pfile->skipping = 0; (*dir->handler) (pfile); + pfile->skipping = buffer->was_skipping; } } } @@ -311,7 +314,7 @@ _cpp_handle_directive (pfile, indented) if (indented && CPP_WTRADITIONAL (pfile)) cpp_warning (pfile, "traditional C ignores #\\n with the # indented"); } - else + else if (!pfile->skipping) { /* An unknown directive. Don't complain about it in assembly source: we don't know where the comments are, and # may @@ -323,7 +326,7 @@ _cpp_handle_directive (pfile, indented) not_asm = 0; _cpp_push_token (pfile, &dname, &pfile->directive_pos); } - else if (!pfile->skipping) + else cpp_error (pfile, "invalid preprocessing directive #%s", cpp_token_as_text (pfile, &dname)); } @@ -1164,7 +1167,7 @@ do_ifdef (pfile) { int skip = 1; - if (! pfile->skipping) + if (! pfile->buffer->was_skipping) { const cpp_hashnode *node = lex_macro_node (pfile); @@ -1182,7 +1185,7 @@ do_ifndef (pfile) int skip = 1; const cpp_hashnode *node = 0; - if (! pfile->skipping) + if (! pfile->buffer->was_skipping) { node = lex_macro_node (pfile); if (node) @@ -1204,7 +1207,7 @@ do_if (pfile) int skip = 1; const cpp_hashnode *cmacro = 0; - if (!pfile->skipping) + if (! pfile->buffer->was_skipping) { /* Controlling macro of #if ! defined () */ pfile->mi_ind_cmacro = 0; @@ -1215,7 +1218,7 @@ do_if (pfile) push_conditional (pfile, skip, T_IF, cmacro); } -/* #else flips pfile->skipping and continues without changing +/* Flip skipping state if appropriate and continue without changing if_stack; this is so that the error message for missing #endif's etc. will point to the original #if. */ @@ -1223,7 +1226,8 @@ static void do_else (pfile) cpp_reader *pfile; { - struct if_stack *ifs = CPP_BUFFER (pfile)->if_stack; + cpp_buffer *buffer = pfile->buffer; + struct if_stack *ifs = buffer->if_stack; if (ifs == NULL) cpp_error (pfile, "#else without #if"); @@ -1235,18 +1239,15 @@ do_else (pfile) cpp_error_with_line (pfile, ifs->pos.line, ifs->pos.col, "the conditional began here"); } + ifs->type = T_ELSE; + + /* Buffer->was_skipping is 1 if all conditionals in this chain + have been false, 2 if a conditional has been true. */ + if (! ifs->was_skipping && buffer->was_skipping != 2) + buffer->was_skipping = ! buffer->was_skipping; /* Invalidate any controlling macro. */ ifs->mi_cmacro = 0; - - ifs->type = T_ELSE; - if (! ifs->was_skipping) - { - /* If pfile->skipping is 2, one of the blocks in an #if - #elif ... chain succeeded, so we skip the else block. */ - if (pfile->skipping < 2) - pfile->skipping = ! pfile->skipping; - } } check_eol (pfile); @@ -1259,35 +1260,35 @@ static void do_elif (pfile) cpp_reader *pfile; { - struct if_stack *ifs = CPP_BUFFER (pfile)->if_stack; + cpp_buffer *buffer = pfile->buffer; + struct if_stack *ifs = buffer->if_stack; if (ifs == NULL) + cpp_error (pfile, "#elif without #if"); + else { - cpp_error (pfile, "#elif without #if"); - return; + if (ifs->type == T_ELSE) + { + cpp_error (pfile, "#elif after #else"); + cpp_error_with_line (pfile, ifs->pos.line, ifs->pos.col, + "the conditional began here"); + } + ifs->type = T_ELIF; + + /* Don't evaluate #elif if our higher level is skipping. */ + if (! ifs->was_skipping) + { + /* Buffer->was_skipping is 1 if all conditionals in this + chain have been false, 2 if a conditional has been true. */ + if (buffer->was_skipping == 1) + buffer->was_skipping = ! _cpp_parse_expr (pfile); + else + buffer->was_skipping = 2; + + /* Invalidate any controlling macro. */ + ifs->mi_cmacro = 0; + } } - - if (ifs->type == T_ELSE) - { - cpp_error (pfile, "#elif after #else"); - cpp_error_with_line (pfile, ifs->pos.line, ifs->pos.col, - "the conditional began here"); - } - - /* Invalidate any controlling macro. */ - ifs->mi_cmacro = 0; - - ifs->type = T_ELIF; - if (ifs->was_skipping) - return; /* Don't evaluate a nested #if */ - - if (pfile->skipping != 1) - { - pfile->skipping = 2; /* one block succeeded, so don't do any others */ - return; - } - - pfile->skipping = ! _cpp_parse_expr (pfile); } /* #endif pops the if stack and resets pfile->skipping. */ @@ -1296,7 +1297,8 @@ static void do_endif (pfile) cpp_reader *pfile; { - struct if_stack *ifs = CPP_BUFFER (pfile)->if_stack; + cpp_buffer *buffer = pfile->buffer; + struct if_stack *ifs = buffer->if_stack; if (ifs == NULL) cpp_error (pfile, "#endif without #if"); @@ -1309,8 +1311,8 @@ do_endif (pfile) pfile->mi_cmacro = ifs->mi_cmacro; } - CPP_BUFFER (pfile)->if_stack = ifs->next; - pfile->skipping = ifs->was_skipping; + buffer->if_stack = ifs->next; + buffer->was_skipping = ifs->was_skipping; obstack_free (pfile->buffer_ob, ifs); } @@ -1329,39 +1331,20 @@ push_conditional (pfile, skip, type, cmacro) const cpp_hashnode *cmacro; { struct if_stack *ifs; + cpp_buffer *buffer = pfile->buffer; ifs = xobnew (pfile->buffer_ob, struct if_stack); ifs->pos = pfile->directive_pos; - ifs->next = CPP_BUFFER (pfile)->if_stack; - ifs->was_skipping = pfile->skipping; + ifs->next = buffer->if_stack; + ifs->was_skipping = buffer->was_skipping; ifs->type = type; if (pfile->mi_state == MI_OUTSIDE && pfile->mi_cmacro == 0) ifs->mi_cmacro = cmacro; else ifs->mi_cmacro = 0; - if (!pfile->skipping) - pfile->skipping = skip; - - CPP_BUFFER (pfile)->if_stack = ifs; -} - -/* Called when we reach the end of a file. Walk back up the - conditional stack till we reach its level at entry to this file, - issuing error messages. Then force skipping off. */ -static void -unwind_if_stack (pfile, pbuf) - cpp_reader *pfile; - cpp_buffer *pbuf; -{ - struct if_stack *ifs; - - /* No need to free stack - they'll all go away with the buffer. */ - for (ifs = pbuf->if_stack; ifs; ifs = ifs->next) - cpp_error_with_line (pfile, ifs->pos.line, ifs->pos.col, - "unterminated #%s", dtable[ifs->type].name); - - pfile->skipping = 0; + buffer->was_skipping = skip; + buffer->if_stack = ifs; } /* Read the tokens of the answer into the macro pool. Only commit the @@ -1723,6 +1706,7 @@ cpp_push_buffer (pfile, buffer, length) new->rlimit = buffer + length; new->prev = buf; new->pfile = pfile; + new->was_skipping = 0; /* Preprocessed files don't do trigraph and escaped newline processing. */ new->from_stage3 = CPP_OPTION (pfile, preprocessed); /* No read ahead or extra char initially. */ @@ -1738,22 +1722,28 @@ cpp_buffer * cpp_pop_buffer (pfile) cpp_reader *pfile; { + cpp_buffer *buffer = pfile->buffer; + struct if_stack *ifs = buffer->if_stack; int wfb; - cpp_buffer *buf = CPP_BUFFER (pfile); - unwind_if_stack (pfile, buf); - wfb = (buf->inc != 0); + /* 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->pos.line, ifs->pos.col, + "unterminated #%s", dtable[ifs->type].name); + + wfb = (buffer->inc != 0); if (wfb) - _cpp_pop_file_buffer (pfile, buf); + _cpp_pop_file_buffer (pfile, buffer); - CPP_BUFFER (pfile) = CPP_PREV_BUFFER (buf); - obstack_free (pfile->buffer_ob, buf); + pfile->buffer = buffer->prev; + obstack_free (pfile->buffer_ob, buffer); pfile->buffer_stack_depth--; - if (CPP_BUFFER (pfile) && wfb && pfile->cb.leave_file) + if (pfile->buffer && wfb && pfile->cb.leave_file) (*pfile->cb.leave_file) (pfile); - return CPP_BUFFER (pfile); + return pfile->buffer; } #define obstack_chunk_alloc xmalloc diff --git a/gcc/cpplib.h b/gcc/cpplib.h index d677396e43f..8b6560dc500 100644 --- a/gcc/cpplib.h +++ b/gcc/cpplib.h @@ -290,6 +290,9 @@ struct cpp_buffer for preprocessed input, command line directives, and _Pragma buffers. */ unsigned char from_stage3; + + /* Temporary storage for pfile->skipping whilst in a directive. */ + unsigned char was_skipping; }; /* Maximum nesting of cpp_buffers. We use a static limit, partly for diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c index 43a9010f141..7ea7085019f 100644 --- a/gcc/cppmacro.c +++ b/gcc/cppmacro.c @@ -86,7 +86,6 @@ static void replace_args PARAMS ((cpp_reader *, cpp_macro *, macro_arg *, static void save_lookahead_token PARAMS ((cpp_reader *, const cpp_token *)); static void take_lookahead_token PARAMS ((cpp_reader *, cpp_token *)); -static void release_lookahead PARAMS ((cpp_reader *)); static cpp_lookahead *alloc_lookahead PARAMS ((cpp_reader *)); static void free_lookahead PARAMS ((cpp_lookahead *)); @@ -897,7 +896,7 @@ _cpp_get_token (pfile, token) cpp_token *token; { next_token: - for (;;) + do { cpp_context *context = pfile->context; @@ -913,22 +912,15 @@ _cpp_get_token (pfile, token) if (context->macro) { _cpp_pop_context (pfile); - continue; + goto next_token; } /* End of argument pre-expansion. */ token->type = CPP_EOF; token->flags = 0; + return; } - break; } - - /* Only perform macro expansion (and therefore pasting) when not - skipping, or when skipping but in a directive. The only - directive where this could be true is #elif. A possible later - optimisation: get do_elif to clear skipping so we don't need the - directive test here. */ - if (pfile->skipping && !pfile->state.in_directive) - return; + while (pfile->skipping); for (;;) { @@ -985,21 +977,7 @@ cpp_get_token (pfile, token) cpp_reader *pfile; cpp_token *token; { - for (;;) - { - _cpp_get_token (pfile, token); - - if (token->type == CPP_EOF) - break; - else if (pfile->skipping) - continue; - - /* Non-comment tokens invalidate any controlling macros. */ - if (token->type != CPP_COMMENT) - pfile->mi_state = MI_FAILED; - - break; - } + _cpp_get_token (pfile, token); if (pfile->la_write) save_lookahead_token (pfile, token); @@ -1057,12 +1035,12 @@ take_lookahead_token (pfile, token) pfile->lexer_pos = twp->pos; if (++la->cur == la->count) - release_lookahead (pfile); + _cpp_release_lookahead (pfile); } /* Moves the lookahead at the front of the read list to the free store. */ -static void -release_lookahead (pfile) +void +_cpp_release_lookahead (pfile) cpp_reader *pfile; { cpp_lookahead *la = pfile->la_read; @@ -1151,7 +1129,7 @@ cpp_stop_lookahead (pfile, drop) pfile->la_read = la; if (drop || la->count == 0) - release_lookahead (pfile); + _cpp_release_lookahead (pfile); else pfile->lexer_pos = la->pos; }