cppexp.c: Don't include cpphash.h.
authorZack Weinberg <zack@wolery.cumb.org>
Thu, 10 Feb 2000 23:47:04 +0000 (23:47 +0000)
committerZack Weinberg <zack@gcc.gnu.org>
Thu, 10 Feb 2000 23:47:04 +0000 (23:47 +0000)
* cppexp.c: Don't include cpphash.h.
(parse_charconst, cpp_lex): Use cpp_defined.
(cpp_lex): Use get_directive_token throughout.  Remove
unnecessary cases from switch.  Move assertion-handling code
down to OTHER case.
(cpp_parse_expr): If we see '+' or '-', check the context to
determine if they are unary or binary operators.  Streamline
the jumps a bit.  Do not call skip_rest_of_line.

* cpplib.c: Make skip_rest_of_line and cpp_skip_hspace
static.  Export get_directive_token.  Update commentary.
(cpp_defined): New function.
(do_define): Remove reference to T_PCSTRING.  Call
free_definition to release memory for old definition, when
redefining a macro.
(eval_if_expression): Set only_seen_white to 0 before calling
cpp_parse_expr.  Call skip_rest_of_line after it returns.
(cpp_read_check_assertion): Don't preserve a pointer into the
token buffer across a call to cpp_get_token.

* Makefile.in (cppexp.o): Don't depend on cpphash.h.
* cppfiles.c (redundant_include_p): Use cpp_defined.
* cpphash.c (free_definition): New function.
(delete_macro): Use it.  Update commentary.
* cpphash.h: Typedef HASHNODE here.  Prototype cpp_lookup and
free_definition.
* cpplib.h: Don't typedef HASHNODE here. Delete T_PCSTRING
from enum node_type.  Prototype cpp_defined and get_directive_token.
Don't prototype cpp_lookup, skip_rest_of_line, or cpp_skip_hspace.

* fix-header.c (check_macro_names): Use cpp_defined.
(read_scan_file): Set inhibit_warnings and inhibit_errors in
the options structure.

From-SVN: r31908

gcc/ChangeLog
gcc/Makefile.in
gcc/cppexp.c
gcc/cppfiles.c
gcc/cpphash.c
gcc/cpphash.h
gcc/cpplib.c
gcc/cpplib.h
gcc/fix-header.c
gcc/testsuite/gcc.dg/20000207-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/20000207-2.c [new file with mode: 0644]

index 5eff6b03bd4060507409f08c75bd9de7e00ce5dc..255ab22a96ded7fa765ebb5610bcbb8ba25708e9 100644 (file)
@@ -1,3 +1,39 @@
+2000-02-10  Zack Weinberg  <zack@wolery.cumb.org>
+
+       * cppexp.c: Don't include cpphash.h.
+       (parse_charconst, cpp_lex): Use cpp_defined.
+       (cpp_lex): Use get_directive_token throughout.  Remove
+       unnecessary cases from switch.  Move assertion-handling code
+       down to OTHER case.
+       (cpp_parse_expr): If we see '+' or '-', check the context to
+       determine if they are unary or binary operators.  Streamline
+       the jumps a bit.  Do not call skip_rest_of_line.
+
+       * cpplib.c: Make skip_rest_of_line and cpp_skip_hspace
+       static.  Export get_directive_token.  Update commentary.
+       (cpp_defined): New function.
+       (do_define): Remove reference to T_PCSTRING.  Call
+       free_definition to release memory for old definition, when
+       redefining a macro.
+       (eval_if_expression): Set only_seen_white to 0 before calling
+       cpp_parse_expr.  Call skip_rest_of_line after it returns.
+       (cpp_read_check_assertion): Don't preserve a pointer into the
+       token buffer across a call to cpp_get_token.
+
+       * Makefile.in (cppexp.o): Don't depend on cpphash.h.
+       * cppfiles.c (redundant_include_p): Use cpp_defined.
+       * cpphash.c (free_definition): New function.
+       (delete_macro): Use it.  Update commentary.
+       * cpphash.h: Typedef HASHNODE here.  Prototype cpp_lookup and
+       free_definition.
+       * cpplib.h: Don't typedef HASHNODE here. Delete T_PCSTRING
+       from enum node_type.  Prototype cpp_defined and get_directive_token.
+       Don't prototype cpp_lookup, skip_rest_of_line, or cpp_skip_hspace.
+
+       * fix-header.c (check_macro_names): Use cpp_defined.
+       (read_scan_file): Set inhibit_warnings and inhibit_errors in
+       the options structure.
+
 2000-02-10  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
 
        * c-pragma.c (maximum_field_alignment): Remove duplicate declaration.
index f231557ee5712b9b4ce7cdc85a25275e9fdd5d58..31a0173f73f8e1ade458c39b74eb5158aff5c367 100644 (file)
@@ -2043,7 +2043,7 @@ cpplib.o:  cpplib.c  $(CONFIG_H) cpplib.h intl.h system.h cpphash.h
 cpphash.o: cpphash.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h
 cppalloc.o: cppalloc.c $(CONFIG_H) cpplib.h intl.h system.h
 cpperror.o: cpperror.c $(CONFIG_H) cpplib.h intl.h system.h
-cppexp.o:   cppexp.c   $(CONFIG_H) cpplib.h intl.h system.h cpphash.h
+cppexp.o:   cppexp.c   $(CONFIG_H) cpplib.h intl.h system.h
 cppfiles.o: cppfiles.c $(CONFIG_H) cpplib.h intl.h system.h
 
 cppinit.o:  cppinit.c $(CONFIG_H) cpplib.h intl.h system.h \
index 7f8c9174797f6063be3f7846027f6b2efee2229d..a7db2ce899a670b03b290482223f646f4902c31f 100644 (file)
@@ -27,7 +27,6 @@ Written by Per Bothner 1994.  */
 #include "config.h"
 #include "system.h"
 #include "cpplib.h"
-#include "cpphash.h"
 
 #ifdef MULTIBYTE_CHARS
 #include <locale.h>
@@ -331,8 +330,8 @@ parse_charconst (pfile, start, end)
   /* If char type is signed, sign-extend the constant.  */
   num_bits = num_chars * width;
       
