summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>2001-07-29 17:27:57 +0000
committerneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>2001-07-29 17:27:57 +0000
commitfa233610fcbee7f3e67375962e6effe96c2b19e2 (patch)
treeae3bf4ef61f7e71d609b714e200c82e7e441cba2
parent4d1f4307480c700e251e01b4931f8935db4a04cc (diff)
downloadgcc-fa233610fcbee7f3e67375962e6effe96c2b19e2.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44459 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/cppexp.c42
-rw-r--r--gcc/cppfiles.c8
-rw-r--r--gcc/cpphash.h8
-rw-r--r--gcc/cpplex.c2
-rw-r--r--gcc/cpplib.c30
-rw-r--r--gcc/cppmacro.c2
-rw-r--r--gcc/doc/cpp.texi13
8 files changed, 68 insertions, 57 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index aa26118a252..cb73400b1ee 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/cppexp.c b/gcc/cppexp.c
index 095a42d8280..52ffb27881c 100644
--- a/gcc/cppexp.c
+++ b/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))
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index 137882b340c..cb6ca5eda73 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -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))
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index a8221d98a25..368fe46f287 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -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. */
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index 48217451523..5248a422f45 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -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,
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index c196c1f9c96..8f9f54c8be6 100644
--- a/gcc/cpplib.c
+++ b/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;
diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c
index e630850106a..a4569a3e073 100644
--- a/gcc/cppmacro.c
+++ b/gcc/cppmacro.c
@@ -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)
{
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index 47ec9cde9d8..319f73510d8 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -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: <% %> <: :> %: %:%: