aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/cppexp.c5
-rw-r--r--gcc/cpphash.h1
-rw-r--r--gcc/cpplex.c7
-rw-r--r--gcc/cpplib.c162
-rw-r--r--gcc/cpplib.h3
-rw-r--r--gcc/cppmacro.c40
7 files changed, 118 insertions, 122 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c4060f3..b255253 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,25 @@
+2000-11-12 Neil Booth <neilb@earthling.net>
+
+ * 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 <mark@codesourcery.com>
* fixinc/inclhack.def (sunos_matherr_decl): Bypass matherr
diff --git a/gcc/cppexp.c b/gcc/cppexp.c
index 4814868..82f8aab 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 a1c859d..ebccda6 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 5c7edcd..75d094d 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 d70e6ec..159c3db8 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");
- }
-
- /* 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");
+ }
+ ifs->type = T_ELIF;
- ifs->type = T_ELIF;
- if (ifs->was_skipping)
- return; /* Don't evaluate a nested #if */
+ /* 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;
- if (pfile->skipping != 1)
- {
- pfile->skipping = 2; /* one block succeeded, so don't do any others */
- return;
+ /* Invalidate any controlling macro. */
+ ifs->mi_cmacro = 0;
+ }
}
-
- 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 d677396..8b6560d 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 43a9010..7ea70850 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;
}