-  if (cpp_lookup (pfile, (const U_CHAR *)"__CHAR_UNSIGNED__",
-                 sizeof ("__CHAR_UNSIGNED__")-1)
+  if (cpp_defined (pfile, (const U_CHAR *)"__CHAR_UNSIGNED__",
+                  sizeof ("__CHAR_UNSIGNED__")-1)
       || ((result >> (num_bits - 1)) & 1) == 0)
     op.value = result & ((unsigned HOST_WIDEST_INT) ~0
                         >> (HOST_BITS_PER_WIDEST_INT - num_bits));
@@ -377,56 +376,28 @@ cpp_lex (pfile, skip_evaluation)
      cpp_reader *pfile;
      int skip_evaluation;
 {
-  U_CHAR c;
   struct token *toktab;
   enum cpp_token token;
   struct operation op;
   U_CHAR *tok_start, *tok_end;
-  int old_written;
-
- retry:
+  long old_written;
 
   old_written = CPP_WRITTEN (pfile);
-  cpp_skip_hspace (pfile);
-  c = CPP_BUF_PEEK (CPP_BUFFER (pfile));
-  if (c == '#')
-    {
-      op.op = INT;
-      op.value = cpp_read_check_assertion (pfile);
-      return op;
-    }
-
-  if (c == '\n')
-    {
-      op.op = 0;
-      return op;
-    }
+  token = get_directive_token (pfile);
 
-  token = cpp_get_token (pfile);
   tok_start = pfile->token_buffer + old_written;
   tok_end = CPP_PWRITTEN (pfile);
-  pfile->limit = tok_start;
+  CPP_SET_WRITTEN (pfile, old_written);
   switch (token)
   {
     case CPP_EOF: /* Should not happen ...  */
     case CPP_VSPACE:
       op.op = 0;
       return op;
-    case CPP_POP:
-      if (CPP_BUFFER (pfile)->fname != NULL)
-       {
-         op.op = 0;
-         return op;
-       }
-      cpp_pop_buffer (pfile);
-      goto retry;
-    case CPP_HSPACE:
-    case CPP_COMMENT: 
-      goto retry;
     case CPP_NUMBER:
       return parse_number (pfile, tok_start, tok_end);
     case CPP_STRING:
-      cpp_error (pfile, "string constants not allowed in #if expressions");
+      cpp_error (pfile, "string constants are not allowed in #if expressions");
       op.op = ERROR;
       return op;
     case CPP_CHAR:
@@ -445,45 +416,38 @@ cpp_lex (pfile, skip_evaluation)
       else
        {
          int paren = 0, len;
-         cpp_buffer *ip = CPP_BUFFER (pfile);
          U_CHAR *tok;
-         HASHNODE *hp;
 
-         cpp_skip_hspace (pfile);
-         if (*ip->cur == '(')
+         pfile->no_macro_expand++;
+         token = get_directive_token (pfile);
+         if (token == CPP_LPAREN)
            {
              paren++;
-             ip->cur++;                        /* Skip over the paren */
-             cpp_skip_hspace (pfile);
+             CPP_SET_WRITTEN (pfile, old_written);
+             token = get_directive_token (pfile);
            }
 
-         if (!is_idstart(*ip->cur))
-           goto oops;
-         if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '"'))
+         if (token != CPP_NAME)
            goto oops;
-         tok = ip->cur;
-         while (is_idchar(*ip->cur))
-           ++ip->cur;
-         len = ip->cur - tok;
-         cpp_skip_hspace (pfile);
+
+         tok = pfile->token_buffer + old_written;
+         len = CPP_PWRITTEN (pfile) - tok;
+         if (cpp_defined (pfile, tok, len))
+           op.value = 1;
+
          if (paren)
            {
-             if (*ip->cur != ')')
+             if (get_directive_token (pfile) != CPP_RPAREN)
                goto oops;
-             ++ip->cur;
-           }
-         hp = cpp_lookup (pfile, tok, len);
-         if (hp != NULL)
-           {
-             if (hp->type == T_POISON)
-               cpp_error (pfile, "attempt to use poisoned `%s'", hp->name);
-             else
-               op.value = 1;
            }
+         CPP_SET_WRITTEN (pfile, old_written);
+         pfile->no_macro_expand--;
        }
       return op;
 
     oops:
+      CPP_SET_WRITTEN (pfile, old_written);
+      pfile->no_macro_expand--;
       cpp_error (pfile, "`defined' without an identifier");
       return op;
 
@@ -501,6 +465,13 @@ cpp_lex (pfile, skip_evaluation)
          op.op = toktab->token; 
          return op;
        }
+      else if (tok_start + 1 == tok_end && *tok_start == '#')
+       {
+         CPP_FORWARD (CPP_BUFFER (pfile), -1);
+         op.op = INT;
+         op.value = cpp_read_check_assertion (pfile);
+         return op;
+       }
       /* fall through */
     default:
       op.op = *tok_start;
@@ -736,15 +707,16 @@ cpp_parse_expr (pfile)
          cpp_ice (pfile, "cpp_lex returns a NAME");
          goto syntax_error;
        case INT:  case CHAR:
-         top->value = op.value;
-         top->unsignedp = op.unsignedp;
          goto set_value;
        case 0:
          lprio = 0;  goto maybe_reduce;
        case '+':  case '-':
-         /* Is this correct if unary ? FIXME */
-         flags = RIGHT_OPERAND_REQUIRED;
-         lprio = PLUS_PRIO;  rprio = lprio + 1;  goto maybe_reduce;
+         if (top->flags & HAVE_VALUE)
+           {
+             lprio = PLUS_PRIO;
+             goto binop;
+           }
+         /* else fall through */
        case '!':  case '~':
          flags = RIGHT_OPERAND_REQUIRED;
          rprio = UNARY_PRIO;  lprio = rprio + 1;  goto maybe_reduce;
