* cppexp.c (parse_defined): Always record the macro name.
authorneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 29 Jul 2001 17:27:57 +0000 (17:27 +0000)
committerneil <neil@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 29 Jul 2001 17:27:57 +0000 (17:27 +0000)
(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

gcc/ChangeLog
gcc/cppexp.c
gcc/cppfiles.c
gcc/cpphash.h
gcc/cpplex.c
gcc/cpplib.c
gcc/cppmacro.c
gcc/doc/cpp.texi

index aa26118..cb73400 100644 (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.
index 095a42d..52ffb27 100644 (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))
index 137882b..cb6ca5e 100644 (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))
index a8221d9..368fe46 100644 (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.  */
index 4821745..5248a42 100644 (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,
index c196c1f..8f9f54c 100644 (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;
index e630850..a4569a3 100644 (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)
            {
index 47ec9cd..319f735 100644 (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:        <%  %>  <:  :>  %:  %:%: