/* Parse C expressions for cpplib.
   Copyright (C) 1987-2016 Free Software Foundation, Inc.
   Contributed by Per Bothner, 1994.

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "cpplib.h"
#include "internal.h"

#define PART_PRECISION (sizeof (cpp_num_part) * CHAR_BIT)
#define HALF_MASK (~(cpp_num_part) 0 >> (PART_PRECISION / 2))
#define LOW_PART(num_part) (num_part & HALF_MASK)
#define HIGH_PART(num_part) (num_part >> (PART_PRECISION / 2))

struct op
{
  const cpp_token *token;	/* The token forming op (for diagnostics).  */
  cpp_num value;		/* The value logically "right" of op.  */
  source_location loc;          /* The location of this value.         */
  enum cpp_ttype op;
};

/* Some simple utility routines on double integers.  */
#define num_zerop(num) ((num.low | num.high) == 0)
#define num_eq(num1, num2) (num1.low == num2.low && num1.high == num2.high)
static bool num_positive (cpp_num, size_t);
static bool num_greater_eq (cpp_num, cpp_num, size_t);
static cpp_num num_trim (cpp_num, size_t);
static cpp_num num_part_mul (cpp_num_part, cpp_num_part);

static cpp_num num_unary_op (cpp_reader *, cpp_num, enum cpp_ttype);
static cpp_num num_binary_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype);
static cpp_num num_negate (cpp_num, size_t);
static cpp_num num_bitwise_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype);
static cpp_num num_inequality_op (cpp_reader *, cpp_num, cpp_num,
				  enum cpp_ttype);
static cpp_num num_equality_op (cpp_reader *, cpp_num, cpp_num,
				enum cpp_ttype);
static cpp_num num_mul (cpp_reader *, cpp_num, cpp_num);
static cpp_num num_div_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype,
			   source_location);
static cpp_num num_lshift (cpp_num, size_t, size_t);
static cpp_num num_rshift (cpp_num, size_t, size_t);

static cpp_num append_digit (cpp_num, int, int, size_t);
static cpp_num parse_defined (cpp_reader *);
static cpp_num eval_token (cpp_reader *, const cpp_token *, source_location);
static struct op *reduce (cpp_reader *, struct op *, enum cpp_ttype);
static unsigned int interpret_float_suffix (cpp_reader *, const uchar *, size_t);
static unsigned int interpret_int_suffix (cpp_reader *, const uchar *, size_t);
static void check_promotion (cpp_reader *, const struct op *);

static cpp_num parse_has_include (cpp_reader *, enum include_type);

/* Token type abuse to create unary plus and minus operators.  */
#define CPP_UPLUS ((enum cpp_ttype) (CPP_LAST_CPP_OP + 1))
#define CPP_UMINUS ((enum cpp_ttype) (CPP_LAST_CPP_OP + 2))

/* With -O2, gcc appears to produce nice code, moving the error
   message load and subsequent jump completely out of the main path.  */
#define SYNTAX_ERROR(msgid) \
  do { cpp_error (pfile, CPP_DL_ERROR, msgid); goto syntax_error; } while(0)
#define SYNTAX_ERROR2(msgid, arg) \
  do { cpp_error (pfile, CPP_DL_ERROR, msgid, arg); goto syntax_error; } \
  while(0)
#define SYNTAX_ERROR_AT(loc, msgid) \
  do { cpp_error_with_line (pfile, CPP_DL_ERROR, (loc), 0, msgid); goto syntax_error; } \
  while(0)
#define SYNTAX_ERROR2_AT(loc, msgid, arg)					\
  do { cpp_error_with_line (pfile, CPP_DL_ERROR, (loc), 0, msgid, arg); goto syntax_error; } \
  while(0)

/* Subroutine of cpp_classify_number.  S points to a float suffix of
   length LEN, possibly zero.  Returns 0 for an invalid suffix, or a
   flag vector describing the suffix.  */
static unsigned int
interpret_float_suffix (cpp_reader *pfile, const uchar *s, size_t len)
{
  size_t flags;
  size_t f, d, l, w, q, i;

  flags = 0;
  f = d = l = w = q = i = 0;

  /* Process decimal float suffixes, which are two letters starting
     with d or D.  Order and case are significant.  */
  if (len == 2 && (*s == 'd' || *s == 'D'))
    {
      bool uppercase = (*s == 'D');
      switch (s[1])
      {
      case 'f': return (!uppercase ? (CPP_N_DFLOAT | CPP_N_SMALL): 0); break;
      case 'F': return (uppercase ? (CPP_N_DFLOAT | CPP_N_SMALL) : 0); break;
      case 'd': return (!uppercase ? (CPP_N_DFLOAT | CPP_N_MEDIUM): 0); break;
      case 'D': return (uppercase ? (CPP_N_DFLOAT | CPP_N_MEDIUM) : 0); break;
      case 'l': return (!uppercase ? (CPP_N_DFLOAT | CPP_N_LARGE) : 0); break;
      case 'L': return (uppercase ? (CPP_N_DFLOAT | CPP_N_LARGE) : 0); break;
      default:
	/* Additional two-character suffixes beginning with D are not
	   for decimal float constants.  */
	break;
      }
    }

  if (CPP_OPTION (pfile, ext_numeric_literals))
    {
      /* Recognize a fixed-point suffix.  */
      if (len != 0)
	switch (s[len-1])
	  {
	  case 'k': case 'K': flags = CPP_N_ACCUM; break;
	  case 'r': case 'R': flags = CPP_N_FRACT; break;
	  default: break;
	  }

      /* Continue processing a fixed-point suffix.  The suffix is case
	 insensitive except for ll or LL.  Order is significant.  */
      if (flags)
	{
	  if (len == 1)
	    return flags;
	  len--;

	  if (*s == 'u' || *s == 'U')
	    {
	      flags |= CPP_N_UNSIGNED;
	      if (len == 1)
		return flags;
	      len--;
	      s++;
            }

	  switch (*s)
	  {
	  case 'h': case 'H':
	    if (len == 1)
	      return flags |= CPP_N_SMALL;
	    break;
	  case 'l':
	    if (len == 1)
	      return flags |= CPP_N_MEDIUM;
	    if (len == 2 && s[1] == 'l')
	      return flags |= CPP_N_LARGE;
	    break;
	  case 'L':
	    if (len == 1)
	      return flags |= CPP_N_MEDIUM;
	    if (len == 2 && s[1] == 'L')
	      return flags |= CPP_N_LARGE;
	    break;
	  default:
	    break;
	  }
	  /* Anything left at this point is invalid.  */
	  return 0;
	}
    }

  /* In any remaining valid suffix, the case and order don't matter.  */
  while (len--)
    switch (s[len])
      {
      case 'f': case 'F': f++; break;
      case 'd': case 'D': d++; break;
      case 'l': case 'L': l++; break;
      case 'w': case 'W': w++; break;
      case 'q': case 'Q': q++; break;
      case 'i': case 'I':
      case 'j': case 'J': i++; break;
      default:
	return 0;
      }

  if (f + d + l + w + q > 1 || i > 1)
    return 0;

  if (i && !CPP_OPTION (pfile, ext_numeric_literals))
    return 0;

  if ((w || q) && !CPP_OPTION (pfile, ext_numeric_literals))
    return 0;

  return ((i ? CPP_N_IMAGINARY : 0)
	  | (f ? CPP_N_SMALL :
	     d ? CPP_N_MEDIUM :
	     l ? CPP_N_LARGE :
	     w ? CPP_N_MD_W :
	     q ? CPP_N_MD_Q : CPP_N_DEFAULT));
}

/* Return the classification flags for a float suffix.  */
unsigned int
cpp_interpret_float_suffix (cpp_reader *pfile, const char *s, size_t len)
{
  return interpret_float_suffix (pfile, (const unsigned char *)s, len);
}

/* Subroutine of cpp_classify_number.  S points to an integer suffix
   of length LEN, possibly zero. Returns 0 for an invalid suffix, or a
   flag vector describing the suffix.  */
static unsigned int
interpret_int_suffix (cpp_reader *pfile, const uchar *s, size_t len)
{
  size_t u, l, i;

  u = l = i = 0;

  while (len--)
    switch (s[len])
      {
      case 'u': case 'U':	u++; break;
      case 'i': case 'I':
      case 'j': case 'J':	i++; break;
      case 'l': case 'L':	l++;
	/* If there are two Ls, they must be adjacent and the same case.  */
	if (l == 2 && s[len] != s[len + 1])
	  return 0;
	break;
      default:
	return 0;
      }

  if (l > 2 || u > 1 || i > 1)
    return 0;

  if (i && !CPP_OPTION (pfile, ext_numeric_literals))
    return 0;

  return ((i ? CPP_N_IMAGINARY : 0)
	  | (u ? CPP_N_UNSIGNED : 0)
	  | ((l == 0) ? CPP_N_SMALL
	     : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE));
}