@@ -777,10 +749,6 @@ cpp_parse_expr (pfile)
          goto maybe_reduce;
        case ERROR:
          goto syntax_error;
-       binop:
-         flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
-         rprio = lprio + 1;
-         goto maybe_reduce;
        default:
          cpp_error (pfile, "invalid character in #if");
          goto syntax_error;
@@ -793,9 +761,15 @@ cpp_parse_expr (pfile)
          cpp_error (pfile, "syntax error in #if");
          goto syntax_error;
        }
+      top->value = op.value;
+      top->unsignedp = op.unsignedp;
       top->flags |= HAVE_VALUE;
       continue;
 
+    binop:
+      flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
+      rprio = lprio + 1;
+
     maybe_reduce:
       /* Push an operator, and check if we can reduce now.  */
       while (top->rprio > lprio)
@@ -1065,6 +1039,5 @@ cpp_parse_expr (pfile)
  syntax_error:
   if (stack != init_stack)
     free (stack);
-  skip_rest_of_line (pfile);
   return 0;
 }
index deb8bf019e75824a737693b73c6d86076950417b..a00fb89e395c671fa391688f75d8ade61e4ad678 100644 (file)
@@ -286,7 +286,7 @@ redundant_include_p (pfile, ihash, ilist)
            included again if the string is the name of a defined macro. */
         return (i->control_macro
                 && (i->control_macro[0] == '\0'
-                    || cpp_lookup (pfile, i->control_macro, -1)))
+                    || cpp_defined (pfile, i->control_macro, -1)))
             ? (struct include_hash *)-1 : i;
 
   return 0;
index 0a4e8607dfb9910b39b97cc070b9533cf54be9b7..7b0bea23f174a93a88ac91dec15ab828e0e7fc71 100644 (file)
@@ -140,20 +140,31 @@ cpp_lookup (pfile, name, len)
   return (HASHNODE *) 0;
 }
 
+/* Free a DEFINITION structure.  Used by delete_macro, and by
+   do_define when redefining macros.  */
+
+void
+free_definition (d)
+     DEFINITION *d;
+{
+  struct reflist *ap, *nextap;
+
+  for (ap = d->pattern; ap != NULL; ap = nextap)
+    {
+      nextap = ap->next;
+      free (ap);
+    }
+  if (d->nargs >= 0)
+    free (d->argnames);
+  free (d);
+}
+
 /*
  * Delete a hash node.  Some weirdness to free junk from macros.
  * More such weirdness will have to be added if you define more hash
  * types that need it.
  */
 
-/* Note that the DEFINITION of a macro is removed from the hash table
-   but its storage is not freed.  This would be a storage leak
-   except that it is not reasonable to keep undefining and redefining
-   large numbers of macros many times.
-   In any case, this is necessary, because a macro can be #undef'd
-   in the middle of reading the arguments to a call to it.
-   If #undef freed the DEFINITION, that would crash.  */
-
 void
 delete_macro (hp)
      HASHNODE *hp;
@@ -170,19 +181,7 @@ delete_macro (hp)
     *hp->bucket_hdr = hp->next;
 
   if (hp->type == T_MACRO)
-    {
-      DEFINITION *d = hp->value.defn;
-      struct reflist *ap, *nextap;
-
-      for (ap = d->pattern; ap != NULL; ap = nextap)
-       {
-         nextap = ap->next;
-         free (ap);
-       }
-      if (d->nargs >= 0)
-       free (d->argnames);
-      free (d);
-    }
+    free_definition (hp->value.defn);
 
   free (hp);
 }
index 960700cc9c2f9e386e1e895b0b58f2a77062a2b8..b9742843ed9536c0770c749b7404b6908101608d 100644 (file)
@@ -83,6 +83,7 @@ union hashval
   struct hashnode *aschain;    /* #assert */
 };
 
+typedef struct hashnode HASHNODE;
 struct hashnode {
   struct hashnode *next;       /* double links for easy deletion */
   struct hashnode *prev;
@@ -97,6 +98,8 @@ struct hashnode {
 
 extern HASHNODE *cpp_install     PARAMS ((cpp_reader *, const U_CHAR *, int,
                                           enum node_type, const char *));
+extern HASHNODE *cpp_lookup      PARAMS ((cpp_reader *, const U_CHAR *, int));
+extern void free_definition      PARAMS ((DEFINITION *));
 extern void delete_macro         PARAMS ((HASHNODE *));
 
 extern MACRODEF create_definition PARAMS ((U_CHAR *, U_CHAR *,
index 896d602414c065caa7b658997d08d06d34fbe169..c64e682f8881e158cc61bd035d3f0eef6a6050dc 100644 (file)
@@ -93,11 +93,12 @@ static int null_cleanup                     PARAMS ((cpp_buffer *, cpp_reader *));
 static int skip_comment                        PARAMS ((cpp_reader *, int));
 static int copy_comment                        PARAMS ((cpp_reader *, int));
 static void copy_rest_of_line          PARAMS ((cpp_reader *));
+static void skip_rest_of_line          PARAMS ((cpp_reader *));
+static void cpp_skip_hspace            PARAMS ((cpp_reader *));
 static int handle_directive            PARAMS ((cpp_reader *));
 static void pass_thru_directive                PARAMS ((const U_CHAR *, size_t,
                                                 cpp_reader *,
                                                 const struct directive *));
-static enum cpp_token get_directive_token PARAMS ((cpp_reader *));
 static int read_line_number            PARAMS ((cpp_reader *, int *));
 static U_CHAR *detect_if_not_defined   PARAMS ((cpp_reader *));
 static int consider_directive_while_skipping PARAMS ((cpp_reader *,
@@ -192,12 +193,7 @@ cpp_grow_buffer (pfile, n)
   CPP_SET_WRITTEN (pfile, old_written);
 }
 
-/* Process the string STR as if it appeared as the body of a #define
-   If STR is just an identifier, define it with value 1.
-   If STR has anything after the identifier, then it should
-   be identifier=definition. */
-
-/* Process the string STR as if it appeared as the body of a #define
+/* Process the string STR as if it appeared as the body of a #define.
    If STR is just an identifier, define it with value 1.
    If STR has anything after the identifier, then it should
    be identifier=definition. */
@@ -252,6 +248,21 @@ cpp_assert (pfile, str)
     }
 }
 
+/* Determine whether the identifier ID, of length LEN, is a defined macro.  */
+int
+cpp_defined (pfile, id, len)
+     cpp_reader *pfile;
+     const U_CHAR *id;
+     int len;
+{
+  HASHNODE *hp = cpp_lookup (pfile, id, len);
+  if (hp && hp->type == T_POISON)
+    {
+      cpp_error (pfile, "attempt to use poisoned `%s'", hp->name);
+      return 0;
+    }
+  return (hp != NULL);
+}
 
 static enum cpp_token
 null_underflow (pfile)
@@ -407,7 +418,7 @@ copy_comment (pfile, m)
 
 /* Skip whitespace \-newline and comments.  Does not macro-expand.  */
 
-void
+static void
 cpp_skip_hspace (pfile)
      cpp_reader *pfile;
 {
@@ -508,7 +519,7 @@ copy_rest_of_line (pfile)
    the scan itself.  >75% of calls to copy_r_o_l are from here or
    skip_if_group, which means the common case is to copy stuff into the
    token_buffer only to discard it.  */
-void
+static void
 skip_rest_of_line (pfile)
      cpp_reader *pfile;
 {
@@ -684,11 +695,8 @@ do_define (pfile, keyword)
   if ((hp = cpp_lookup (pfile, mdef.symnam, mdef.symlen)) != NULL)
     {
       int ok = 0;
-      /* Redefining a precompiled key is ok.  */
-      if (hp->type == T_PCSTRING)
-       ok = 1;
       /* Redefining a poisoned identifier is even worse than `not ok'.  */
-      else if (hp->type == T_POISON)
+      if (hp->type == T_POISON)
        ok = -1;
       /* Redefining a macro is ok if the definitions are the same.  */
       else if (hp->type == T_MACRO)
@@ -713,6 +721,7 @@ do_define (pfile, keyword)
        {
          /* Replace the old definition.  */
          hp->type = new_type;
+         free_definition (hp->value.defn);
          hp->value.defn = mdef.defn;
        }
     }
@@ -986,7 +995,7 @@ output_line_command (pfile, file_change)
 /* Like cpp_get_token, except that it does not read past end-of-line.
    Also, horizontal space is skipped, and macros are popped.  */
 
-static enum cpp_token
+enum cpp_token
 get_directive_token (pfile)
      cpp_reader *pfile;
 {
@@ -1872,8 +1881,13 @@ eval_if_expression (pfile)
   HOST_WIDEST_INT value;
   long old_written = CPP_WRITTEN (pfile);
 
+  /* Work around bug in cpp_get_token where it may mistake an
+     assertion for a directive.  */
+  pfile->only_seen_white = 0;
+
   value = cpp_parse_expr (pfile);
 
+  skip_rest_of_line (pfile);
   CPP_SET_WRITTEN (pfile, old_written); /* Pop */
 
   return value;
@@ -2631,10 +2645,7 @@ cpp_get_token (pfile)
                return CPP_NAME;
              }
 
-           /* If macro wants an arglist, verify that a '(' follows.
-              first skip all whitespace, copying it to the output
-              after the macro name.  Then, if there is no '(',
-              decide this is not a macro call and leave things that way.  */
+           /* If macro wants an arglist, verify that a '(' follows.  */
            if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
            {
              int macbuf_whitespace = 0;
@@ -3130,9 +3141,9 @@ int
 cpp_read_check_assertion (pfile)
      cpp_reader *pfile;
 {
-  U_CHAR *name = CPP_PWRITTEN (pfile);
+  U_CHAR *name;
   int result;
-  HASHNODE *hp;
+  long written = CPP_WRITTEN (pfile);
   
   FORWARD (1);  /* Skip '#' */
   cpp_skip_hspace (pfile);
@@ -3140,15 +3151,21 @@ cpp_read_check_assertion (pfile)
     result = 0;
   else
     {
-      hp = cpp_lookup (pfile, name, CPP_PWRITTEN (pfile) - name);
-      result = (hp != 0);
+      name = pfile->token_buffer + written;
+      result = cpp_defined (pfile, name, CPP_PWRITTEN (pfile) - name);
     }
 
-  pfile->limit = name;
+  CPP_SET_WRITTEN (pfile, written);
   return result;
 }
 
-/* Remember the current position of PFILE.  */
+/* Remember the current position of PFILE so it may be returned to
+   after looking ahead a bit.
+
+   Note that when you set a mark, you _must_ return to that mark.  You
+   may not forget about it and continue parsing.  You may not pop a
+   buffer with an active mark.  You may not call CPP_BUMP_LINE while a
+   mark is active.  */
 
 static void
 parse_set_mark (pfile)
index 266b90305abfdc1cb4bf3a659720e33c1b4359c1..82eb55c44b9dfb19756ce0256f9937de148c87ef 100644 (file)
@@ -61,8 +61,8 @@ typedef int (*parse_cleanup_t) PARAMS((cpp_buffer *, cpp_reader *));
 extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **));
 extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
 extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *));
-extern void cpp_skip_hspace PARAMS((cpp_reader *));
 extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *));
+extern enum cpp_token get_directive_token PARAMS ((cpp_reader *));
 
 /* This frees resources used by PFILE. */
 extern void cpp_cleanup PARAMS ((cpp_reader *PFILE));
@@ -139,9 +139,6 @@ struct file_name_map_list;
    Applying cpp_get_token repeatedly yields a stream of pre-processor
    tokens.  Usually, there is only one cpp_reader object active. */
 
-struct hashnode;
-typedef struct hashnode HASHNODE;
-
 struct cpp_reader
 {
   parse_underflow_t get_token;
@@ -169,7 +166,7 @@ struct cpp_reader
 
   /* Hash table of macros and assertions.  See cpphash.c */
 #define HASHSIZE 1403
-  HASHNODE **hashtab;
+  struct hashnode **hashtab;
 
   /* Hash table of other included files.  See cppfiles.c */
 #define ALL_INCLUDE_HASHSIZE 71
@@ -600,7 +597,6 @@ enum node_type {
  T_CONST,      /* Constant string, used by `__SIZE_TYPE__' etc */
  T_MACRO,      /* macro defined by `#define' */
  T_DISABLED,   /* macro temporarily turned off for rescan */
- T_PCSTRING,   /* precompiled string (hashval is KEYDEF *) */
  T_POISON,     /* defined with `#pragma poison' */
  T_UNUSED      /* Used for something not defined.  */
  };
@@ -686,13 +682,12 @@ extern void cpp_grow_buffer PARAMS ((cpp_reader *, long));
 extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
                                            unsigned char *, long));
 extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
