OSDN Git Service

* config/s390/s390.c (s390_emit_epilogue): Always restore registers
[pf3gnuchains/gcc-fork.git] / gcc / cppexp.c
index acfa30e..b62741b 100644 (file)
@@ -1,6 +1,6 @@
 /* Parse C expressions for cpplib.
-   Copyright (C) 1987, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2001
-   Free Software Foundation.
+   Copyright (C) 1987, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
+   2002 Free Software Foundation.
    Contributed by Per Bothner, 1994.
 
 This program is free software; you can redistribute it and/or modify it
@@ -36,15 +36,15 @@ static HOST_WIDEST_INT right_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT,
                                            unsigned HOST_WIDEST_INT));
 static struct op parse_number PARAMS ((cpp_reader *, const cpp_token *));
 static struct op parse_defined PARAMS ((cpp_reader *));
-static struct op lex PARAMS ((cpp_reader *, int, cpp_token *));
+static struct op lex PARAMS ((cpp_reader *, int));
 static const unsigned char *op_as_text PARAMS ((cpp_reader *, enum cpp_ttype));
 
 struct op
 {
   enum cpp_ttype op;
-  U_CHAR prio;         /* Priority of op.  */
-  U_CHAR flags;
-  U_CHAR unsignedp;    /* True if value should be treated as unsigned.  */
+  uchar prio;         /* Priority of op.  */
+  uchar flags;
+  uchar unsignedp;    /* True if value should be treated as unsigned.  */
   HOST_WIDEST_INT value; /* The value logically "right" of op.  */
 };
 
@@ -54,48 +54,46 @@ struct op
 
 /* With -O2, gcc appears to produce nice code, moving the error
    message load and subsequent jump completely out of the main path.  */
-#define CPP_ICE(msgid) \
-  do { cpp_ice (pfile, msgid); goto syntax_error; } while(0)
 #define SYNTAX_ERROR(msgid) \
-  do { cpp_error (pfile, msgid); goto syntax_error; } while(0)
+  do { cpp_error (pfile, DL_ERROR, msgid); goto syntax_error; } while(0)
 #define SYNTAX_ERROR2(msgid, arg) \
-  do { cpp_error (pfile, msgid, arg); goto syntax_error; } while(0)
+  do { cpp_error (pfile, DL_ERROR, msgid, arg); goto syntax_error; } while(0)
 
-/* Parse and convert an integer for #if.  Accepts decimal, hex, or octal
-   with or without size suffixes.  */
 struct suffix
 {
-  unsigned char s[4];
-  unsigned char u;
-  unsigned char l;
+  const unsigned char s[4];
+  const unsigned char u;
+  const unsigned char l;
 };
 
