mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 10:54:07 +08:00
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:
parent
0068fd9637
commit
6d18adbc2c
@ -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.
|
||||
|
42
gcc/cppexp.c
42
gcc/cppexp.c
@ -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))
|
||||
|
@ -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))
|
||||
|
@ -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. */
|
||||
|
@ -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,
|
||||
|
30
gcc/cpplib.c
30
gcc/cpplib.c
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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: <% %> <: :> %: %:%:
|
||||
|
Loading…
Reference in New Issue
Block a user