OSDN Git Service

* config/stormy16/stormy16.h: Remove DEFAULT_VTABLE_THUNKS.
[pf3gnuchains/gcc-fork.git] / gcc / cppexp.c
index acfa30e..f7fe054 100644 (file)
@@ -36,7 +36,7 @@ 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
@@ -61,32 +61,34 @@ struct op
 #define SYNTAX_ERROR2(msgid, arg) \
   do { cpp_error (pfile, 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 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.  */
+
 static struct op
 parse_number (pfile, tok)
      cpp_reader *pfile;
@@ -127,14 +129,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;
 
@@ -198,7 +195,7 @@ parse_number (pfile, tok)
     }
 
   op.value = n;
-  op.op = CPP_INT;
+  op.op = CPP_NUMBER;
   return op;
 
  invalid_suffix:
@@ -215,44 +212,41 @@ parse_defined (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, "missing ')' after \"defined\"");
+         node = 0;
        }
     }
   else
     {
       cpp_error (pfile, "operator \"defined\" requires an identifier");
-      if (token.flags & NAMED_OP)
+      if (token->flags & NAMED_OP)
        {
          cpp_token op;
 
          op.flags = 0;
-         op.type = token.type;
+         op.type = token->type;
          cpp_error (pfile,
                     "(\"%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 +255,37 @@ parse_defined (pfile)
     op.op = CPP_ERROR;
   else
     {
+      if (pfile->context != initial_context)
+       cpp_warning (pfile, "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);
 
@@ -306,7 +296,7 @@ lex (pfile, skip_evaluation, token)
 
        /* This is always a signed type.  */
        op.unsignedp = 0;
-       op.op = CPP_INT;
+       op.op = CPP_NUMBER;
        op.value = cpp_interpret_charconst (pfile, token, 1, 0, &chars_seen);
        return op;
       }
@@ -315,9 +305,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 +313,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);
 
@@ -345,21 +327,18 @@ lex (pfile, skip_evaluation, token)
          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);
+                        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_warning (pfile, "\"%s\" is not defined",
+                        NODE_NAME (token->val.node));
          return op;
        }
 
@@ -367,7 +346,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 +354,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)
@@ -478,8 +452,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)
@@ -592,14 +566,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 +590,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 +601,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 +611,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 */
@@ -833,13 +813,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,7 +847,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))