/* Routines for restoring various data types from a file stream.  This deals
   with various data types like strings, integers, enums, etc.

   Copyright (C) 2011-2023 Free Software Foundation, Inc.
   Contributed by Diego Novillo <dnovillo@google.com>

This file is part of GCC.

GCC 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.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "cgraph.h"
#include "data-streamer.h"
#include "value-range.h"
#include "streamer-hooks.h"

/* Read a string from the string table in DATA_IN using input block
   IB.  Write the length to RLEN.  */

static const char *
string_for_index (class data_in *data_in, unsigned int loc, unsigned int *rlen)
{
  unsigned int len;
  const char *result;

  if (!loc)
    {
      *rlen = 0;
      return NULL;
    }

  /* Get the string stored at location LOC in DATA_IN->STRINGS.  */
  lto_input_block str_tab (data_in->strings, loc - 1, data_in->strings_len, NULL);
  len = streamer_read_uhwi (&str_tab);
  *rlen = len;

  if (str_tab.p + len > data_in->strings_len)
    internal_error ("bytecode stream: string too long for the string table");

  result = (const char *)(data_in->strings + str_tab.p);

  return result;
}


/* Read a string from the string table in DATA_IN using input block
   IB.  Write the length to RLEN.  */

const char *
streamer_read_indexed_string (class data_in *data_in,
			      class lto_input_block *ib, unsigned int *rlen)
{
  return string_for_index (data_in, streamer_read_uhwi (ib), rlen);
}


/* Read a NULL terminated string from the string table in DATA_IN.  */

const char *
streamer_read_string (class data_in *data_in, class lto_input_block *ib)
{
  unsigned int len;
  const char *ptr;

  ptr = streamer_read_indexed_string (data_in, ib, &len);
  if (!ptr)
    return NULL;
  if (ptr[len - 1] != '\0')
    internal_error ("bytecode stream: found non-null terminated string");

  return ptr;
}


/* Read a string from the string table in DATA_IN using the bitpack BP.
   Write the length to RLEN.  */

const char *
bp_unpack_indexed_string (class data_in *data_in,
			  struct bitpack_d *bp, unsigned int *rlen)
{
  return string_for_index (data_in, bp_unpack_var_len_unsigned (bp), rlen);
}


/* Read a NULL terminated string from the string table in DATA_IN.  */

const char *
bp_unpack_string (class data_in *data_in, struct bitpack_d *bp)
{
  unsigned int len;
  const char *ptr;

  ptr = bp_unpack_indexed_string (data_in, bp, &len);
  if (!ptr)
    return NULL;
  if (ptr[len - 1] != '\0')
    internal_error ("bytecode stream: found non-null terminated string");

  return ptr;
}


/* Read an unsigned HOST_WIDE_INT number from IB.  */

unsigned HOST_WIDE_INT
streamer_read_uhwi (class lto_input_block *ib)
{
  unsigned HOST_WIDE_INT result;
  int shift;
  unsigned HOST_WIDE_INT byte;
  unsigned int p = ib->p;
  unsigned int len = ib->len;

  const char *data = ib->data;
  result = data[p++];
  if ((result & 0x80) != 0)
    {
      result &= 0x7f;
      shift = 7;
      do
	{
	  byte = data[p++];
	  result |= (byte & 0x7f) << shift;
	  shift += 7;
	}
      while ((byte & 0x80) != 0);
    }

  /* We check for section overrun after the fact for performance reason.  */
  if (p > len)
    lto_section_overrun (ib);

  ib->p = p;
  return result;
}


/* Read a HOST_WIDE_INT number from IB.  */

HOST_WIDE_INT
streamer_read_hwi (class 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_1U << shift);

	  return result;
	}
    }
}

/* Read a poly_uint64 from IB.  */

poly_uint64
streamer_read_poly_uint64 (class lto_input_block *ib)
{
  poly_uint64 res;
  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    res.coeffs[i] = streamer_read_uhwi (ib);
  return res;
}

/* Read a poly_int64 from IB.  */

poly_int64
streamer_read_poly_int64 (class lto_input_block *ib)
{
  poly_int64 res;
  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    res.coeffs[i] = streamer_read_hwi (ib);
  return res;
}

/* Read gcov_type value from IB.  */

gcov_type
streamer_read_gcov_count (class lto_input_block *ib)
{
  gcov_type ret = streamer_read_hwi (ib);
  return ret;
}

/* Read REAL_VALUE_TYPE from IB.  */

void
streamer_read_real_value (class lto_input_block *ib, REAL_VALUE_TYPE *r)
{
  struct bitpack_d bp = streamer_read_bitpack (ib);
  bp_unpack_real_value (&bp, r);
}

void
streamer_read_value_range (class lto_input_block *ib, data_in *data_in,
			   Value_Range &vr)
{
  // Read the common fields to all vranges.
  value_range_kind kind = streamer_read_enum (ib, value_range_kind, VR_LAST);
  gcc_checking_assert (kind != VR_UNDEFINED);
  tree type = stream_read_tree (ib, data_in);

  // Initialize the Value_Range to the correct type.
  vr.set_type (type);

  if (is_a <irange> (vr))
    {
      irange &r = as_a <irange> (vr);
      r.set_undefined ();
      unsigned HOST_WIDE_INT num_pairs = streamer_read_uhwi (ib);
      for (unsigned i = 0; i < num_pairs; ++i)
	{
	  wide_int lb = streamer_read_wide_int (ib);
	  wide_int ub = streamer_read_wide_int (ib);
	  int_range<2> tmp (type, lb, ub);
	  r.union_ (tmp);
	}
      wide_int nz = streamer_read_wide_int (ib);
      r.set_nonzero_bits (nz);
      return;
    }
  if (is_a <frange> (vr))
    {
      frange &r = as_a <frange> (vr);

      // Stream in NAN bits.
      struct bitpack_d bp = streamer_read_bitpack (ib);
      bool pos_nan = (bool) bp_unpack_value (&bp, 1);
      bool neg_nan = (bool) bp_unpack_value (&bp, 1);
      nan_state nan (pos_nan, neg_nan);

      if (kind == VR_NAN)
	r.set_nan (type, nan);
      else
	{
	  REAL_VALUE_TYPE lb, ub;
	  streamer_read_real_value (ib, &lb);
	  streamer_read_real_value (ib, &ub);
	  r.set (type, lb, ub, nan);
	}
      return;
    }
  gcc_unreachable ();
}

/* Read the physical representation of a wide_int val from
   input block IB.  */

wide_int
streamer_read_wide_int (class lto_input_block *ib)
{
  HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
  int i;
  int prec = streamer_read_uhwi (ib);
  int len = streamer_read_uhwi (ib);
  for (i = 0; i < len; i++)
    a[i] = streamer_read_hwi (ib);
  return wide_int::from_array (a, len, prec);
}

/* Read the physical representation of a widest_int val from
   input block IB.  */

widest_int
streamer_read_widest_int (class lto_input_block *ib)
{
  HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
  int i;
  int prec ATTRIBUTE_UNUSED = streamer_read_uhwi (ib);
  int len = streamer_read_uhwi (ib);
  for (i = 0; i < len; i++)
    a[i] = streamer_read_hwi (ib);
  return widest_int::from_array (a, len);
}

