cppexp.c (parse_defined): Always record the macro name.

* cppexp.c (parse_defined): Always record the macro name.
	(lex): Don't worry about identifiers, or special-case
	CPP_NOT here.
	(_cpp_parse_expr): Figure out at the end of the routine
	whether we saw a valid !defined() expression.
	* cppfiles.c (stack_include_file): Update for mi_valid.
	(_cpp_pop_file_buffer): Similarly.
	* cpplex.c (_cpp_lex_token): Similarly.
	* cpphash.h (enum mi_state, enum mi_ind, mi_state,
	mi_if_not_defined, mi_lexed): Remove.
	(mi_valid): New.
	* cpplib.c (do_if): Simplify.
	(do_endif, push_conditional, _cpp_handle_directive): Update
	for renaming of mi_state to mi_valid.

	* cpp.texi: Add index entries for digraphs, and add comment
	that C++ refers to them as alternative tokens.

From-SVN: r44459
This commit is contained in:
Neil Booth 2001-07-29 17:27:57 +00:00 committed by Neil Booth
parent 0068fd9637
commit 6d18adbc2c
8 changed files with 68 additions and 57 deletions

View File

@ -1,3 +1,23 @@
2001-07-29 Neil Booth <neil@cat.daikokuya.demon.co.uk>
* cppexp.c (parse_defined): Always record the macro name.
(lex): Don't worry about identifiers, or special-case
CPP_NOT here.
(_cpp_parse_expr): Figure out at the end of the routine
whether we saw a valid !defined() expression.
* cppfiles.c (stack_include_file): Update for mi_valid.
(_cpp_pop_file_buffer): Similarly.
* cpplex.c (_cpp_lex_token): Similarly.
* cpphash.h (enum mi_state, enum mi_ind, mi_state,
mi_if_not_defined, mi_lexed): Remove.
(mi_valid): New.
* cpplib.c (do_if): Simplify.
(do_endif, push_conditional, _cpp_handle_directive): Update
for renaming of mi_state to mi_valid.
doc:
* cpp.texi: Add index entries for digraphs, and add comment
that C++ refers to them as alternative tokens.
Sun Jul 29 18:59:13 CEST 2001 Jan Hubicka <jh@suse.cz>
* basic-block.h (CLEANUP_PRE_LOOP): New.

View File

@ -267,16 +267,9 @@ parse_defined (pfile)
op.unsignedp = 0;
op.op = CPP_NUMBER;
/* No macros? At top of file? */
if (pfile->mi_state == MI_OUTSIDE && pfile->mi_cmacro == 0
&& pfile->mi_if_not_defined == MI_IND_NOT && pfile->mi_lexed == 1)
{
cpp_start_lookahead (pfile);
cpp_get_token (pfile, &token);
if (token.type == CPP_EOF)
pfile->mi_ind_cmacro = node;
cpp_stop_lookahead (pfile, 0);
}
/* A possible controlling macro of the form #if !defined ().
_cpp_parse_expr checks there was no other junk on the line. */
pfile->mi_ind_cmacro = node;
}
pfile->state.prevent_expansion--;
@ -351,10 +344,6 @@ lex (pfile, skip_evaluation, token)
}
else
{
/* Controlling #if expressions cannot contain identifiers (they
could become macros in the future). */
pfile->mi_state = MI_FAILED;
op.op = CPP_NUMBER;
op.unsignedp = 0;
op.value = 0;
@ -377,11 +366,6 @@ lex (pfile, skip_evaluation, token)
return op;
}
case CPP_NOT:
/* We don't worry about its position here. */
pfile->mi_if_not_defined = MI_IND_NOT;
/* Fall through. */
default:
if (((int) token->type > (int) CPP_EQ
&& (int) token->type < (int) CPP_PLUS_EQ)
@ -598,10 +582,12 @@ _cpp_parse_expr (pfile)
register struct op *top = stack + 1;
int skip_evaluation = 0;
int result;
unsigned int lex_count, saw_leading_not;
/* Set up detection of #if ! defined(). */
pfile->mi_lexed = 0;
pfile->mi_if_not_defined = MI_IND_NONE;
pfile->mi_ind_cmacro = 0;
saw_leading_not = 0;
lex_count = 0;
/* We've finished when we try to reduce this. */
top->op = CPP_EOF;
@ -618,7 +604,7 @@ _cpp_parse_expr (pfile)
/* Read a token */
op = lex (pfile, skip_evaluation, &token);
pfile->mi_lexed++;
lex_count++;
/* If the token is an operand, push its value and get next
token. If it is an operator, get its priority and flags, and
@ -638,6 +624,11 @@ _cpp_parse_expr (pfile)
continue;
case CPP_EOF: prio = FORCE_REDUCE_PRIO; break;
case CPP_NOT:
saw_leading_not = lex_count == 1;
prio = op_to_prio[op.op];
break;
case CPP_PLUS:
case CPP_MINUS: prio = PLUS_PRIO; if (top->flags & HAVE_VALUE) break;
/* else unary; fall through */
@ -869,7 +860,14 @@ _cpp_parse_expr (pfile)
}
done:
/* The controlling macro expression is only valid if we called lex 3
times: <!> <defined expression> and <EOF>. push_conditional ()
checks that we are at top-of-file. */
if (pfile->mi_ind_cmacro && !(saw_leading_not && lex_count == 3))
pfile->mi_ind_cmacro = 0;
result = (top[1].value != 0);
if (top != stack)
CPP_ICE ("unbalanced stack in #if");
else if (!(top[1].flags & HAVE_VALUE))

