OSDN Git Service

* config/s390/s390.c (s390_emit_epilogue): Always restore registers
[pf3gnuchains/gcc-fork.git] / gcc / cppexp.c
index ac222ee..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
@@ -42,9 +42,9 @@ 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,12 +54,10 @@ 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)
 
 struct suffix
 {
@@ -83,21 +81,19 @@ 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 an integer for #if.  Accepts decimal, hex, or
-   octal with or without size suffixes.  Returned op is CPP_ERROR on
-   error, otherwise it is a CPP_NUMBER.  */
 
+/* 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;
@@ -129,14 +125,9 @@ parse_number (pfile, tok)
     {
       c = *p;
 
-      if (ISDIGIT (c))
-       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;
 
@@ -163,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;
        }
 
@@ -179,23 +170,26 @@ 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;
     }
 
@@ -204,13 +198,14 @@ parse_number (pfile, tok)
   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;
@@ -236,20 +231,21 @@ parse_defined (pfile)
       node = token->val.node;
       if (paren && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN)
        {
-         cpp_error (pfile, "missing ')' after \"defined\"");
+         cpp_error (pfile, DL_ERROR, "missing ')' after \"defined\"");
          node = 0;
        }
     }
   else
     {
-      cpp_error (pfile, "operator \"defined\" requires an identifier");
+      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,
+         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, &op));
@@ -261,7 +257,8 @@ parse_defined (pfile)
   else
     {
       if (pfile->context != initial_context)
-       cpp_warning (pfile, "this use of \"defined\" may not be portable");
+       cpp_error (pfile, DL_WARNING,
+                  "this use of \"defined\" may not be portable");
 
       op.value = node->type == NT_MACRO;
       op.unsignedp = 0;
@@ -280,7 +277,6 @@ parse_defined (pfile)
    (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)
      cpp_reader *pfile;
@@ -299,10 +295,12 @@ lex (pfile, skip_evaluation)
       {
        unsigned int chars_seen;
 
-       /* This is always a signed type.  */
-       op.unsignedp = 0;
+       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, 0, &chars_seen);
+       op.value = cpp_interpret_charconst (pfile, token, 1, &chars_seen);
        return op;
       }
 
@@ -331,8 +329,9 @@ lex (pfile, skip_evaluation)
             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",
-                        NODE_NAME (token->val.node));
+           cpp_error (pfile, DL_PEDWARN,
+                      "ISO C++ does not permit \"%s\" in #if",
+                      NODE_NAME (token->val.node));
          return op;
        }
       else
@@ -342,8 +341,8 @@ lex (pfile, skip_evaluation)
          op.value = 0;
 
          if (CPP_OPTION (pfile, warn_undef) && !skip_evaluation)
-           cpp_warning (pfile, "\"%s\" is not defined",
-                        NODE_NAME (token->val.node));
+           cpp_error (pfile, DL_WARNING, "\"%s\" is not defined",
+                      NODE_NAME (token->val.node));
          return op;
        }
 
@@ -377,14 +376,18 @@ lex (pfile, skip_evaluation)
   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;
@@ -409,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;
@@ -552,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;
@@ -658,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;
@@ -689,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
@@ -768,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;
@@ -861,7 +866,10 @@ _cpp_parse_expr (pfile)
   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");
@@ -875,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;