-extern HASHNODE *cpp_lookup PARAMS ((cpp_reader *, const U_CHAR *, int));
+extern int cpp_defined PARAMS ((cpp_reader *, const U_CHAR *, int));
 
 extern void cpp_reader_init PARAMS ((cpp_reader *));
 extern void cpp_options_init PARAMS ((cpp_options *));
 extern int cpp_start_read PARAMS ((cpp_reader *, char *));
 extern int cpp_read_check_assertion PARAMS ((cpp_reader *));
-extern void skip_rest_of_line PARAMS ((cpp_reader *));
 extern void cpp_finish PARAMS ((cpp_reader *));
 
 extern void quote_string               PARAMS ((cpp_reader *, const char *));
index 802d6364ac363725d18ff49e5af718e5216353af..6b1c56f575c2f9d37645454b41acb9df376f8ea6 100644 (file)
@@ -603,7 +603,7 @@ check_macro_names (pfile, names)
 {
   while (*names)
     {
-      if (cpp_lookup (pfile, names, -1))
+      if (cpp_defined (pfile, names, -1))
        recognized_macro (names);
       names += strlen (names) + 1;
     }
@@ -626,6 +626,10 @@ read_scan_file (in_fname, argc, argv)
   cpp_reader_init (&scan_in);
   scan_in.opts = &scan_options;
   cpp_options_init (&scan_options);
+  /* We are going to be scanning a header file out of its proper context,
+     so ignore warnings and errors.  */
+  scan_options.inhibit_warnings = 1;
+  scan_options.inhibit_errors = 1;
   i = cpp_handle_options (&scan_in, argc, argv);
   if (i < argc && ! CPP_FATAL_ERRORS (&scan_in))
     cpp_fatal (&scan_in, "Invalid option `%s'", argv[i]);
diff --git a/gcc/testsuite/gcc.dg/20000207-1.c b/gcc/testsuite/gcc.dg/20000207-1.c
new file mode 100644 (file)
index 0000000..931cc0d
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do preprocess } */
+
+/* Test for proper handling of unary minus in #if.  */
+
+#if !(-1)
+#error Error   /* { dg-bogus "Error" "case !(-1)" } */
+#endif
+
+#if !-1
+#error Error   /* { dg-bogus "Error" "case !-1" } */
+#endif
+
+#if -1
+#else
+#error Error   /* { dg-bogus "Error" "case -1" } */
+#endif
diff --git a/gcc/testsuite/gcc.dg/20000207-2.c b/gcc/testsuite/gcc.dg/20000207-2.c
new file mode 100644 (file)
index 0000000..fbdf39e
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do preprocess } */
+
+/* Test for proper handling of unary plus in #if.  */
+
+#if !(+1)
+#error Error   /* { dg-bogus "Error" "case !(+1)" } */
+#endif
+
+#if !+1
+#error Error   /* { dg-bogus "Error" "case !+1" } */
+#endif
+
+#if +1
+#else
+#error Error   /* { dg-bogus "Error" "case +1" } */
+#endif