/* Parse C expressions for cpplib.
   Copyright (C) 1987-2020 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.  */
  location_t 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,
			   location_t);
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 *, location_t);
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 (of CPP_N_* bits) describing the suffix.  */
static unsigned int
interpret_float_suffix (cpp_reader *pfile, const uchar *s, size_t len)
{
  size_t orig_len = len;
  const uchar *orig_s = s;
  size_t flags;
  size_t f, d, l, w, q, i, fn, fnx, fn_bits;

  flags = 0;
  f = d = l = w = q = i = fn = fnx = fn_bits = 0;

  /* The following decimal float suffixes, from TR 24732:2009, TS
     18661-2:2015 and C2X, are supported:

     df, DF - _Decimal32.
     dd, DD - _Decimal64.
     dl, DL - _Decimal128.

     The dN and DN suffixes for _DecimalN, and dNx and DNx for
     _DecimalNx, defined in TS 18661-3:2015, are not supported.

     Fixed-point suffixes, from TR 18037:2008, are supported.  They
     consist of three parts, in order:

     (i) An optional u or U, for unsigned types.

     (ii) An optional h or H, for short types, or l or L, for long
     types, or ll or LL, for long long types.  Use of ll or LL is a
     GNU extension.

     (iii) r or R, for _Fract types, or k or K, for _Accum types.

     Otherwise the suffix is for a binary or standard floating-point
     type.  Such a suffix, or the absence of a suffix, may be preceded
     or followed by i, I, j or J, to indicate an imaginary number with
     the corresponding complex type.  The following suffixes for
     binary or standard floating-point types are supported:

     f, F - float (ISO C and C++).
     l, L - long double (ISO C and C++).
     d, D - double, even with the FLOAT_CONST_DECIMAL64 pragma in
	    operation (from TR 24732:2009; the pragma and the suffix
	    are not included in TS 18661-2:2015).
     w, W - machine-specific type such as __float80 (GNU extension).
     q, Q - machine-specific type such as __float128 (GNU extension).
     fN, FN - _FloatN (TS 18661-3:2015).
     fNx, FNx - _FloatNx (TS 18661-3:2015).  */

  /* 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[0])
	{
	case 'f': case 'F':
	  f++;
	  if (len > 0
	      && !CPP_OPTION (pfile, cplusplus)
	      && s[1] >= '1'
	      && s[1] <= '9'
	      && fn_bits == 0)
	    {
	      f--;
	      while (len > 0
		     && s[1] >= '0'
		     && s[1] <= '9'
		     && fn_bits < CPP_FLOATN_MAX)
		{
		  fn_bits = fn_bits * 10 + (s[1] - '0');
		  len--;
		  s++;
		}
	      if (len > 0 && s[1] == 'x')
		{
		  fnx++;
		  len--;
		  s++;
		}
	      else
		fn++;
	    }
	  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;
	}
      s++;
    }

  /* Reject any case of multiple suffixes specifying types, multiple
     suffixes specifying an imaginary constant, _FloatN or _FloatNx
     suffixes for invalid values of N, and _FloatN suffixes for values
     of N larger than can be represented in the return value.  The
     caller is responsible for rejecting _FloatN suffixes where
     _FloatN is not supported on the chosen target.  */
  if (f + d + l + w + q + fn + fnx > 1 || i > 1)
    return 0;
  if (fn_bits > CPP_FLOATN_MAX)
    return 0;
  if (fnx && fn_bits != 32 && fn_bits != 64 && fn_bits != 128)
    return 0;
  if (fn && fn_bits != 16 && fn_bits % 32 != 0)
    return 0;
  if (fn && fn_bits == 96)
    return 0;

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

      /* In C++14 and up these suffixes are in the standard library, so treat
	 them as user-defined literals.  */
      if (CPP_OPTION (pfile, cplusplus)
	  && CPP_OPTION (pfile, lang) > CLK_CXX11
	  && orig_s[0] == 'i'
	  && (orig_len == 1
	      || (orig_len == 2
		  && (orig_s[1] == 'f' || orig_s[1] == 'l'))))
	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 :
	     fn ? CPP_N_FLOATN | (fn_bits << CPP_FLOATN_SHIFT) :
	     fnx ? CPP_N_FLOATNX | (fn_bits << CPP_FLOATN_SHIFT) :
	     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 orig_len = 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)
    {
      if (!CPP_OPTION (pfile, ext_numeric_literals))
	return 0;

      /* In C++14 and up these suffixes are in the standard library, so treat
	 them as user-defined literals.  */
      if (CPP_OPTION (pfile, cplusplus)
	  && CPP_OPTION (pfile, lang) > CLK_CXX11
	  && s[0] == 'i'
	  && (orig_len == 1 || (orig_len == 2 && s[1] == 'l')))
	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, location_t 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++17 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)
	{
	  if (CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, dfp_constants))
	    cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0,
				 "decimal float constants are a C2X feature");
	  else if (CPP_OPTION (pfile, cpp_warn_c11_c2x_compat) > 0)
	    cpp_warning_with_line (pfile, CPP_W_C11_C2X_COMPAT,
				   virtual_location, 0,
				   "decimal float constants are a C2X feature");
	}

      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
	   || initial_context != &pfile->base_context)
	  && CPP_OPTION (pfile, warn_expansion_to_defined))
        cpp_pedwarning (pfile, CPP_W_EXPANSION_TO_DEFINED,
		        "this use of \"defined\" may not be portable");

      _cpp_mark_macro_used (node);
      _cpp_maybe_notify_macro_use (pfile, 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 port 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 && cpp_macro_p (node)
		&& !(node->flags & NODE_CONDITIONAL));
  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,
	    location_t 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, evaluates to 0",
				   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;
  location_t 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,
	    location_t 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 && !SEEN_EOL () && 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;
}
