static inline long long
streamer_read_hwi_in_range (struct lto_input_block *ib,
     const char *purpose,
     long long min,
     long long max)
{
  long long range = max - min;
  long long val = streamer_read_uchar (ib);
  if (range >= 0xff)
    val |= ((long long)streamer_read_uchar (ib)) << 8;
  if (val < min || val > max)
    lto_value_range_error (purpose, val, min, max);
  return val;
}
unsigned HOST_WIDE_INT
streamer_read_uhwi (struct lto_input_block *ib)
{
  unsigned HOST_WIDE_INT result = 0;
  int shift = 0;
  unsigned HOST_WIDE_INT byte;

  while (true)
    {
      byte = streamer_read_uchar (ib);
      result |= (byte & 0x7f) << shift;
      shift += 7;
      if ((byte & 0x80) == 0)
	return result;
    }
}
HOST_WIDE_INT
streamer_read_hwi (struct lto_input_block *ib)
{
  HOST_WIDE_INT result = 0;
  int shift = 0;
  unsigned HOST_WIDE_INT byte;

  while (true)
    {
      byte = streamer_read_uchar (ib);
      result |= (byte & 0x7f) << shift;
      shift += 7;
      if ((byte & 0x80) == 0)
	{
	  if ((shift < HOST_BITS_PER_WIDE_INT) && (byte & 0x40))
	    result |= - ((HOST_WIDE_INT)1 << shift);

	  return result;
	}
    }
}
tree
streamer_read_integer_cst (struct lto_input_block *ib, struct data_in *data_in)
{
  tree result, type;
  HOST_WIDE_INT low, high;
  bool overflow_p;

  type = stream_read_tree (ib, data_in);
  overflow_p = (streamer_read_uchar (ib) != 0);
  low = streamer_read_uhwi (ib);
  high = streamer_read_uhwi (ib);
  result = build_int_cst_wide (type, low, high);

  /* If the original constant had overflown, build a replica of RESULT to
     avoid modifying the shared constant returned by build_int_cst_wide.  */
  if (overflow_p)
    {
      result = copy_node (result);
      TREE_OVERFLOW (result) = 1;
    }

  return result;
}