-const struct suffix vsuf_1[] = {
+static const struct suffix vsuf_1[] = {
   { "u", 1, 0 }, { "U", 1, 0 },
   { "l", 0, 1 }, { "L", 0, 1 }
 };
 
-const struct suffix vsuf_2[] = {
+static const struct suffix vsuf_2[] = {
   { "ul", 1, 1 }, { "UL", 1, 1 }, { "uL", 1, 1 }, { "Ul", 1, 1 },
   { "lu", 1, 1 }, { "LU", 1, 1 }, { "Lu", 1, 1 }, { "lU", 1, 1 },
   { "ll", 0, 2 }, { "LL", 0, 2 }
 };
 
-const struct suffix vsuf_3[] = {
+static const struct suffix vsuf_3[] = {
   { "ull", 1, 2 }, { "ULL", 1, 2 }, { "uLL", 1, 2 }, { "Ull", 1, 2 },
   { "llu", 1, 2 }, { "LLU", 1, 2 }, { "LLu", 1, 2 }, { "llU", 1, 2 }
 };
-#define Nsuff(tab) (sizeof tab / sizeof (struct suffix))
 
+/* Parse and convert what is presumably an integer in TOK.  Accepts
+   decimal, hex, or octal with or without size suffixes.  Returned op
+   is CPP_ERROR on error, otherwise it is a CPP_NUMBER.  */
 static struct op
 parse_number (pfile, tok)
      cpp_reader *pfile;
      const cpp_token *tok;
 {
   struct op op;
-  const U_CHAR *start = tok->val.str.text;
-  const U_CHAR *end = start + tok->val.str.len;
-  const U_CHAR *p = start;
+  const uchar *start = tok->val.str.text;
+  const uchar *end = start + tok->val.str.len;
+  const uchar *p = start;
   int c = 0, i, nsuff;
   unsigned HOST_WIDEST_INT n = 0, nd, MAX_over_base;
   int base = 10;
@@ -127,14 +125,9 @@ parse_number (pfile, tok)
     {
       c = *p;
 
-      if (c >= '0' && c <= '9')
-       digit = c - '0';
-      /* We believe that in all live character sets, a-f are
-        consecutive, and so are A-F.  */
-      else if (base == 16 && c >= 'a' && c <= 'f')
-       digit = c - 'a' + 10;
-      else if (base == 16 && c >= 'A' && c <= 'F')
-       digit = c - 'A' + 10;
+      if (ISDIGIT (c)
+         || (base == 16 && ISXDIGIT (c)))
+       digit = hex_value (c);
       else
        break;
 
@@ -161,9 +154,9 @@ parse_number (pfile, tok)
         See the suffix tables, above.  */
       switch (end - p)
        {
-       case 1: sufftab = vsuf_1; nsuff = Nsuff(vsuf_1); break;
-       case 2: sufftab = vsuf_2; nsuff = Nsuff(vsuf_2); break;
-       case 3: sufftab = vsuf_3; nsuff = Nsuff(vsuf_3); break;
+       case 1: sufftab = vsuf_1; nsuff = ARRAY_SIZE (vsuf_1); break;
+       case 2: sufftab = vsuf_2; nsuff = ARRAY_SIZE (vsuf_2); break;
+       case 3: sufftab = vsuf_3; nsuff = ARRAY_SIZE (vsuf_3); break;
        default: goto invalid_suffix;
        }
 
@@ -177,82 +170,84 @@ parse_number (pfile, tok)
       if (CPP_WTRADITIONAL (pfile)
          && sufftab[i].u
          && ! cpp_sys_macro_p (pfile))
-       cpp_warning (pfile, "traditional C rejects the `U' suffix");
+       cpp_error (pfile, DL_WARNING, "traditional C rejects the `U' suffix");
       if (sufftab[i].l == 2 && CPP_OPTION (pfile, pedantic)
          && ! CPP_OPTION (pfile, c99))
-       cpp_pedwarn (pfile, "too many 'l' suffixes in integer constant");
+       cpp_error (pfile, DL_PEDWARN,
+                  "too many 'l' suffixes in integer constant");
     }
   
   if (base <= largest_digit)
-    cpp_pedwarn (pfile, "integer constant contains digits beyond the radix");
+    cpp_error (pfile, DL_PEDWARN,
+              "integer constant contains digits beyond the radix");
 
   if (overflow)
-    cpp_pedwarn (pfile, "integer constant out of range");
+    cpp_error (pfile, DL_PEDWARN, "integer constant out of range");
 
   /* If too big to be signed, consider it unsigned.  */
   else if ((HOST_WIDEST_INT) n < 0 && ! op.unsignedp)
     {
       if (base == 10)
-       cpp_warning (pfile, "integer constant is so large that it is unsigned");
+       cpp_error (pfile, DL_WARNING,
+                  "integer constant is so large that it is unsigned");
       op.unsignedp = 1;
     }
 
   op.value = n;
-  op.op = CPP_INT;
+  op.op = CPP_NUMBER;
   return op;
 
  invalid_suffix:
-  cpp_error (pfile, "invalid suffix '%.*s' on integer constant",
+  cpp_error (pfile, DL_ERROR, "invalid suffix '%.*s' on integer constant",
             (int) (end - p), p);
  syntax_error:
   op.op = CPP_ERROR;
   return op;
 }
 
+/* Handle meeting "defined" in a preprocessor expression.  */
 static struct op
 parse_defined (pfile)
      cpp_reader *pfile;
 {
   int paren = 0;
   cpp_hashnode *node = 0;
-  cpp_token token;
+  const cpp_token *token;
   struct op op;
+  cpp_context *initial_context = pfile->context;
 
   /* Don't expand macros.  */
   pfile->state.prevent_expansion++;
 
-  cpp_get_token (pfile, &token);
-  if (token.type == CPP_OPEN_PAREN)
+  token = cpp_get_token (pfile);
+  if (token->type == CPP_OPEN_PAREN)
     {
       paren = 1;
-      cpp_get_token (pfile, &token);
+      token = cpp_get_token (pfile);
     }
 
-  if (token.type == CPP_NAME)
+  if (token->type == CPP_NAME)
     {
-      node = token.val.node;
-      if (paren)
+      node = token->val.node;
+      if (paren && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN)
        {
-         cpp_get_token (pfile, &token);
-         if (token.type != CPP_CLOSE_PAREN)
-           {
-             cpp_error (pfile, "missing ')' after \"defined\"");
-             node = 0;
-           }
+         cpp_error (pfile, DL_ERROR, "missing ')' after \"defined\"");
+         node = 0;
        }
     }
   else
     {
-      cpp_error (pfile, "operator \"defined\" requires an identifier");
-      if (token.flags & NAMED_OP)
+      cpp_error (pfile, DL_ERROR,
+                "operator \"defined\" requires an identifier");
+      if (token->flags & NAMED_OP)
        {
          cpp_token op;
 
          op.flags = 0;
-         op.type = token.type;
-         cpp_error (pfile,
+         op.type = token->type;
+         cpp_error (pfile, DL_ERROR,
                     "(\"%s\" is an alternative token for \"%s\" in C++)",
-                    cpp_token_as_text (pfile, &token),
+                    cpp_token_as_text (pfile, token),
                     cpp_token_as_text (pfile, &op));
        }
     }
@@ -261,41 +256,37 @@ parse_defined (pfile)
     op.op = CPP_ERROR;
   else
     {
+      if (pfile->context != initial_context)
+       cpp_error (pfile, DL_WARNING,
+                  "this use of \"defined\" may not be portable");
+
       op.value = node->type == NT_MACRO;
       op.unsignedp = 0;
-      op.op = CPP_INT;
+      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--;
   return op;
 }
 
-/* Read one token.  */
-
+/* Read a token.  The returned type is CPP_NUMBER for a valid number
+   (an interpreted preprocessing number or character constant, or the
+   result of the "defined" or "#" operators), CPP_ERROR on error,
+   CPP_EOF, or the type of an operator token.  */
 static struct op
-lex (pfile, skip_evaluation, token)
+lex (pfile, skip_evaluation)
      cpp_reader *pfile;
      int skip_evaluation;
-     cpp_token *token;
 {
   struct op op;
-
-  cpp_get_token (pfile, token);
+  const cpp_token *token = cpp_get_token (pfile);
 
   switch (token->type)
     {
-    case CPP_INT:
     case CPP_NUMBER:
       return parse_number (pfile, token);
 
@@ -304,10 +295,12 @@ lex (pfile, skip_evaluation, token)
       {
        unsigned int chars_seen;
 
-       /* This is always a signed type.  */
-       op.unsignedp = 0;
-       op.op = CPP_INT;
-       op.value = cpp_interpret_charconst (pfile, token, 1, 0, &chars_seen);
+       if (token->type == CPP_CHAR)
+         op.unsignedp = 0;
+       else
+         op.unsignedp = WCHAR_UNSIGNED;
+       op.op = CPP_NUMBER;
+       op.value = cpp_interpret_charconst (pfile, token, 1, &chars_seen);
        return op;
       }
 
@@ -315,9 +308,6 @@ lex (pfile, skip_evaluation, token)
     case CPP_WSTRING:
       SYNTAX_ERROR ("string constants are not valid in #if");
 
-    case CPP_FLOAT:
-      SYNTAX_ERROR ("floating point numbers are not valid in #if");
-
     case CPP_OTHER:
       if (ISGRAPH (token->val.c))
        SYNTAX_ERROR2 ("invalid character '%c' in #if", token->val.c);
@@ -326,17 +316,12 @@ lex (pfile, skip_evaluation, token)
 
     case CPP_NAME:
       if (token->val.node == pfile->spec_nodes.n_defined)
-       {
-         if (pfile->context->prev && CPP_PEDANTIC (pfile))
-           cpp_pedwarn (pfile, "\"defined\" operator appears during macro expansion");
-
-         return parse_defined (pfile);
-       }
+       return parse_defined (pfile);
       else if (CPP_OPTION (pfile, cplusplus)
               && (token->val.node == pfile->spec_nodes.n_true
                   || token->val.node == pfile->spec_nodes.n_false))
        {
-         op.op = CPP_INT;
+         op.op = CPP_NUMBER;
          op.unsignedp = 0;
          op.value = (token->val.node == pfile->spec_nodes.n_true);
 
@@ -344,22 +329,20 @@ lex (pfile, skip_evaluation, token)
             and stdbool.h has not been included.  */
          if (CPP_PEDANTIC (pfile)
              && ! cpp_defined (pfile, DSC("__bool_true_false_are_defined")))
-           cpp_pedwarn (pfile, "ISO C++ does not permit \"%s\" in #if",
-                        token->val.node->name);
+           cpp_error (pfile, DL_PEDWARN,
+                      "ISO C++ does not permit \"%s\" in #if",
+                      NODE_NAME (token->val.node));
          return op;
        }
       else
        {
-         /* Controlling #if expressions cannot contain identifiers (they
-            could become macros in the future).  */
-         pfile->mi_state = MI_FAILED;
-
-         op.op = CPP_INT;
+         op.op = CPP_NUMBER;
          op.unsignedp = 0;
          op.value = 0;
 
          if (CPP_OPTION (pfile, warn_undef) && !skip_evaluation)
-           cpp_warning (pfile, "\"%s\" is not defined", token->val.node->name);
+           cpp_error (pfile, DL_WARNING, "\"%s\" is not defined",
+                      NODE_NAME (token->val.node));
          return op;
        }
 
@@ -367,7 +350,7 @@ lex (pfile, skip_evaluation, token)
       {
        int temp;
 
-       op.op = CPP_INT;
+       op.op = CPP_NUMBER;
        if (_cpp_test_assertion (pfile, &temp))
          op.op = CPP_ERROR;
        op.unsignedp = 0;
@@ -375,11 +358,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)
@@ -398,14 +376,18 @@ lex (pfile, skip_evaluation, token)
   return op;
 }
 
+/* Warn if appropriate on overflow.  */
 static void
 integer_overflow (pfile)
      cpp_reader *pfile;
 {
   if (CPP_PEDANTIC (pfile))
-    cpp_pedwarn (pfile, "integer overflow in preprocessor expression");
+    cpp_error (pfile, DL_PEDWARN,
+              "integer overflow in preprocessor expression");
 }
 
+/* Handle shifting A left by B bits.  UNSIGNEDP is non-zero if A is
+   unsigned.  */
 static HOST_WIDEST_INT
 left_shift (pfile, a, unsignedp, b)
      cpp_reader *pfile;
@@ -430,6 +412,8 @@ left_shift (pfile, a, unsignedp, b)
     }
 }
 
+/* Handle shifting A right by B bits.  UNSIGNEDP is non-zero if A is
+   unsigned.  */
 static HOST_WIDEST_INT
 right_shift (pfile, a, unsignedp, b)
      cpp_reader *pfile ATTRIBUTE_UNUSED;
@@ -478,8 +462,8 @@ be handled with operator-specific code.  */
 #define FLAG_BITS  8
 #define FLAG_MASK ((1 << FLAG_BITS) - 1)
 #define PRIO_SHIFT (FLAG_BITS + 1)
-#define EXTRACT_PRIO(cnst) (cnst >> FLAG_BITS)
-#define EXTRACT_FLAGS(cnst) (cnst & FLAG_MASK)
+#define EXTRACT_PRIO(CNST) ((CNST) >> FLAG_BITS)
+#define EXTRACT_FLAGS(CNST) ((CNST) & FLAG_MASK)
 
 /* Flags.  */
 #define HAVE_VALUE     (1 << 0)
@@ -573,7 +557,6 @@ op_to_prio[] =
 
 /* Parse and evaluate a C expression, reading from PFILE.
    Returns the truth value of the expression.  */
-
 int
 _cpp_parse_expr (pfile)
      cpp_reader *pfile;
@@ -592,14 +575,15 @@ _cpp_parse_expr (pfile)
   struct op init_stack[INIT_STACK_SIZE];
   struct op *stack = init_stack;
   struct op *limit = stack + INIT_STACK_SIZE;
-  cpp_token token;
-  register struct op *top = stack + 1;
+  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;
@@ -615,8 +599,8 @@ _cpp_parse_expr (pfile)
       struct op op;
 
       /* Read a token */
-      op = lex (pfile, skip_evaluation, &token);
-      pfile->mi_lexed++;
+      op = lex (pfile, skip_evaluation);
+      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
@@ -626,7 +610,7 @@ _cpp_parse_expr (pfile)
        case CPP_ERROR:
          goto syntax_error;
        push_immediate:
-       case CPP_INT:
+       case CPP_NUMBER:
          /* Push a value onto the stack.  */
          if (top->flags & HAVE_VALUE)
            SYNTAX_ERROR ("missing binary operator");
@@ -636,6 +620,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 */
@@ -673,8 +662,8 @@ _cpp_parse_expr (pfile)
          switch (top[1].op)
            {
            default:
-             cpp_ice (pfile, "impossible operator '%s'",
-                              op_as_text (pfile, top[1].op));
+             cpp_error (pfile, DL_ICE, "impossible operator '%s'",
+                        op_as_text (pfile, top[1].op));
              goto syntax_error;
 
            case CPP_NOT:        UNARY(!);      break;
@@ -704,7 +693,7 @@ _cpp_parse_expr (pfile)
                  top->flags |= HAVE_VALUE;
 
                  if (CPP_WTRADITIONAL (pfile))
-                   cpp_warning (pfile,
+                   cpp_error (pfile, DL_WARNING,
                        "traditional C rejects the unary plus operator");
                }
              else
@@ -783,7 +772,8 @@ _cpp_parse_expr (pfile)
              break;
            case CPP_COMMA:
              if (CPP_PEDANTIC (pfile))
-               cpp_pedwarn (pfile, "comma operator in operand of #if");
+               cpp_error (pfile, DL_PEDWARN,
+                          "comma operator in operand of #if");
              top->value = v2;
              top->unsignedp = unsigned2;
              break;
@@ -833,13 +823,13 @@ _cpp_parse_expr (pfile)
        {
          if (top->flags & HAVE_VALUE)
            SYNTAX_ERROR2 ("missing binary operator before '%s'",
-                          op_as_text (pfile, top->op));
+                          op_as_text (pfile, op.op));
        }
       else
        {
          if (!(top->flags & HAVE_VALUE))
            SYNTAX_ERROR2 ("operator '%s' has no left operand",
-                          op_as_text (pfile, top->op));
+                          op_as_text (pfile, op.op));
        }
 
       /* Check for and handle stack overflow.  */
@@ -867,9 +857,19 @@ _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");
+    {
+      cpp_error (pfile, DL_ICE, "unbalanced stack in #if");
+      goto syntax_error;
+    }
   else if (!(top[1].flags & HAVE_VALUE))
     {
       SYNTAX_ERROR ("#if with no expression");
@@ -883,6 +883,7 @@ _cpp_parse_expr (pfile)
   return result;
 }
 
+/* Output OP as text for diagnostics.  */
 static const unsigned char *
 op_as_text (pfile, op)
      cpp_reader *pfile;