OSDN Git Service

* config/s390/s390.c (s390_emit_epilogue): Always restore registers
[pf3gnuchains/gcc-fork.git] / gcc / cppexp.c
index 52ffb27..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,50 +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)
 
 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 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 (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;
 
@@ -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,57 +198,56 @@ 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;
 {
   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));
        }
     }
@@ -263,6 +256,10 @@ 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_NUMBER;
@@ -280,16 +277,13 @@ 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, 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)
     {
@@ -301,10 +295,12 @@ lex (pfile, skip_evaluation, token)
       {
        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;
       }
 
@@ -320,12 +316,7 @@ 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))
@@ -338,8 +329,9 @@ 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",
-                        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
@@ -349,8 +341,8 @@ lex (pfile, skip_evaluation, token)
          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;
        }
 
@@ -384,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;
@@ -416,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;
@@ -464,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)
@@ -559,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;
@@ -578,8 +575,7 @@ _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;
@@ -603,7 +599,7 @@ _cpp_parse_expr (pfile)
       struct op op;
 
       /* Read a token */
-      op = lex (pfile, skip_evaluation, &token);
+      op = lex (pfile, skip_evaluation);
       lex_count++;
 
       /* If the token is an operand, push its value and get next
@@ -666,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;
@@ -697,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
@@ -776,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;
@@ -826,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.  */
@@ -869,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");
@@ -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;