/* Return the classification flags for an int suffix.  */
unsigned int
cpp_interpret_int_suffix (cpp_reader *pfile, const char *s, size_t len)
{
  return interpret_int_suffix (pfile, (const unsigned char *)s, len);
}

/* Return the string type corresponding to the the input user-defined string
   literal type.  If the input type is not a user-defined string literal
   type return the input type.  */
enum cpp_ttype
cpp_userdef_string_remove_type (enum cpp_ttype type)
{
  if (type == CPP_STRING_USERDEF)
    return CPP_STRING;
  else if (type == CPP_WSTRING_USERDEF)
    return CPP_WSTRING;
  else if (type == CPP_STRING16_USERDEF)
    return CPP_STRING16;
  else if (type == CPP_STRING32_USERDEF)
    return CPP_STRING32;
  else if (type == CPP_UTF8STRING_USERDEF)
    return CPP_UTF8STRING;
  else
    return type;
}

/* Return the user-defined string literal type corresponding to the input
   string type.  If the input type is not a string type return the input
   type.  */
enum cpp_ttype
cpp_userdef_string_add_type (enum cpp_ttype type)
{
  if (type == CPP_STRING)
    return CPP_STRING_USERDEF;
  else if (type == CPP_WSTRING)
    return CPP_WSTRING_USERDEF;
  else if (type == CPP_STRING16)
    return CPP_STRING16_USERDEF;
  else if (type == CPP_STRING32)
    return CPP_STRING32_USERDEF;
  else if (type == CPP_UTF8STRING)
    return CPP_UTF8STRING_USERDEF;
  else
    return type;
}

/* Return the char type corresponding to the the input user-defined char
   literal type.  If the input type is not a user-defined char literal
   type return the input type.  */
enum cpp_ttype
cpp_userdef_char_remove_type (enum cpp_ttype type)
{
  if (type == CPP_CHAR_USERDEF)
    return CPP_CHAR;
  else if (type == CPP_WCHAR_USERDEF)
    return CPP_WCHAR;
  else if (type == CPP_CHAR16_USERDEF)
    return CPP_CHAR16;
  else if (type == CPP_CHAR32_USERDEF)
    return CPP_CHAR32;
  else if (type == CPP_UTF8CHAR_USERDEF)
    return CPP_UTF8CHAR;
  else
    return type;
}

/* Return the user-defined char literal type corresponding to the input
   char type.  If the input type is not a char type return the input
   type.  */
enum cpp_ttype
cpp_userdef_char_add_type (enum cpp_ttype type)
{
  if (type == CPP_CHAR)
    return CPP_CHAR_USERDEF;
  else if (type == CPP_WCHAR)
    return CPP_WCHAR_USERDEF;
  else if (type == CPP_CHAR16)
    return CPP_CHAR16_USERDEF;
  else if (type == CPP_CHAR32)
    return CPP_CHAR32_USERDEF;
  else if (type == CPP_UTF8CHAR)
    return CPP_UTF8CHAR_USERDEF;
  else
    return type;
}

/* Return true if the token type is a user-defined string literal.  */
bool
cpp_userdef_string_p (enum cpp_ttype type)
{
  if (type == CPP_STRING_USERDEF
   || type == CPP_WSTRING_USERDEF
   || type == CPP_STRING16_USERDEF
   || type == CPP_STRING32_USERDEF
   || type == CPP_UTF8STRING_USERDEF)
    return true;
  else
    return false;
}

/* Return true if the token type is a user-defined char literal.  */
bool
cpp_userdef_char_p (enum cpp_ttype type)
{
  if (type == CPP_CHAR_USERDEF
   || type == CPP_WCHAR_USERDEF
   || type == CPP_CHAR16_USERDEF
   || type == CPP_CHAR32_USERDEF
   || type == CPP_UTF8CHAR_USERDEF)
    return true;
  else
    return false;
}

/* Extract the suffix from a user-defined literal string or char.  */
const char *
cpp_get_userdef_suffix (const cpp_token *tok)
{
  unsigned int len = tok->val.str.len;
  const char *text = (const char *)tok->val.str.text;
  char delim;
  unsigned int i;
  for (i = 0; i < len; ++i)
    if (text[i] == '\'' || text[i] == '"')
      break;
  if (i == len)
    return text + len;
  delim = text[i];
  for (i = len; i > 0; --i)
    if (text[i - 1] == delim)
      break;
  return text + i;
}

/* Categorize numeric constants according to their field (integer,
   floating point, or invalid), radix (decimal, octal, hexadecimal),
   and type suffixes.

   TOKEN is the token that represents the numeric constant to
   classify.

   In C++0X if UD_SUFFIX is non null it will be assigned
   any unrecognized suffix for a user-defined literal.

   VIRTUAL_LOCATION is the virtual location for TOKEN.  */