View File

@ -332,7 +332,7 @@ stack_include_file (pfile, inc)
fp->sysp = sysp;
/* Initialise controlling macro state. */
pfile->mi_state = MI_OUTSIDE;
pfile->mi_valid = true;
pfile->mi_cmacro = 0;
pfile->include_depth++;
@ -748,12 +748,12 @@ _cpp_pop_file_buffer (pfile, buf)
pfile->include_depth--;
/* Record the inclusion-preventing macro, which could be NULL
meaning no controlling macro, if we haven't got it already. */
if (pfile->mi_state == MI_OUTSIDE && inc->cmacro == NULL)
meaning no controlling macro. */
if (pfile->mi_valid && inc->cmacro == NULL)
inc->cmacro = pfile->mi_cmacro;
/* Invalidate control macros in the #including file. */
pfile->mi_state = MI_FAILED;
pfile->mi_valid = false;
inc->refcnt--;
if (inc->refcnt == 0 && DO_NOT_REREAD (inc))

View File

@ -93,10 +93,6 @@ struct search_path
struct file_name_map *name_map;
};
/* Multiple-include optimisation. */
enum mi_state {MI_FAILED = 0, MI_OUTSIDE};
enum mi_ind {MI_IND_NONE = 0, MI_IND_NOT};
/* #include types. */
enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE};
@ -268,11 +264,9 @@ struct cpp_reader
const struct directive *directive;
/* Multiple inlcude optimisation. */
enum mi_state mi_state;
enum mi_ind mi_if_not_defined;
unsigned int mi_lexed;
const cpp_hashnode *mi_cmacro;
const cpp_hashnode *mi_ind_cmacro;
bool mi_valid;
/* Token lookahead. */
struct cpp_lookahead *la_read; /* Read from this lookahead. */

View File