unsigned int
cpp_classify_number (cpp_reader *pfile, const cpp_token *token,
		     const char **ud_suffix, source_location virtual_location)
{
  const uchar *str = token->val.str.text;
  const uchar *limit;
  unsigned int max_digit, result, radix;
  enum {NOT_FLOAT = 0, AFTER_POINT, AFTER_EXPON} float_flag;
  bool seen_digit;
  bool seen_digit_sep;

  if (ud_suffix)
    *ud_suffix = NULL;

  /* If the lexer has done its job, length one can only be a single
     digit.  Fast-path this very common case.  */
  if (token->val.str.len == 1)
    return CPP_N_INTEGER | CPP_N_SMALL | CPP_N_DECIMAL;

  limit = str + token->val.str.len;
  float_flag = NOT_FLOAT;
  max_digit = 0;
  radix = 10;
  seen_digit = false;
  seen_digit_sep = false;

  /* First, interpret the radix.  */
  if (*str == '0')
    {
      radix = 8;
      str++;

      /* Require at least one hex digit to classify it as hex.  */
      if (*str == 'x' || *str == 'X')
	{
	  if (str[1] == '.' || ISXDIGIT (str[1]))
	    {
	      radix = 16;
	      str++;
	    }
	  else if (DIGIT_SEP (str[1]))
	    SYNTAX_ERROR_AT (virtual_location,
			     "digit separator after base indicator");
	}
      else if (*str == 'b' || *str == 'B')
	{
	  if (str[1] == '0' || str[1] == '1')
	    {
	      radix = 2;
	      str++;
	    }
	  else if (DIGIT_SEP (str[1]))
	    SYNTAX_ERROR_AT (virtual_location,
			     "digit separator after base indicator");
	}
    }

  /* Now scan for a well-formed integer or float.  */
  for (;;)
    {
      unsigned int c = *str++;

      if (ISDIGIT (c) || (ISXDIGIT (c) && radix == 16))
	{
	  seen_digit_sep = false;
	  seen_digit = true;
	  c = hex_value (c);
	  if (c > max_digit)
	    max_digit = c;
	}
      else if (DIGIT_SEP (c))
	{
	  if (seen_digit_sep)
	    SYNTAX_ERROR_AT (virtual_location, "adjacent digit separators");
	  seen_digit_sep = true;
	}
      else if (c == '.')
	{
	  if (seen_digit_sep || DIGIT_SEP (*str))
	    SYNTAX_ERROR_AT (virtual_location,
			     "digit separator adjacent to decimal point");
	  seen_digit_sep = false;
	  if (float_flag == NOT_FLOAT)
	    float_flag = AFTER_POINT;
	  else
	    SYNTAX_ERROR_AT (virtual_location,
			     "too many decimal points in number");
	}
      else if ((radix <= 10 && (c == 'e' || c == 'E'))
	       || (radix == 16 && (c == 'p' || c == 'P')))
	{
	  if (seen_digit_sep || DIGIT_SEP (*str))
	    SYNTAX_ERROR_AT (virtual_location,
			     "digit separator adjacent to exponent");
	  float_flag = AFTER_EXPON;
	  break;
	}
      else
	{
	  /* Start of suffix.  */
	  str--;
	  break;
	}
    }

  if (seen_digit_sep && float_flag != AFTER_EXPON)
    SYNTAX_ERROR_AT (virtual_location,
		     "digit separator outside digit sequence");

  /* The suffix may be for decimal fixed-point constants without exponent.  */
  if (radix != 16 && float_flag == NOT_FLOAT)
    {
      result = interpret_float_suffix (pfile, str, limit - str);
      if ((result & CPP_N_FRACT) || (result & CPP_N_ACCUM))
	{
	  result |= CPP_N_FLOATING;
	  /* We need to restore the radix to 10, if the radix is 8.  */
	  if (radix == 8)
	    radix = 10;

	  if (CPP_PEDANTIC (pfile))
	    cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
				 "fixed-point constants are a GCC extension");
	  goto syntax_ok;
	}
      else
	result = 0;
    }

  if (float_flag != NOT_FLOAT && radix == 8)
    radix = 10;

  if (max_digit >= radix)
    {
      if (radix == 2)
	SYNTAX_ERROR2_AT (virtual_location,
			  "invalid digit \"%c\" in binary constant", '0' + max_digit);
      else
	SYNTAX_ERROR2_AT (virtual_location,
			  "invalid digit \"%c\" in octal constant", '0' + max_digit);
    }

  if (float_flag != NOT_FLOAT)
    {
      if (radix == 2)
	{
	  cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0,
			       "invalid prefix \"0b\" for floating constant");
	  return CPP_N_INVALID;
	}

      if (radix == 16 && !seen_digit)
	SYNTAX_ERROR_AT (virtual_location,
			 "no digits in hexadecimal floating constant");

      if (radix == 16 && CPP_PEDANTIC (pfile)
	  && !CPP_OPTION (pfile, extended_numbers))
	{
	  if (CPP_OPTION (pfile, cplusplus))
	    cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
				 "use of C++1z hexadecimal floating constant");
	  else
	    cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
				 "use of C99 hexadecimal floating constant");
	}

      if (float_flag == AFTER_EXPON)
	{
	  if (*str == '+' || *str == '-')
	    str++;

	  /* Exponent is decimal, even if string is a hex float.  */
	  if (!ISDIGIT (*str))
	    {
	      if (DIGIT_SEP (*str))
		SYNTAX_ERROR_AT (virtual_location,
				 "digit separator adjacent to exponent");
	      else
		SYNTAX_ERROR_AT (virtual_location, "exponent has no digits");
	    }
	  do
	    {
	      seen_digit_sep = DIGIT_SEP (*str);
	      str++;
	    }
	  while (ISDIGIT (*str) || DIGIT_SEP (*str));
	}
      else if (radix == 16)
	SYNTAX_ERROR_AT (virtual_location,
			 "hexadecimal floating constants require an exponent");

      if (seen_digit_sep)
	SYNTAX_ERROR_AT (virtual_location,
			 "digit separator outside digit sequence");

      result = interpret_float_suffix (pfile, str, limit - str);
      if (result == 0)
	{
	  if (CPP_OPTION (pfile, user_literals))
	    {
	      if (ud_suffix)
		*ud_suffix = (const char *) str;
	      result = CPP_N_LARGE | CPP_N_USERDEF;
	    }
	  else
	    {
	      cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0,
				   "invalid suffix \"%.*s\" on floating constant",
				   (int) (limit - str), str);
	      return CPP_N_INVALID;
	    }
	}

      /* Traditional C didn't accept any floating suffixes.  */
      if (limit != str
	  && CPP_WTRADITIONAL (pfile)
	  && ! cpp_sys_macro_p (pfile))
	cpp_warning_with_line (pfile, CPP_W_TRADITIONAL, virtual_location, 0,
			       "traditional C rejects the \"%.*s\" suffix",
			       (int) (limit - str), str);

      /* A suffix for double is a GCC extension via decimal float support.
	 If the suffix also specifies an imaginary value we'll catch that
	 later.  */
      if ((result == CPP_N_MEDIUM) && CPP_PEDANTIC (pfile))
	cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
			     "suffix for double constant is a GCC extension");

      /* Radix must be 10 for decimal floats.  */
      if ((result & CPP_N_DFLOAT) && radix != 10)
        {
          cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0,
			       "invalid suffix \"%.*s\" with hexadecimal floating constant",
			       (int) (limit - str), str);
          return CPP_N_INVALID;
        }

      if ((result & (CPP_N_FRACT | CPP_N_ACCUM)) && CPP_PEDANTIC (pfile))
	cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
			     "fixed-point constants are a GCC extension");

      if ((result & CPP_N_DFLOAT) && CPP_PEDANTIC (pfile))
	cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
			     "decimal float constants are a GCC extension");

      result |= CPP_N_FLOATING;
    }
  else
    {
      result = interpret_int_suffix (pfile, str, limit - str);
      if (result == 0)
	{
	  if (CPP_OPTION (pfile, user_literals))
	    {
	      if (ud_suffix)
		*ud_suffix = (const char *) str;
	      result = CPP_N_UNSIGNED | CPP_N_LARGE | CPP_N_USERDEF;
	    }
	  else
	    {
	      cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0,
				   "invalid suffix \"%.*s\" on integer constant",
				   (int) (limit - str), str);
	      return CPP_N_INVALID;
	    }
	}

      /* Traditional C only accepted the 'L' suffix.
         Suppress warning about 'LL' with -Wno-long-long.  */
      if (CPP_WTRADITIONAL (pfile) && ! cpp_sys_macro_p (pfile))
	{
	  int u_or_i = (result & (CPP_N_UNSIGNED|CPP_N_IMAGINARY));
	  int large = (result & CPP_N_WIDTH) == CPP_N_LARGE
		       && CPP_OPTION (pfile, cpp_warn_long_long);

	  if (u_or_i || large)
	    cpp_warning_with_line (pfile, large ? CPP_W_LONG_LONG : CPP_W_TRADITIONAL,
				   virtual_location, 0,
				   "traditional C rejects the \"%.*s\" suffix",
				   (int) (limit - str), str);
	}

      if ((result & CPP_N_WIDTH) == CPP_N_LARGE
	  && CPP_OPTION (pfile, cpp_warn_long_long))
        {
          const char *message = CPP_OPTION (pfile, cplusplus) 
				? N_("use of C++11 long long integer constant")
		                : N_("use of C99 long long integer constant");

	  if (CPP_OPTION (pfile, c99))
            cpp_warning_with_line (pfile, CPP_W_LONG_LONG, virtual_location,
				   0, message);
          else
            cpp_pedwarning_with_line (pfile, CPP_W_LONG_LONG,
				      virtual_location, 0, message);
        }

      result |= CPP_N_INTEGER;
    }

 syntax_ok:
  if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
    cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
			 "imaginary constants are a GCC extension");
  if (radix == 2
      && !CPP_OPTION (pfile, binary_constants)
      && CPP_PEDANTIC (pfile))
    cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
			 CPP_OPTION (pfile, cplusplus)
			 ? N_("binary constants are a C++14 feature "
			      "or GCC extension")
			 : N_("binary constants are a GCC extension"));

  if (radix == 10)
    result |= CPP_N_DECIMAL;
  else if (radix == 16)
    result |= CPP_N_HEX;
  else if (radix == 2)
    result |= CPP_N_BINARY;
  else
    result |= CPP_N_OCTAL;

  return result;

 syntax_error:
  return CPP_N_INVALID;
}

/* cpp_interpret_integer converts an integer constant into a cpp_num,
   of precision options->precision.

   We do not provide any interface for decimal->float conversion,
   because the preprocessor doesn't need it and we don't want to
   drag in GCC's floating point emulator.  */
cpp_num
cpp_interpret_integer (cpp_reader *pfile, const cpp_token *token,
		       unsigned int type)
{
  const uchar *p, *end;
  cpp_num result;

  result.low = 0;
  result.high = 0;
  result.unsignedp = !!(type & CPP_N_UNSIGNED);
  result.overflow = false;

  p = token->val.str.text;
  end = p + token->val.str.len;

  /* Common case of a single digit.  */
  if (token->val.str.len == 1)
    result.low = p[0] - '0';
  else
    {
      cpp_num_part max;
      size_t precision = CPP_OPTION (pfile, precision);
      unsigned int base = 10, c = 0;
      bool overflow = false;

      if ((type & CPP_N_RADIX) == CPP_N_OCTAL)
	{
	  base = 8;
	  p++;
	}
      else if ((type & CPP_N_RADIX) == CPP_N_HEX)
	{
	  base = 16;
	  p += 2;
	}
      else if ((type & CPP_N_RADIX) == CPP_N_BINARY)
	{
	  base = 2;
	  p += 2;
	}

      /* We can add a digit to numbers strictly less than this without
	 needing the precision and slowness of double integers.  */
      max = ~(cpp_num_part) 0;
      if (precision < PART_PRECISION)
	max >>= PART_PRECISION - precision;
      max = (max - base + 1) / base + 1;

      for (; p < end; p++)
	{
	  c = *p;

	  if (ISDIGIT (c) || (base == 16 && ISXDIGIT (c)))
	    c = hex_value (c);
	  else if (DIGIT_SEP (c))
	    continue;
	  else
	    break;

	  /* Strict inequality for when max is set to zero.  */
	  if (result.low < max)
	    result.low = result.low * base + c;
	  else
	    {
	      result = append_digit (result, c, base, precision);
	      overflow |= result.overflow;
	      max = 0;
	    }
	}

      if (overflow && !(type & CPP_N_USERDEF))
	cpp_error (pfile, CPP_DL_PEDWARN,
		   "integer constant is too large for its type");
      /* If too big to be signed, consider it unsigned.  Only warn for
	 decimal numbers.  Traditional numbers were always signed (but
	 we still honor an explicit U suffix); but we only have
	 traditional semantics in directives.  */
      else if (!result.unsignedp
	       && !(CPP_OPTION (pfile, traditional)
		    && pfile->state.in_directive)
	       && !num_positive (result, precision))
	{
	  /* This is for constants within the range of uintmax_t but
	     not that of intmax_t.  For such decimal constants, a
	     diagnostic is required for C99 as the selected type must
	     be signed and not having a type is a constraint violation
	     (DR#298, TC3), so this must be a pedwarn.  For C90,
	     unsigned long is specified to be used for a constant that
	     does not fit in signed long; if uintmax_t has the same
	     range as unsigned long this means only a warning is
	     appropriate here.  C90 permits the preprocessor to use a
	     wider range than unsigned long in the compiler, so if
	     uintmax_t is wider than unsigned long no diagnostic is
	     required for such constants in preprocessor #if
	     expressions and the compiler will pedwarn for such
	     constants outside the range of unsigned long that reach
	     the compiler so a diagnostic is not required there
	     either; thus, pedwarn for C99 but use a plain warning for
	     C90.  */
	  if (base == 10)
	    cpp_error (pfile, (CPP_OPTION (pfile, c99)
			       ? CPP_DL_PEDWARN
			       : CPP_DL_WARNING),
		       "integer constant is so large that it is unsigned");
	  result.unsignedp = true;
	}
    }

  return result;
}

/* Append DIGIT to NUM, a number of PRECISION bits being read in base BASE.  */
static cpp_num
append_digit (cpp_num num, int digit, int base, size_t precision)
{
  cpp_num result;
  unsigned int shift;
  bool overflow;
  cpp_num_part add_high, add_low;

  /* Multiply by 2, 8 or 16.  Catching this overflow here means we don't
     need to worry about add_high overflowing.  */
  switch (base)
    {
    case 2:
      shift = 1;
      break;

    case 16:
      shift = 4;
      break;

    default:
      shift = 3;
    }
  overflow = !!(num.high >> (PART_PRECISION - shift));
  result.high = num.high << shift;
  result.low = num.low << shift;
  result.high |= num.low >> (PART_PRECISION - shift);
  result.unsignedp = num.unsignedp;

  if (base == 10)
    {
      add_low = num.low << 1;
      add_high = (num.high << 1) + (num.low >> (PART_PRECISION - 1));
    }
  else
    add_high = add_low = 0;

  if (add_low + digit < add_low)
    add_high++;
  add_low += digit;

  if (result.low + add_low < result.low)
    add_high++;
  if (result.high + add_high < result.high)
    overflow = true;

  result.low += add_low;
  result.high += add_high;
  result.overflow = overflow;

  /* The above code catches overflow of a cpp_num type.  This catches
     overflow of the (possibly shorter) target precision.  */
  num.low = result.low;
  num.high = result.high;
  result = num_trim (result, precision);
  if (!num_eq (result, num))
    result.overflow = true;

  return result;
}

/* Handle meeting "defined" in a preprocessor expression.  */
static cpp_num
parse_defined (cpp_reader *pfile)
{
  cpp_num result;
  int paren = 0;
  cpp_hashnode *node = 0;
  const cpp_token *token;
  cpp_context *initial_context = pfile->context;

  /* Don't expand macros.  */
  pfile->state.prevent_expansion++;

  token = cpp_get_token (pfile);
  if (token->type == CPP_OPEN_PAREN)
    {
      paren = 1;
      token = cpp_get_token (pfile);
    }

  if (token->type == CPP_NAME)
    {
      node = token->val.node.node;
      if (paren && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN)
	{
	  cpp_error (pfile, CPP_DL_ERROR, "missing ')' after \"defined\"");
	  node = 0;
	}
    }
  else
    {
      cpp_error (pfile, CPP_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_DL_ERROR,
		     "(\"%s\" is an alternative token for \"%s\" in C++)",
		     cpp_token_as_text (pfile, token),
		     cpp_token_as_text (pfile, &op));
	}
    }

  if (node)
    {
      if (pfile->context != initial_context && CPP_PEDANTIC (pfile))
	cpp_error (pfile, CPP_DL_WARNING,
		   "this use of \"defined\" may not be portable");

      _cpp_mark_macro_used (node);
      if (!(node->flags & NODE_USED))
	{
	  node->flags |= NODE_USED;
	  if (node->type == NT_MACRO)
	    {
	      if ((node->flags & NODE_BUILTIN)
		  && pfile->cb.user_builtin_macro)
		pfile->cb.user_builtin_macro (pfile, node);
	      if (pfile->cb.used_define)
		pfile->cb.used_define (pfile, pfile->directive_line, node);
	    }
	  else
	    {
	      if (pfile->cb.used_undef)
		pfile->cb.used_undef (pfile, pfile->directive_line, node);
	    }
	}

      /* 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--;

  /* Do not treat conditional macros as being defined.  This is due to the
     powerpc and spu ports using conditional macros for 'vector', 'bool', and
     'pixel' to act as conditional keywords.  This messes up tests like #ifndef
     bool.  */
  result.unsignedp = false;
  result.high = 0;
  result.overflow = false;
  result.low = (node && node->type == NT_MACRO
		&& (node->flags & NODE_CONDITIONAL) == 0);
  return result;
}

/* Convert a token into a CPP_NUMBER (an interpreted preprocessing
   number or character constant, or the result of the "defined" or "#"
   operators).  */
static cpp_num
eval_token (cpp_reader *pfile, const cpp_token *token,
	    source_location virtual_location)
{
  cpp_num result;
  unsigned int temp;
  int unsignedp = 0;

  result.unsignedp = false;
  result.overflow = false;

  switch (token->type)
    {
    case CPP_NUMBER:
      temp = cpp_classify_number (pfile, token, NULL, virtual_location);
      if (temp & CPP_N_USERDEF)
	cpp_error (pfile, CPP_DL_ERROR,
		   "user-defined literal in preprocessor expression");
      switch (temp & CPP_N_CATEGORY)
	{
	case CPP_N_FLOATING:
	  cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0,
			       "floating constant in preprocessor expression");
	  break;
	case CPP_N_INTEGER:
	  if (!(temp & CPP_N_IMAGINARY))
	    return cpp_interpret_integer (pfile, token, temp);
	  cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0,
			       "imaginary number in preprocessor expression");
	  break;

	case CPP_N_INVALID:
	  /* Error already issued.  */
	  break;
	}
      result.high = result.low = 0;
      break;

    case CPP_WCHAR:
    case CPP_CHAR:
    case CPP_CHAR16:
    case CPP_CHAR32:
    case CPP_UTF8CHAR:
      {
	cppchar_t cc = cpp_interpret_charconst (pfile, token,
						&temp, &unsignedp);

	result.high = 0;
	result.low = cc;
	/* Sign-extend the result if necessary.  */
	if (!unsignedp && (cppchar_signed_t) cc < 0)
	  {
	    if (PART_PRECISION > BITS_PER_CPPCHAR_T)
	      result.low |= ~(~(cpp_num_part) 0
			      >> (PART_PRECISION - BITS_PER_CPPCHAR_T));
	    result.high = ~(cpp_num_part) 0;
	    result = num_trim (result, CPP_OPTION (pfile, precision));
	  }
      }
      break;

    case CPP_NAME:
      if (token->val.node.node == pfile->spec_nodes.n_defined)
	return parse_defined (pfile);
      else if (token->val.node.node == pfile->spec_nodes.n__has_include__)
	return parse_has_include (pfile, IT_INCLUDE);
      else if (token->val.node.node == pfile->spec_nodes.n__has_include_next__)
	return parse_has_include (pfile, IT_INCLUDE_NEXT);
      else if (CPP_OPTION (pfile, cplusplus)
	       && (token->val.node.node == pfile->spec_nodes.n_true
		   || token->val.node.node == pfile->spec_nodes.n_false))
	{
	  result.high = 0;
	  result.low = (token->val.node.node == pfile->spec_nodes.n_true);
	}
      else
	{
	  result.high = 0;
	  result.low = 0;
	  if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval)
	    cpp_warning_with_line (pfile, CPP_W_UNDEF, virtual_location, 0,
				   "\"%s\" is not defined",
				   NODE_NAME (token->val.node.node));
	}
      break;

    case CPP_HASH:
      if (!pfile->state.skipping)
	{
	  /* A pedantic warning takes precedence over a deprecated
	     warning here.  */
	  if (CPP_PEDANTIC (pfile))
	    cpp_error_with_line (pfile, CPP_DL_PEDWARN,
				 virtual_location, 0,
				 "assertions are a GCC extension");
	  else if (CPP_OPTION (pfile, cpp_warn_deprecated))
	    cpp_warning_with_line (pfile, CPP_W_DEPRECATED, virtual_location, 0,
				   "assertions are a deprecated extension");
	}
      _cpp_test_assertion (pfile, &temp);
      result.high = 0;
      result.low = temp;
      break;

    default:
      abort ();
    }

  result.unsignedp = !!unsignedp;
  return result;
}

/* Operator precedence and flags table.

After an operator is returned from the lexer, if it has priority less
than the operator on the top of the stack, we reduce the stack by one
operator and repeat the test.  Since equal priorities do not reduce,
this is naturally right-associative.

We handle left-associative operators by decrementing the priority of
just-lexed operators by one, but retaining the priority of operators
already on the stack.

The remaining cases are '(' and ')'.  We handle '(' by skipping the
reduction phase completely.  ')' is given lower priority than
everything else, including '(', effectively forcing a reduction of the
parenthesized expression.  If there is a matching '(', the routine
reduce() exits immediately.  If the normal exit route sees a ')', then
there cannot have been a matching '(' and an error message is output.

The parser assumes all shifted operators require a left operand unless
the flag NO_L_OPERAND is set.  These semantics are automatic; any
extra semantics need to be handled with operator-specific code.  */

/* Flags.  If CHECK_PROMOTION, we warn if the effective sign of an
   operand changes because of integer promotions.  */
#define NO_L_OPERAND	(1 << 0)
#define LEFT_ASSOC	(1 << 1)
#define CHECK_PROMOTION	(1 << 2)

/* Operator to priority map.  Must be in the same order as the first
   N entries of enum cpp_ttype.  */
static const struct cpp_operator
{
  uchar prio;
  uchar flags;
} optab[] =
{
  /* EQ */		{0, 0},	/* Shouldn't happen.  */
  /* NOT */		{16, NO_L_OPERAND},
  /* GREATER */		{12, LEFT_ASSOC | CHECK_PROMOTION},
  /* LESS */		{12, LEFT_ASSOC | CHECK_PROMOTION},
  /* PLUS */		{14, LEFT_ASSOC | CHECK_PROMOTION},
  /* MINUS */		{14, LEFT_ASSOC | CHECK_PROMOTION},
  /* MULT */		{15, LEFT_ASSOC | CHECK_PROMOTION},
  /* DIV */		{15, LEFT_ASSOC | CHECK_PROMOTION},
  /* MOD */		{15, LEFT_ASSOC | CHECK_PROMOTION},
  /* AND */		{9, LEFT_ASSOC | CHECK_PROMOTION},
  /* OR */		{7, LEFT_ASSOC | CHECK_PROMOTION},
  /* XOR */		{8, LEFT_ASSOC | CHECK_PROMOTION},
  /* RSHIFT */		{13, LEFT_ASSOC},
  /* LSHIFT */		{13, LEFT_ASSOC},

  /* COMPL */		{16, NO_L_OPERAND},
  /* AND_AND */		{6, LEFT_ASSOC},
  /* OR_OR */		{5, LEFT_ASSOC},
  /* Note that QUERY, COLON, and COMMA must have the same precedence.
     However, there are some special cases for these in reduce().  */
  /* QUERY */		{4, 0},
  /* COLON */		{4, LEFT_ASSOC | CHECK_PROMOTION},
  /* COMMA */		{4, LEFT_ASSOC},
  /* OPEN_PAREN */	{1, NO_L_OPERAND},
  /* CLOSE_PAREN */	{0, 0},
  /* EOF */		{0, 0},
  /* EQ_EQ */		{11, LEFT_ASSOC},
  /* NOT_EQ */		{11, LEFT_ASSOC},
  /* GREATER_EQ */	{12, LEFT_ASSOC | CHECK_PROMOTION},
  /* LESS_EQ */		{12, LEFT_ASSOC | CHECK_PROMOTION},
  /* UPLUS */		{16, NO_L_OPERAND},
  /* UMINUS */		{16, NO_L_OPERAND}
};

/* Parse and evaluate a C expression, reading from PFILE.
   Returns the truth value of the expression.

   The implementation is an operator precedence parser, i.e. a
   bottom-up parser, using a stack for not-yet-reduced tokens.

   The stack base is op_stack, and the current stack pointer is 'top'.
   There is a stack element for each operator (only), and the most
   recently pushed operator is 'top->op'.  An operand (value) is
   stored in the 'value' field of the stack element of the operator
   that precedes it.  */
bool
_cpp_parse_expr (cpp_reader *pfile, bool is_if)
{
  struct op *top = pfile->op_stack;
  unsigned int lex_count;
  bool saw_leading_not, want_value = true;
  source_location virtual_location = 0;

  pfile->state.skip_eval = 0;

  /* Set up detection of #if ! defined().  */
  pfile->mi_ind_cmacro = 0;
  saw_leading_not = false;
  lex_count = 0;

  /* Lowest priority operator prevents further reductions.  */
  top->op = CPP_EOF;

  for (;;)
    {
      struct op op;

      lex_count++;
      op.token = cpp_get_token_with_location (pfile, &virtual_location);
      op.op = op.token->type;
      op.loc = virtual_location;

      switch (op.op)
	{
	  /* These tokens convert into values.  */
	case CPP_NUMBER:
	case CPP_CHAR:
	case CPP_WCHAR:
	case CPP_CHAR16:
	case CPP_CHAR32:
	case CPP_UTF8CHAR:
	case CPP_NAME:
	case CPP_HASH:
	  if (!want_value)
	    SYNTAX_ERROR2_AT (op.loc,
			      "missing binary operator before token \"%s\"",
			      cpp_token_as_text (pfile, op.token));
	  want_value = false;
	  top->value = eval_token (pfile, op.token, op.loc);
	  continue;

	case CPP_NOT:
	  saw_leading_not = lex_count == 1;
	  break;
	case CPP_PLUS:
	  if (want_value)
	    op.op = CPP_UPLUS;
	  break;
	case CPP_MINUS:
	  if (want_value)
	    op.op = CPP_UMINUS;
	  break;

	default:
	  if ((int) op.op <= (int) CPP_EQ || (int) op.op >= (int) CPP_PLUS_EQ)
	    SYNTAX_ERROR2_AT (op.loc,
			      "token \"%s\" is not valid in preprocessor expressions",
			      cpp_token_as_text (pfile, op.token));
	  break;
	}

      /* Check we have a value or operator as appropriate.  */
      if (optab[op.op].flags & NO_L_OPERAND)
	{
	  if (!want_value)
	    SYNTAX_ERROR2_AT (op.loc,
			      "missing binary operator before token \"%s\"",
			      cpp_token_as_text (pfile, op.token));
	}
      else if (want_value)
	{
	  /* We want a number (or expression) and haven't got one.
	     Try to emit a specific diagnostic.  */
	  if (op.op == CPP_CLOSE_PAREN && top->op == CPP_OPEN_PAREN)
	    SYNTAX_ERROR_AT (op.loc,
			     "missing expression between '(' and ')'");

	  if (op.op == CPP_EOF && top->op == CPP_EOF)
 	    SYNTAX_ERROR2_AT (op.loc,
			      "%s with no expression", is_if ? "#if" : "#elif");

 	  if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN)
 	    SYNTAX_ERROR2_AT (op.loc,
			      "operator '%s' has no right operand",
			      cpp_token_as_text (pfile, top->token));
	  else if (op.op == CPP_CLOSE_PAREN || op.op == CPP_EOF)
	    /* Complain about missing paren during reduction.  */;
	  else
	    SYNTAX_ERROR2_AT (op.loc,
			      "operator '%s' has no left operand",
			      cpp_token_as_text (pfile, op.token));
	}

      top = reduce (pfile, top, op.op);
      if (!top)
	goto syntax_error;

      if (op.op == CPP_EOF)
	break;

      switch (op.op)
	{
	case CPP_CLOSE_PAREN:
	  continue;
	case CPP_OR_OR:
	  if (!num_zerop (top->value))
	    pfile->state.skip_eval++;
	  break;
	case CPP_AND_AND:
	case CPP_QUERY:
	  if (num_zerop (top->value))
	    pfile->state.skip_eval++;
	  break;
	case CPP_COLON:
	  if (top->op != CPP_QUERY)
	    SYNTAX_ERROR_AT (op.loc,
			     " ':' without preceding '?'");
	  if (!num_zerop (top[-1].value)) /* Was '?' condition true?  */
	    pfile->state.skip_eval++;
	  else
	    pfile->state.skip_eval--;
	default:
	  break;
	}

      want_value = true;

      /* Check for and handle stack overflow.  */
      if (++top == pfile->op_limit)
	top = _cpp_expand_op_stack (pfile);

      top->op = op.op;
      top->token = op.token;
      top->loc = op.loc;
    }

  /* 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;

  if (top != pfile->op_stack)
    {
      cpp_error_with_line (pfile, CPP_DL_ICE, top->loc, 0,
			   "unbalanced stack in %s",
			   is_if ? "#if" : "#elif");
    syntax_error:
      return false;  /* Return false on syntax error.  */
    }

  return !num_zerop (top->value);
}

/* Reduce the operator / value stack if possible, in preparation for
   pushing operator OP.  Returns NULL on error, otherwise the top of
   the stack.  */
static struct op *
reduce (cpp_reader *pfile, struct op *top, enum cpp_ttype op)
{
  unsigned int prio;

  if (top->op <= CPP_EQ || top->op > CPP_LAST_CPP_OP + 2)
    {
    bad_op:
      cpp_error (pfile, CPP_DL_ICE, "impossible operator '%u'", top->op);
      return 0;
    }

  if (op == CPP_OPEN_PAREN)
    return top;

  /* Decrement the priority of left-associative operators to force a
     reduction with operators of otherwise equal priority.  */
  prio = optab[op].prio - ((optab[op].flags & LEFT_ASSOC) != 0);
  while (prio < optab[top->op].prio)
    {
      if (CPP_OPTION (pfile, warn_num_sign_change)
	  && optab[top->op].flags & CHECK_PROMOTION)
	check_promotion (pfile, top);

      switch (top->op)
	{
	case CPP_UPLUS:
	case CPP_UMINUS:
	case CPP_NOT:
	case CPP_COMPL:
	  top[-1].value = num_unary_op (pfile, top->value, top->op);
	  top[-1].loc = top->loc;
	  break;

	case CPP_PLUS:
	case CPP_MINUS:
	case CPP_RSHIFT:
	case CPP_LSHIFT:
	case CPP_COMMA:
	  top[-1].value = num_binary_op (pfile, top[-1].value,
					 top->value, top->op);
	  top[-1].loc = top->loc;
	  break;

	case CPP_GREATER:
	case CPP_LESS:
	case CPP_GREATER_EQ:
	case CPP_LESS_EQ:
	  top[-1].value
	    = num_inequality_op (pfile, top[-1].value, top->value, top->op);
	  top[-1].loc = top->loc;
	  break;

	case CPP_EQ_EQ:
	case CPP_NOT_EQ:
	  top[-1].value
	    = num_equality_op (pfile, top[-1].value, top->value, top->op);
	  top[-1].loc = top->loc;
	  break;

	case CPP_AND:
	case CPP_OR:
	case CPP_XOR:
	  top[-1].value
	    = num_bitwise_op (pfile, top[-1].value, top->value, top->op);
	  top[-1].loc = top->loc;
	  break;

	case CPP_MULT:
	  top[-1].value = num_mul (pfile, top[-1].value, top->value);
	  top[-1].loc = top->loc;
	  break;

	case CPP_DIV:
	case CPP_MOD:
	  top[-1].value = num_div_op (pfile, top[-1].value,
				      top->value, top->op, top->loc);
	  top[-1].loc = top->loc;
	  break;

	case CPP_OR_OR:
	  top--;
	  if (!num_zerop (top->value))
	    pfile->state.skip_eval--;
	  top->value.low = (!num_zerop (top->value)
			    || !num_zerop (top[1].value));
	  top->value.high = 0;
	  top->value.unsignedp = false;
	  top->value.overflow = false;
	  top->loc = top[1].loc;
	  continue;

	case CPP_AND_AND:
	  top--;
	  if (num_zerop (top->value))
	    pfile->state.skip_eval--;
	  top->value.low = (!num_zerop (top->value)
			    && !num_zerop (top[1].value));
	  top->value.high = 0;
	  top->value.unsignedp = false;
	  top->value.overflow = false;
	  top->loc = top[1].loc;
	  continue;

	case CPP_OPEN_PAREN:
	  if (op != CPP_CLOSE_PAREN)
	    {
	      cpp_error_with_line (pfile, CPP_DL_ERROR, 
				   top->token->src_loc,
				   0, "missing ')' in expression");
	      return 0;
	    }
	  top--;
	  top->value = top[1].value;
	  top->loc = top[1].loc;
	  return top;

	case CPP_COLON:
	  top -= 2;
	  if (!num_zerop (top->value))
	    {
	      pfile->state.skip_eval--;
	      top->value = top[1].value;
	      top->loc = top[1].loc;
	    }
	  else
	    {
	      top->value = top[2].value;
	      top->loc = top[2].loc;
	    }
	  top->value.unsignedp = (top[1].value.unsignedp
				  || top[2].value.unsignedp);
	  continue;

	case CPP_QUERY:
	  /* COMMA and COLON should not reduce a QUERY operator.  */
	  if (op == CPP_COMMA || op == CPP_COLON)
	    return top;
	  cpp_error (pfile, CPP_DL_ERROR, "'?' without following ':'");
	  return 0;

	default:
	  goto bad_op;
	}

      top--;
      if (top->value.overflow && !pfile->state.skip_eval)
	cpp_error (pfile, CPP_DL_PEDWARN,
		   "integer overflow in preprocessor expression");
    }

  if (op == CPP_CLOSE_PAREN)
    {
      cpp_error (pfile, CPP_DL_ERROR, "missing '(' in expression");
      return 0;
    }

  return top;
}

/* Returns the position of the old top of stack after expansion.  */
struct op *
_cpp_expand_op_stack (cpp_reader *pfile)
{
  size_t old_size = (size_t) (pfile->op_limit - pfile->op_stack);
  size_t new_size = old_size * 2 + 20;

  pfile->op_stack = XRESIZEVEC (struct op, pfile->op_stack, new_size);
  pfile->op_limit = pfile->op_stack + new_size;

  return pfile->op_stack + old_size;
}

/* Emits a warning if the effective sign of either operand of OP
   changes because of integer promotions.  */
static void
check_promotion (cpp_reader *pfile, const struct op *op)
{
  if (op->value.unsignedp == op[-1].value.unsignedp)
    return;

  if (op->value.unsignedp)
    {
      if (!num_positive (op[-1].value, CPP_OPTION (pfile, precision)))
	cpp_error_with_line (pfile, CPP_DL_WARNING, op[-1].loc, 0,
			     "the left operand of \"%s\" changes sign when promoted",
			     cpp_token_as_text (pfile, op->token));
    }
  else if (!num_positive (op->value, CPP_OPTION (pfile, precision)))
    cpp_error_with_line (pfile, CPP_DL_WARNING, op->loc, 0,
	       "the right operand of \"%s\" changes sign when promoted",
	       cpp_token_as_text (pfile, op->token));
}

/* Clears the unused high order bits of the number pointed to by PNUM.  */
static cpp_num
num_trim (cpp_num num, size_t precision)
{
  if (precision > PART_PRECISION)
    {
      precision -= PART_PRECISION;
      if (precision < PART_PRECISION)
	num.high &= ((cpp_num_part) 1 << precision) - 1;
    }
  else
    {
      if (precision < PART_PRECISION)
	num.low &= ((cpp_num_part) 1 << precision) - 1;
      num.high = 0;
    }

  return num;
}

/* True iff A (presumed signed) >= 0.  */
static bool
num_positive (cpp_num num, size_t precision)
{
  if (precision > PART_PRECISION)
    {
      precision -= PART_PRECISION;
      return (num.high & (cpp_num_part) 1 << (precision - 1)) == 0;
    }

  return (num.low & (cpp_num_part) 1 << (precision - 1)) == 0;
}

/* Sign extend a number, with PRECISION significant bits and all
   others assumed clear, to fill out a cpp_num structure.  */
cpp_num
cpp_num_sign_extend (cpp_num num, size_t precision)
{
  if (!num.unsignedp)
    {
      if (precision > PART_PRECISION)
	{
	  precision -= PART_PRECISION;
	  if (precision < PART_PRECISION
	      && (num.high & (cpp_num_part) 1 << (precision - 1)))
	    num.high |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision));
	}
      else if (num.low & (cpp_num_part) 1 << (precision - 1))
	{
	  if (precision < PART_PRECISION)
	    num.low |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision));
	  num.high = ~(cpp_num_part) 0;
	}
    }

  return num;
}

/* Returns the negative of NUM.  */
static cpp_num
num_negate (cpp_num num, size_t precision)
{
  cpp_num copy;

  copy = num;
  num.high = ~num.high;
  num.low = ~num.low;
  if (++num.low == 0)
    num.high++;
  num = num_trim (num, precision);
  num.overflow = (!num.unsignedp && num_eq (num, copy) && !num_zerop (num));

  return num;
}

/* Returns true if A >= B.  */
static bool
num_greater_eq (cpp_num pa, cpp_num pb, size_t precision)
{
  bool unsignedp;

  unsignedp = pa.unsignedp || pb.unsignedp;

  if (!unsignedp)
    {
      /* Both numbers have signed type.  If they are of different
       sign, the answer is the sign of A.  */
      unsignedp = num_positive (pa, precision);

      if (unsignedp != num_positive (pb, precision))
	return unsignedp;

      /* Otherwise we can do an unsigned comparison.  */
    }

  return (pa.high > pb.high) || (pa.high == pb.high && pa.low >= pb.low);
}

/* Returns LHS OP RHS, where OP is a bit-wise operation.  */
static cpp_num
num_bitwise_op (cpp_reader *pfile ATTRIBUTE_UNUSED,
		cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
{
  lhs.overflow = false;
  lhs.unsignedp = lhs.unsignedp || rhs.unsignedp;

  /* As excess precision is zeroed, there is no need to num_trim () as
     these operations cannot introduce a set bit there.  */
  if (op == CPP_AND)
    {
      lhs.low &= rhs.low;
      lhs.high &= rhs.high;
    }
  else if (op == CPP_OR)
    {
      lhs.low |= rhs.low;
      lhs.high |= rhs.high;
    }
  else
    {
      lhs.low ^= rhs.low;
      lhs.high ^= rhs.high;
    }

  return lhs;
}

/* Returns LHS OP RHS, where OP is an inequality.  */
static cpp_num
num_inequality_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs,
		   enum cpp_ttype op)
{
  bool gte = num_greater_eq (lhs, rhs, CPP_OPTION (pfile, precision));

  if (op == CPP_GREATER_EQ)
    lhs.low = gte;
  else if (op == CPP_LESS)
    lhs.low = !gte;
  else if (op == CPP_GREATER)
    lhs.low = gte && !num_eq (lhs, rhs);
  else /* CPP_LESS_EQ.  */
    lhs.low = !gte || num_eq (lhs, rhs);

  lhs.high = 0;
  lhs.overflow = false;
  lhs.unsignedp = false;
  return lhs;
}

/* Returns LHS OP RHS, where OP is == or !=.  */
static cpp_num
num_equality_op (cpp_reader *pfile ATTRIBUTE_UNUSED,
		 cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
{
  /* Work around a 3.0.4 bug; see PR 6950.  */
  bool eq = num_eq (lhs, rhs);
  if (op == CPP_NOT_EQ)
    eq = !eq;
  lhs.low = eq;
  lhs.high = 0;
  lhs.overflow = false;
  lhs.unsignedp = false;
  return lhs;
}

/* Shift NUM, of width PRECISION, right by N bits.  */
static cpp_num
num_rshift (cpp_num num, size_t precision, size_t n)
{
  cpp_num_part sign_mask;
  bool x = num_positive (num, precision);

  if (num.unsignedp || x)
    sign_mask = 0;
  else
    sign_mask = ~(cpp_num_part) 0;

  if (n >= precision)
    num.high = num.low = sign_mask;
  else
    {
      /* Sign-extend.  */
      if (precision < PART_PRECISION)
	num.high = sign_mask, num.low |= sign_mask << precision;
      else if (precision < 2 * PART_PRECISION)
	num.high |= sign_mask << (precision - PART_PRECISION);

      if (n >= PART_PRECISION)
	{
	  n -= PART_PRECISION;
	  num.low = num.high;
	  num.high = sign_mask;
	}

      if (n)
	{
	  num.low = (num.low >> n) | (num.high << (PART_PRECISION - n));
	  num.high = (num.high >> n) | (sign_mask << (PART_PRECISION - n));
	}
    }

  num = num_trim (num, precision);
  num.overflow = false;
  return num;
}

/* Shift NUM, of width PRECISION, left by N bits.  */
static cpp_num
num_lshift (cpp_num num, size_t precision, size_t n)
{
  if (n >= precision)
    {
      num.overflow = !num.unsignedp && !num_zerop (num);
      num.high = num.low = 0;
    }
  else
    {
      cpp_num orig, maybe_orig;
      size_t m = n;

      orig = num;
      if (m >= PART_PRECISION)
	{
	  m -= PART_PRECISION;
	  num.high = num.low;
	  num.low = 0;
	}
      if (m)
	{
	  num.high = (num.high << m) | (num.low >> (PART_PRECISION - m));
	  num.low <<= m;
	}
      num = num_trim (num, precision);

      if (num.unsignedp)
	num.overflow = false;
      else
	{
	  maybe_orig = num_rshift (num, precision, n);
	  num.overflow = !num_eq (orig, maybe_orig);
	}
    }

  return num;
}

/* The four unary operators: +, -, ! and ~.  */
static cpp_num
num_unary_op (cpp_reader *pfile, cpp_num num, enum cpp_ttype op)
{
  switch (op)
    {
    case CPP_UPLUS:
      if (CPP_WTRADITIONAL (pfile) && !pfile->state.skip_eval)
	cpp_warning (pfile, CPP_W_TRADITIONAL,
		     "traditional C rejects the unary plus operator");
      num.overflow = false;
      break;

    case CPP_UMINUS:
      num = num_negate (num, CPP_OPTION (pfile, precision));
      break;

    case CPP_COMPL:
      num.high = ~num.high;
      num.low = ~num.low;
      num = num_trim (num, CPP_OPTION (pfile, precision));
      num.overflow = false;
      break;

    default: /* case CPP_NOT: */
      num.low = num_zerop (num);
      num.high = 0;
      num.overflow = false;
      num.unsignedp = false;
      break;
    }

  return num;
}

/* The various binary operators.  */
static cpp_num
num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
{
  cpp_num result;
  size_t precision = CPP_OPTION (pfile, precision);
  size_t n;

  switch (op)
    {
      /* Shifts.  */
    case CPP_LSHIFT:
    case CPP_RSHIFT:
      if (!rhs.unsignedp && !num_positive (rhs, precision))
	{
	  /* A negative shift is a positive shift the other way.  */
	  if (op == CPP_LSHIFT)
	    op = CPP_RSHIFT;
	  else
	    op = CPP_LSHIFT;
	  rhs = num_negate (rhs, precision);
	}
      if (rhs.high)
	n = ~0;			/* Maximal.  */
      else
	n = rhs.low;
      if (op == CPP_LSHIFT)
	lhs = num_lshift (lhs, precision, n);
      else
	lhs = num_rshift (lhs, precision, n);
      break;

      /* Arithmetic.  */
    case CPP_MINUS:
      result.low = lhs.low - rhs.low;
      result.high = lhs.high - rhs.high;
      if (result.low > lhs.low)
	result.high--;
      result.unsignedp = lhs.unsignedp || rhs.unsignedp;
      result.overflow = false;

      result = num_trim (result, precision);
      if (!result.unsignedp)
	{
	  bool lhsp = num_positive (lhs, precision);
	  result.overflow = (lhsp != num_positive (rhs, precision)
			     && lhsp != num_positive (result, precision));
	}
      return result;

    case CPP_PLUS:
      result.low = lhs.low + rhs.low;
      result.high = lhs.high + rhs.high;
      if (result.low < lhs.low)
	result.high++;
      result.unsignedp = lhs.unsignedp || rhs.unsignedp;
      result.overflow = false;

      result = num_trim (result, precision);
      if (!result.unsignedp)
	{
	  bool lhsp = num_positive (lhs, precision);
	  result.overflow = (lhsp == num_positive (rhs, precision)
			     && lhsp != num_positive (result, precision));
	}
      return result;

      /* Comma.  */
    default: /* case CPP_COMMA: */
      if (CPP_PEDANTIC (pfile) && (!CPP_OPTION (pfile, c99)
				   || !pfile->state.skip_eval))
	cpp_pedwarning (pfile, CPP_W_PEDANTIC,
			"comma operator in operand of #if");
      lhs = rhs;
      break;
    }

  return lhs;
}

/* Multiplies two unsigned cpp_num_parts to give a cpp_num.  This
   cannot overflow.  */
static cpp_num
num_part_mul (cpp_num_part lhs, cpp_num_part rhs)
{
  cpp_num result;
  cpp_num_part middle[2], temp;

  result.low = LOW_PART (lhs) * LOW_PART (rhs);
  result.high = HIGH_PART (lhs) * HIGH_PART (rhs);

  middle[0] = LOW_PART (lhs) * HIGH_PART (rhs);
  middle[1] = HIGH_PART (lhs) * LOW_PART (rhs);

  temp = result.low;
  result.low += LOW_PART (middle[0]) << (PART_PRECISION / 2);
  if (result.low < temp)
    result.high++;

  temp = result.low;
  result.low += LOW_PART (middle[1]) << (PART_PRECISION / 2);
  if (result.low < temp)
    result.high++;

  result.high += HIGH_PART (middle[0]);
  result.high += HIGH_PART (middle[1]);
  result.unsignedp = true;
  result.overflow = false;

  return result;
}

/* Multiply two preprocessing numbers.  */
static cpp_num
num_mul (cpp_reader *pfile, cpp_num lhs, cpp_num rhs)
{
  cpp_num result, temp;
  bool unsignedp = lhs.unsignedp || rhs.unsignedp;
  bool overflow, negate = false;
  size_t precision = CPP_OPTION (pfile, precision);

  /* Prepare for unsigned multiplication.  */
  if (!unsignedp)
    {
      if (!num_positive (lhs, precision))
	negate = !negate, lhs = num_negate (lhs, precision);
      if (!num_positive (rhs, precision))
	negate = !negate, rhs = num_negate (rhs, precision);
    }

  overflow = lhs.high && rhs.high;
  result = num_part_mul (lhs.low, rhs.low);

  temp = num_part_mul (lhs.high, rhs.low);
  result.high += temp.low;
  if (temp.high)
    overflow = true;

  temp = num_part_mul (lhs.low, rhs.high);
  result.high += temp.low;
  if (temp.high)
    overflow = true;

  temp.low = result.low, temp.high = result.high;
  result = num_trim (result, precision);
  if (!num_eq (result, temp))
    overflow = true;

  if (negate)
    result = num_negate (result, precision);

  if (unsignedp)
    result.overflow = false;
  else
    result.overflow = overflow || (num_positive (result, precision) ^ !negate
				   && !num_zerop (result));
  result.unsignedp = unsignedp;

  return result;
}

/* Divide two preprocessing numbers, LHS and RHS, returning the answer
   or the remainder depending upon OP. LOCATION is the source location
   of this operator (for diagnostics).  */

static cpp_num
num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op,
	    source_location location)
{
  cpp_num result, sub;
  cpp_num_part mask;
  bool unsignedp = lhs.unsignedp || rhs.unsignedp;
  bool negate = false, lhs_neg = false;
  size_t i, precision = CPP_OPTION (pfile, precision);

  /* Prepare for unsigned division.  */
  if (!unsignedp)
    {
      if (!num_positive (lhs, precision))
	negate = !negate, lhs_neg = true, lhs = num_negate (lhs, precision);
      if (!num_positive (rhs, precision))
	negate = !negate, rhs = num_negate (rhs, precision);
    }

  /* Find the high bit.  */
  if (rhs.high)
    {
      i = precision - 1;
      mask = (cpp_num_part) 1 << (i - PART_PRECISION);
      for (; ; i--, mask >>= 1)
	if (rhs.high & mask)
	  break;
    }
  else if (rhs.low)
    {
      if (precision > PART_PRECISION)
	i = precision - PART_PRECISION - 1;
      else
	i = precision - 1;
      mask = (cpp_num_part) 1 << i;
      for (; ; i--, mask >>= 1)
	if (rhs.low & mask)
	  break;
    }
  else
    {
      if (!pfile->state.skip_eval)
	cpp_error_with_line (pfile, CPP_DL_ERROR, location, 0,
			     "division by zero in #if");
      return lhs;
    }

  /* First nonzero bit of RHS is bit I.  Do naive division by
     shifting the RHS fully left, and subtracting from LHS if LHS is
     at least as big, and then repeating but with one less shift.
     This is not very efficient, but is easy to understand.  */

  rhs.unsignedp = true;
  lhs.unsignedp = true;
  i = precision - i - 1;
  sub = num_lshift (rhs, precision, i);

  result.high = result.low = 0;
  for (;;)
    {
      if (num_greater_eq (lhs, sub, precision))
	{
	  lhs = num_binary_op (pfile, lhs, sub, CPP_MINUS);
	  if (i >= PART_PRECISION)
	    result.high |= (cpp_num_part) 1 << (i - PART_PRECISION);
	  else
	    result.low |= (cpp_num_part) 1 << i;
	}
      if (i-- == 0)
	break;
      sub.low = (sub.low >> 1) | (sub.high << (PART_PRECISION - 1));
      sub.high >>= 1;
    }

  /* We divide so that the remainder has the sign of the LHS.  */
  if (op == CPP_DIV)
    {
      result.unsignedp = unsignedp;
      result.overflow = false;
      if (!unsignedp)
	{
	  if (negate)
	    result = num_negate (result, precision);
	  result.overflow = (num_positive (result, precision) ^ !negate
			     && !num_zerop (result));
	}

      return result;
    }

  /* CPP_MOD.  */
  lhs.unsignedp = unsignedp;
  lhs.overflow = false;
  if (lhs_neg)
    lhs = num_negate (lhs, precision);

  return lhs;
}

/* Handle meeting "__has_include__" in a preprocessor expression.  */
static cpp_num
parse_has_include (cpp_reader *pfile, enum include_type type)
{
  cpp_num result;
  bool paren = false;
  cpp_hashnode *node = 0;
  const cpp_token *token;
  bool bracket = false;
  char *fname = 0;

  result.unsignedp = false;
  result.high = 0;
  result.overflow = false;
  result.low = 0;

  pfile->state.in__has_include__++;

  token = cpp_get_token (pfile);
  if (token->type == CPP_OPEN_PAREN)
    {
      paren = true;
      token = cpp_get_token (pfile);
    }

  if (token->type == CPP_STRING || token->type == CPP_HEADER_NAME)
    {
      if (token->type == CPP_HEADER_NAME)
	bracket = true;
      fname = XNEWVEC (char, token->val.str.len - 1);
      memcpy (fname, token->val.str.text + 1, token->val.str.len - 2);
      fname[token->val.str.len - 2] = '\0';
      node = token->val.node.node;
    }
  else if (token->type == CPP_LESS)
    {
      bracket = true;
      fname = _cpp_bracket_include (pfile);
    }
  else
    cpp_error (pfile, CPP_DL_ERROR,
	       "operator \"__has_include__\" requires a header string");

  if (fname)
    {
      int angle_brackets = (bracket ? 1 : 0);

      if (_cpp_has_header (pfile, fname, angle_brackets, type))
	result.low = 1;
      else
	result.low = 0;

      XDELETEVEC (fname);
    }

  if (paren && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN)
    cpp_error (pfile, CPP_DL_ERROR,
	       "missing ')' after \"__has_include__\"");

  /* A possible controlling macro of the form #if !__has_include__ ().
     _cpp_parse_expr checks there was no other junk on the line.  */
  if (node)
    pfile->mi_ind_cmacro = node;

  pfile->state.in__has_include__--;

  return result;
}