@ -1266,7 +1266,7 @@ _cpp_lex_token (pfile, result)
/* If not in a directive, this token invalidates controlling macros. */
if (!pfile->state.in_directive)
pfile->mi_state = MI_FAILED;
pfile->mi_valid = false;
}
/* An upper bound on the number of bytes needed to spell a token,

View File

@ -358,7 +358,7 @@ _cpp_handle_directive (pfile, indented)
/* If we have a directive that is not an opening
conditional, invalidate any control macro. */
if (! (dir->flags & IF_COND))
pfile->mi_state = MI_FAILED;
pfile->mi_valid = false;
(*dir->handler) (pfile);
}
@ -1278,27 +1278,22 @@ do_ifndef (pfile)
push_conditional (pfile, skip, T_IFNDEF, node);
}
/* #if cooperates with parse_defined to handle multiple-include
optimisations. If macro expansions or identifiers appear in the
expression, we cannot treat it as a controlling conditional, since
their values could change in the future. */
/* _cpp_parse_expr puts a macro in a "#if !defined ()" expression in
pfile->mi_ind_cmacro so we can handle multiple-include
optimisations. If macro expansion occurs in the expression, we
cannot treat it as a controlling conditional, since the expansion
could change in the future. That is handled by cpp_get_token. */
static void
do_if (pfile)
cpp_reader *pfile;
{
int skip = 1;
const cpp_hashnode *cmacro = 0;
if (! pfile->state.skipping)
{
/* Controlling macro of #if ! defined () */
pfile->mi_ind_cmacro = 0;
skip = _cpp_parse_expr (pfile) == 0;
cmacro = pfile->mi_ind_cmacro;
}
skip = _cpp_parse_expr (pfile) == 0;
push_conditional (pfile, skip, T_IF, cmacro);
push_conditional (pfile, skip, T_IF, pfile->mi_ind_cmacro);
}
/* Flip skipping state if appropriate and continue without changing
@ -1395,7 +1390,7 @@ do_endif (pfile)
/* If potential control macro, we go back outside again. */
if (ifs->next == 0 && ifs->mi_cmacro)
{
pfile->mi_state = MI_OUTSIDE;
pfile->mi_valid = true;
pfile->mi_cmacro = ifs->mi_cmacro;
}
@ -1406,8 +1401,8 @@ do_endif (pfile)
}
/* Push an if_stack entry and set pfile->state.skipping accordingly.
If this is a #ifndef starting at the beginning of a file,
CMACRO is the macro name tested by the #ifndef. */
If this is a #if or #ifndef, CMACRO is a potentially controlling
macro - we need to check here that we are at the top of the file. */
static void
push_conditional (pfile, skip, type, cmacro)
@ -1425,7 +1420,8 @@ push_conditional (pfile, skip, type, cmacro)
ifs->skip_elses = pfile->state.skipping || !skip;
ifs->was_skipping = pfile->state.skipping;
ifs->type = type;
if (pfile->mi_state == MI_OUTSIDE && pfile->mi_cmacro == 0)
/* This condition is effectively a test for top-of-file. */
if (pfile->mi_valid && pfile->mi_cmacro == 0)
ifs->mi_cmacro = cmacro;
else
ifs->mi_cmacro = 0;

View File

@ -953,7 +953,7 @@ cpp_get_token (pfile, token)
cpp_hashnode *node = token->val.node;
/* Macros invalidate controlling macros. */
pfile->mi_state = MI_FAILED;
pfile->mi_valid = false;
if (node->flags & NODE_BUILTIN)
{

View File

@ -536,15 +536,18 @@ be removed in GCC 3.1. You may use continued lines instead, or string
constant concatenation. @xref{Differences from previous versions}.
@cindex punctuators
@cindex digraphs
@cindex alternative tokens
@dfn{Punctuators} are all the usual bits of punctuation which are
meaningful to C and C++. All but three of the punctuation characters in
ASCII are C punctuators. The exceptions are @samp{@@}, @samp{$}, and
@samp{`}. In addition, all the two- and three-character operators are
punctuators. There are also six @dfn{digraphs}, which are merely
alternate ways to spell other punctuators. This is a second attempt to
work around missing punctuation in obsolete systems. It has no negative
side effects, unlike trigraphs, but does not cover as much ground. The
digraphs and their corresponding normal punctuators are:
punctuators. There are also six @dfn{digraphs}, which the C++ standard
calls @dfn{alternative tokens}, which are merely alternate ways to spell
other punctuators. This is a second attempt to work around missing
punctuation in obsolete systems. It has no negative side effects,
unlike trigraphs, but does not cover as much ground. The digraphs and
their corresponding normal punctuators are:
@example
Digraph: <% %> <: :> %: %:%: