/* Generate CTF types and objects from the GCC DWARF.
   Copyright (C) 2021-2022 Free Software Foundation, Inc.

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 "target.h"
#include "dwarf2out.h"
#include "dwarf2out.h"

#include "dwarf2ctf.h"
#include "ctfc.h"

/* Forward declarations for some routines defined in this file.  */

static ctf_id_t
gen_ctf_type (ctf_container_ref, dw_die_ref);

/* All the DIE structures we handle come from the DWARF information
   generated by GCC.  However, there are three situations where we need
   to create our own created DIE structures because GCC doesn't
   provide them.

   The DWARF spec suggests using a DIE with DW_TAG_unspecified_type
   and name "void" in order to denote the void type.  But GCC doesn't
   follow this advice.  Still we need a DIE to act as a key for void
   types, we use ctf_void_die.

   Also, if a subrange type corresponding to an array index does not
   specify a type then we assume it is `int'.

   Finally, for types unrepresentable in CTF, we need a DIE to anchor
   them to a CTF type of kind unknown.

   The variables below are initialized in ctf_debug_init and hold
   references to the proper DIEs.  */

static GTY (()) dw_die_ref ctf_void_die;
static GTY (()) dw_die_ref ctf_array_index_die;
static GTY (()) dw_die_ref ctf_unknown_die;

/* Some DIEs have a type description attribute, stored in a DW_AT_type
   attribute.  However, GCC generates no attribute to signify a `void'
   type.

   This can happen in many contexts (return type of a function,
   pointed or qualified type, etc) so we use the `ctf_get_AT_type'
   function below abstracts this.  */

static dw_die_ref
ctf_get_AT_type (dw_die_ref die)
{
  dw_die_ref type_die = get_AT_ref (die, DW_AT_type);
  return (type_die ? type_die : ctf_void_die);
}

/* Some data member DIEs have location specified as a DWARF expression
   (specifically in DWARF2).  Luckily, the expression is a simple
   DW_OP_plus_uconst with one operand set to zero.

   Sometimes the data member location may also be negative.  In yet some other
   cases (specifically union data members), the data member location is
   non-existent.  Handle all these scenarios here to abstract this.  */

static HOST_WIDE_INT
ctf_get_AT_data_member_location (dw_die_ref die)
{
  HOST_WIDE_INT field_location = 0;
  dw_attr_node * attr;

  /* The field location (in bits) can be determined from
     either a DW_AT_data_member_location attribute or a
     DW_AT_data_bit_offset attribute.  */
  if (get_AT (die, DW_AT_data_bit_offset))
    field_location = get_AT_unsigned (die, DW_AT_data_bit_offset);
  else
    {
      attr = get_AT (die, DW_AT_data_member_location);
      if (attr && AT_class (attr) == dw_val_class_loc)
	{
	  dw_loc_descr_ref descr = AT_loc (attr);
	  /* Operand 2 must be zero; the structure is assumed to be on the
	     stack in DWARF2.  */
	  gcc_assert (!descr->dw_loc_oprnd2.v.val_unsigned);
	  gcc_assert (descr->dw_loc_oprnd2.val_class
		      == dw_val_class_unsigned_const);
	  field_location = descr->dw_loc_oprnd1.v.val_unsigned * 8;
	}
      else
	{
	  attr = get_AT (die, DW_AT_data_member_location);
	  if (attr && AT_class (attr) == dw_val_class_const)
	    field_location = AT_int (attr) * 8;
	  else
	    field_location = (get_AT_unsigned (die,
					   DW_AT_data_member_location)
			      * 8);
	}
    }

  return field_location;
}

/* CTF Types' and CTF Variables' Location Information.  CTF section does not
   emit location information, this is provided for BTF CO-RE use-cases.  These
   functions fetch information from DWARF Die directly, as such the location
   information is not buffered in the CTF container.  */

const char *
ctf_get_die_loc_file (dw_die_ref die)
{
  if (!die)
    return NULL;

  struct dwarf_file_data * file;
  file = get_AT_file (die, DW_AT_decl_file);
  if (!file)
    return NULL;

  return file->filename;
}

unsigned int
ctf_get_die_loc_line (dw_die_ref die)
{
  if (!die)
    return 0;

  return get_AT_unsigned (die, DW_AT_decl_line);
}

unsigned int
ctf_get_die_loc_col (dw_die_ref die)
{
  if (!die)
    return 0;

  return get_AT_unsigned (die, DW_AT_decl_column);
}

/* Generate CTF for the void type.  */

static ctf_id_t
gen_ctf_void_type (ctf_container_ref ctfc)
{
  ctf_encoding_t ctf_encoding = {0, 0, 0};

  /* In CTF the void type is encoded as a 0-byte signed integer
     type.  */

  ctf_encoding.cte_bits = 0;
  ctf_encoding.cte_format = CTF_INT_SIGNED;

  gcc_assert (ctf_void_die != NULL);
  return ctf_add_integer (ctfc, CTF_ADD_ROOT, "void",
			  &ctf_encoding, ctf_void_die);
}

/* Generate CTF type of unknown kind.  */

static ctf_id_t
gen_ctf_unknown_type (ctf_container_ref ctfc)
{
  ctf_id_t unknown_type_id;

  /* In CTF, the unknown type is encoded as a 0 byte sized type with kind
     CTF_K_UNKNOWN.  Create an encoding object merely to reuse the underlying
     ctf_add_encoded interface; the CTF encoding object is not 'used' any more
     than just the generation of size from.  */
  ctf_encoding_t ctf_encoding = {0, 0, 0};

  gcc_assert (ctf_unknown_die != NULL);
  /* Type de-duplication.  */
  if (!ctf_type_exists (ctfc, ctf_unknown_die, &unknown_type_id))
    unknown_type_id = ctf_add_unknown (ctfc, CTF_ADD_ROOT, "unknown",
				       &ctf_encoding, ctf_unknown_die);

  return unknown_type_id;
}

/* Sizes of entities can be given in bytes or bits.  This function
   abstracts this by returning the size in bits of the given entity.
   If no DW_AT_byte_size nor DW_AT_bit_size are defined, this function
   returns 0.  */

static uint32_t
ctf_die_bitsize (dw_die_ref die)
{
  dw_attr_node *attr_byte_size = get_AT (die, DW_AT_byte_size);
  dw_attr_node *attr_bit_size = get_AT (die, DW_AT_bit_size);

  if (attr_bit_size)
    return AT_unsigned (attr_bit_size);
  else if (attr_byte_size)
    return (AT_unsigned (attr_byte_size) * 8);
  else
    return 0;
}

/* Generate CTF for base type (integer, boolean, real, fixed point and complex).
   Important: the caller of this API must make sure that duplicate types are
   not added.  */

static ctf_id_t
gen_ctf_base_type (ctf_container_ref ctfc, dw_die_ref type)
{
  ctf_id_t type_id = CTF_NULL_TYPEID;

  ctf_encoding_t ctf_encoding = {0, 0, 0};

  unsigned int encoding = get_AT_unsigned (type, DW_AT_encoding);
  unsigned int bit_size = ctf_die_bitsize (type);
  const char * name_string = get_AT_string (type, DW_AT_name);

  switch (encoding)
    {
    case DW_ATE_void:

      ctf_encoding.cte_format = CTF_INT_SIGNED;
      ctf_encoding.cte_bits = 0;

      gcc_assert (name_string);
      type_id = ctf_add_integer (ctfc, CTF_ADD_ROOT, name_string,
				 &ctf_encoding, type);

      break;
    case DW_ATE_boolean:

      ctf_encoding.cte_format = CTF_INT_BOOL;
      ctf_encoding.cte_bits = bit_size;

      gcc_assert (name_string);
      type_id = ctf_add_integer (ctfc, CTF_ADD_ROOT, name_string,
				 &ctf_encoding, type);
      break;
    case DW_ATE_float:
      {
	unsigned int float_bit_size
	  = tree_to_uhwi (TYPE_SIZE (float_type_node));
	unsigned int double_bit_size
	  = tree_to_uhwi (TYPE_SIZE (double_type_node));
	unsigned int long_double_bit_size
	  = tree_to_uhwi (TYPE_SIZE (long_double_type_node));

	if (bit_size == float_bit_size)
	  ctf_encoding.cte_format = CTF_FP_SINGLE;
	else if (bit_size == double_bit_size)
	  ctf_encoding.cte_format = CTF_FP_DOUBLE;
	else if (bit_size == long_double_bit_size)
	  ctf_encoding.cte_format = CTF_FP_LDOUBLE;
	else
	  /* CTF does not have representation for other types.  Skip them.  */
	  break;

	ctf_encoding.cte_bits = bit_size;
	type_id = ctf_add_float (ctfc, CTF_ADD_ROOT, name_string,
				 &ctf_encoding, type);

	break;
      }
    case DW_ATE_signed_char:
      /* FALLTHROUGH */
    case DW_ATE_unsigned_char:
      /* FALLTHROUGH */
    case DW_ATE_signed:
      /* FALLTHROUGH */
    case DW_ATE_unsigned:

      if (encoding == DW_ATE_signed_char
	  || encoding == DW_ATE_unsigned_char)
	ctf_encoding.cte_format |= CTF_INT_CHAR;

      if (encoding == DW_ATE_signed
	  || encoding == DW_ATE_signed_char)
	ctf_encoding.cte_format |= CTF_INT_SIGNED;

      ctf_encoding.cte_bits = bit_size;
      type_id = ctf_add_integer (ctfc, CTF_ADD_ROOT, name_string,
				 &ctf_encoding, type);
      break;

    case DW_ATE_complex_float:
      {
	unsigned int float_bit_size
	  = tree_to_uhwi (TYPE_SIZE (float_type_node));
	unsigned int double_bit_size
	  = tree_to_uhwi (TYPE_SIZE (double_type_node));
	unsigned int long_double_bit_size
	  = tree_to_uhwi (TYPE_SIZE (long_double_type_node));

	if (bit_size == float_bit_size * 2)
	  ctf_encoding.cte_format = CTF_FP_CPLX;
	else if (bit_size == double_bit_size * 2)
	  ctf_encoding.cte_format = CTF_FP_DCPLX;
	else if (bit_size == long_double_bit_size * 2)
	    ctf_encoding.cte_format = CTF_FP_LDCPLX;
	else
	  /* CTF does not have representation for other types.  Skip them.  */
	  break;

	ctf_encoding.cte_bits = bit_size;
	type_id = ctf_add_float (ctfc, CTF_ADD_ROOT, name_string,
				 &ctf_encoding, type);
	break;
      }
    default:
      /* Ignore.  */
      break;
    }

  return type_id;
}

/* Generate CTF for a pointer type.  */

static ctf_id_t
gen_ctf_pointer_type (ctf_container_ref ctfc, dw_die_ref ptr_type)
{
  ctf_id_t type_id = CTF_NULL_TYPEID;
  ctf_id_t ptr_type_id = CTF_NULL_TYPEID;
  dw_die_ref pointed_type_die = ctf_get_AT_type (ptr_type);

  type_id = gen_ctf_type (ctfc, pointed_type_die);

  /* Type de-duplication.
     Consult the ctfc_types hash again before adding the CTF pointer type
     because there can be cases where a pointer type may have been added by
     the gen_ctf_type call above.  */
  if (ctf_type_exists (ctfc, ptr_type, &ptr_type_id))
    return ptr_type_id;

  ptr_type_id = ctf_add_pointer (ctfc, CTF_ADD_ROOT, type_id, ptr_type);
  return ptr_type_id;
}

/* Generate CTF for an array type.  */

static ctf_id_t
gen_ctf_array_type (ctf_container_ref ctfc, dw_die_ref array_type)
{
  dw_die_ref c;
  ctf_id_t array_elems_type_id = CTF_NULL_TYPEID;

  int vector_type_p = get_AT_flag (array_type, DW_AT_GNU_vector);
  if (vector_type_p)
    return array_elems_type_id;

  dw_die_ref array_elems_type = ctf_get_AT_type (array_type);

  /* First, register the type of the array elements if needed.  */
  array_elems_type_id = gen_ctf_type (ctfc, array_elems_type);

  /* DWARF array types pretend C supports multi-dimensional arrays.
     So for the type int[N][M], the array type DIE contains two
     subrange_type children, the first with upper bound N-1 and the
     second with upper bound M-1.

     CTF, on the other hand, just encodes each array type in its own
     array type CTF struct.  Therefore we have to iterate on the
     children and create all the needed types.  */

  c = dw_get_die_child (array_type);
  gcc_assert (c);
  do
    {
      ctf_arinfo_t arinfo;
      dw_die_ref array_index_type;
      uint32_t array_num_elements;

      c = dw_get_die_sib (c);

      if (dw_get_die_tag (c) == DW_TAG_subrange_type)
	{
	  dw_attr_node *upper_bound_at;

	  array_index_type = ctf_get_AT_type (c);

	  /* When DW_AT_upper_bound is used to specify the size of an
	     array in DWARF, it is usually an unsigned constant
	     specifying the upper bound index of the array.  However,
	     for unsized arrays, such as foo[] or bar[0],
	     DW_AT_upper_bound is a signed integer constant
	     instead.  */

	  upper_bound_at = get_AT (c, DW_AT_upper_bound);
	  if (upper_bound_at
	      && AT_class (upper_bound_at) == dw_val_class_unsigned_const)
	    /* This is the upper bound index.  */
	    array_num_elements = get_AT_unsigned (c, DW_AT_upper_bound) + 1;
	  else if (get_AT (c, DW_AT_count))
	    array_num_elements = get_AT_unsigned (c, DW_AT_count);
	  else
	    {
	      /* This is a VLA of some kind.  */
	      array_num_elements = 0;
	    }
	}
      else if (dw_get_die_tag (c) == DW_TAG_enumeration_type)
	{
	  array_index_type = 0;
	  array_num_elements = 0;
	  /* XXX writeme. */
	  gcc_assert (1);
	}
      else
	gcc_unreachable ();

      /* Ok, mount and register the array type.  Note how the array
	 type we register here is the type of the elements in
	 subsequent "dimensions", if there are any.  */

      arinfo.ctr_nelems = array_num_elements;
      if (array_index_type)
	arinfo.ctr_index = gen_ctf_type (ctfc, array_index_type);
      else
	arinfo.ctr_index = gen_ctf_type (ctfc, ctf_array_index_die);

      arinfo.ctr_contents = array_elems_type_id;
      if (!ctf_type_exists (ctfc, c, &array_elems_type_id))
	array_elems_type_id = ctf_add_array (ctfc, CTF_ADD_ROOT, &arinfo,
					     c);
    }
  while (c != dw_get_die_child (array_type));

#if 0
  /* Type de-duplication.
     Consult the ctfc_types hash again before adding the CTF array type because
     there can be cases where an array_type type may have been added by the
     gen_ctf_type call above.  */
  if (!ctf_type_exists (ctfc, array_type, &type_id))
    type_id = ctf_add_array (ctfc, CTF_ADD_ROOT, &arinfo, array_type);
#endif

  return array_elems_type_id;
}

/* Generate CTF for a typedef.  */

static ctf_id_t
gen_ctf_typedef (ctf_container_ref ctfc, dw_die_ref tdef)
{
  ctf_id_t tdef_type_id, tid;
  const char *tdef_name = get_AT_string (tdef, DW_AT_name);
  dw_die_ref tdef_type = ctf_get_AT_type (tdef);

  tid = gen_ctf_type (ctfc, tdef_type);

  /* Type de-duplication.
     This is necessary because the ctf for the typedef may have been already
     added due to the gen_ctf_type call above.  */
  if (!ctf_type_exists (ctfc, tdef, &tdef_type_id))
  {
    tdef_type_id = ctf_add_typedef (ctfc, CTF_ADD_ROOT,
				    tdef_name,
				    tid,
				    tdef);
  }
  return tdef_type_id;
}

/* Generate CTF for a type modifier.

   If the given DIE contains a valid C modifier (like _Atomic), which is not
   supported by CTF, then this function skips the modifier die and continues
   with the underlying type.

   For all other cases, this function returns a CTF_NULL_TYPEID;
*/

static ctf_id_t
gen_ctf_modifier_type (ctf_container_ref ctfc, dw_die_ref modifier)
{
  uint32_t kind = CTF_K_MAX;
  ctf_id_t modifier_type_id, qual_type_id;
  dw_die_ref qual_type = ctf_get_AT_type (modifier);

  switch (dw_get_die_tag (modifier))
    {
    case DW_TAG_const_type: kind = CTF_K_CONST; break;
    case DW_TAG_volatile_type: kind = CTF_K_VOLATILE; break;
    case DW_TAG_restrict_type: kind = CTF_K_RESTRICT; break;
    case DW_TAG_atomic_type: break;
    default:
      return CTF_NULL_TYPEID;
    }

  /* Register the type for which this modifier applies.  */
  qual_type_id = gen_ctf_type (ctfc, qual_type);

  /* Skip generating a CTF modifier record for _Atomic as there is no
     representation for it.  */
  if (dw_get_die_tag (modifier) == DW_TAG_atomic_type)
    return qual_type_id;

  gcc_assert (kind != CTF_K_MAX);
  /* Now register the modifier itself.  */
  if (!ctf_type_exists (ctfc, modifier, &modifier_type_id))
    modifier_type_id = ctf_add_reftype (ctfc, CTF_ADD_ROOT,
					qual_type_id, kind,
					modifier);

  return modifier_type_id;
}

/* Generate CTF for a struct type.  */

static ctf_id_t
gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, uint32_t kind)
{
  uint32_t bit_size = ctf_die_bitsize (sou);
  int declaration_p = get_AT_flag (sou, DW_AT_declaration);
  const char *sou_name = get_AT_string (sou, DW_AT_name);

  ctf_id_t sou_type_id;

  /* An incomplete structure or union type is represented in DWARF by
     a structure or union DIE that does not have a size attribute and
     that has a DW_AT_declaration attribute.  This corresponds to a
     CTF forward type with kind CTF_K_STRUCT.  */
  if (bit_size == 0 && declaration_p)
    return ctf_add_forward (ctfc, CTF_ADD_ROOT,
			    sou_name, kind, sou);

  /* This is a complete struct or union type.  Generate a CTF type for
     it if it doesn't exist already.  */
  if (!ctf_type_exists (ctfc, sou, &sou_type_id))
    sou_type_id = ctf_add_sou (ctfc, CTF_ADD_ROOT,
			       sou_name, kind, bit_size / 8,
			       sou);

  /* Now process the struct members.  */
  {
    dw_die_ref c;

    c = dw_get_die_child (sou);
    if (c)
      do
	{
	  const char *field_name;
	  dw_die_ref field_type;
	  HOST_WIDE_INT field_location;
	  ctf_id_t field_type_id;

	  c = dw_get_die_sib (c);

	  field_name = get_AT_string (c, DW_AT_name);
	  field_type = ctf_get_AT_type (c);
	  field_location = ctf_get_AT_data_member_location (c);

	  /* Generate the field type.  */
	  field_type_id = gen_ctf_type (ctfc, field_type);

	  /* If this is a bit-field, then wrap the field type
	     generated above with a CTF slice.  */
	  if (get_AT (c, DW_AT_bit_offset)
	      || get_AT (c, DW_AT_data_bit_offset))
	    {
	      dw_attr_node *attr;
	      HOST_WIDE_INT bitpos = 0;
	      HOST_WIDE_INT bitsize = ctf_die_bitsize (c);
	      HOST_WIDE_INT bit_offset;

	      /* The bit offset is given in bits and it may be
		 negative.  */
	      attr = get_AT (c, DW_AT_bit_offset);
	      if (attr)
		{
		  if (AT_class (attr) == dw_val_class_unsigned_const)
		    bit_offset = AT_unsigned (attr);
		  else
		    bit_offset = AT_int (attr);

		  if (BYTES_BIG_ENDIAN)
		    bitpos = field_location + bit_offset;
		  else
		    {
		      HOST_WIDE_INT bit_size;

		      attr = get_AT (c, DW_AT_byte_size);
		      if (attr)
			/* Explicit size given in bytes.  */
			bit_size = AT_unsigned (attr) * 8;
		      else
			/* Infer the size from the member type.  */
			bit_size = ctf_die_bitsize (field_type);

		      bitpos = (field_location
				+ bit_size
				- bit_offset
				- bitsize);
		    }
		}

	      /* In DWARF5 a data_bit_offset attribute is given with
		 the offset of the data from the beginning of the
		 struct.  Acknowledge it if present.  */
	      attr = get_AT (c, DW_AT_data_bit_offset);
	      if (attr)
		bitpos += AT_unsigned (attr);

	      field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT,
					     field_type_id,
					     bitpos - field_location,
					     bitsize,
					     c);
	    }

	  /* Add the field type to the struct or union type.  */
	  ctf_add_member_offset (ctfc, sou,
				 field_name,
				 field_type_id,
				 field_location);
	}
      while (c != dw_get_die_child (sou));
  }

  return sou_type_id;
}

/* Generate CTF for a function type.  */

static ctf_id_t
gen_ctf_function_type (ctf_container_ref ctfc, dw_die_ref function,
		       bool from_global_func)
{
  const char *function_name = get_AT_string (function, DW_AT_name);
  dw_die_ref return_type = ctf_get_AT_type (function);

  ctf_funcinfo_t func_info;
  uint32_t num_args = 0;
  int linkage = get_AT_flag (function, DW_AT_external);

  ctf_id_t return_type_id;
  ctf_id_t function_type_id;

  /* First, add the return type.  */
  return_type_id = gen_ctf_type (ctfc, return_type);
  func_info.ctc_return = return_type_id;

  /* Type de-duplication.
     Consult the ctfc_types hash before adding the CTF function type.  */
  if (ctf_type_exists (ctfc, function, &function_type_id))
    return function_type_id;

  /* Do a first pass on the formals to determine the number of
     arguments, and whether the function type gets a varargs.  */
  {
    dw_die_ref c;

    c = dw_get_die_child (function);
    if (c)
      do
	{
	  c = dw_get_die_sib (c);

	  if (dw_get_die_tag (c) == DW_TAG_formal_parameter)
	    num_args += 1;
	  else if (dw_get_die_tag (c) == DW_TAG_unspecified_parameters)
	    {
	      func_info.ctc_flags |= CTF_FUNC_VARARG;
	      num_args += 1;
	    }
	}
      while (c != dw_get_die_child (function));
  }

  /* Note the number of typed arguments _includes_ the vararg.  */
  func_info.ctc_argc = num_args;

  /* Type de-duplication has already been performed by now.  */
  function_type_id = ctf_add_function (ctfc, CTF_ADD_ROOT,
				       function_name,
				       (const ctf_funcinfo_t *)&func_info,
				       function,
				       from_global_func,
                                       linkage);

  /* Second pass on formals: generate the CTF types corresponding to
     them and add them as CTF function args.  */
  {
    dw_die_ref c;
    unsigned int i = 0;
    const char *arg_name;
    ctf_id_t arg_type;

    c = dw_get_die_child (function);
    if (c)
      do
	{
	  c = dw_get_die_sib (c);

	  if (dw_get_die_tag (c) == DW_TAG_unspecified_parameters)
	    {
	      gcc_assert (i == num_args - 1);
	      /* Add an argument with type 0 and no name.  */
	      ctf_add_function_arg (ctfc, function, "", 0);
	    }
	  else if (dw_get_die_tag (c) == DW_TAG_formal_parameter)
	    {
	      i++;
	      arg_name = get_AT_string (c, DW_AT_name);
	      arg_type = gen_ctf_type (ctfc, ctf_get_AT_type (c));
	      /* Add the argument to the existing CTF function type.  */
	      ctf_add_function_arg (ctfc, function, arg_name, arg_type);
	    }
	  else
	    /* This is a local variable.  Ignore.  */
	    continue;
	}
      while (c != dw_get_die_child (function));
  }

  return function_type_id;
}

/* Generate CTF for an enumeration type.  */

static ctf_id_t
gen_ctf_enumeration_type (ctf_container_ref ctfc, dw_die_ref enumeration)
{
  const char *enum_name = get_AT_string (enumeration, DW_AT_name);
  unsigned int bit_size = ctf_die_bitsize (enumeration);
  unsigned int signedness = get_AT_unsigned (enumeration, DW_AT_encoding);
  int declaration_p = get_AT_flag (enumeration, DW_AT_declaration);

  ctf_id_t enumeration_type_id;

  /* If this is an incomplete enum, generate a CTF forward for it and
     be done.  */
  if (declaration_p)
    {
      gcc_assert (enum_name);
      return ctf_add_forward (ctfc, CTF_ADD_ROOT, enum_name,
			      CTF_K_ENUM, enumeration);
    }

  /* If the size the enumerators is not specified then use the size of
     the underlying type, which must be a base type.  */
  if (bit_size == 0)
    {
      dw_die_ref type = ctf_get_AT_type (enumeration);
      bit_size = ctf_die_bitsize (type);
    }

  /* Generate a CTF type for the enumeration.  */
  enumeration_type_id = ctf_add_enum (ctfc, CTF_ADD_ROOT,
				      enum_name, bit_size / 8,
				      (signedness == DW_ATE_unsigned),
				      enumeration);

  /* Process the enumerators.  */
  {
    dw_die_ref c;

    c = dw_get_die_child (enumeration);
    if (c)
      do
	{
	  const char *enumerator_name;
	  dw_attr_node *enumerator_value;
	  HOST_WIDE_INT value_wide_int;

	  c = dw_get_die_sib (c);

	  enumerator_name = get_AT_string (c, DW_AT_name);
	  enumerator_value = get_AT (c, DW_AT_const_value);

	  /* enumerator_value can be either a signed or an unsigned
	     constant value.  */
	  if (AT_class (enumerator_value) == dw_val_class_unsigned_const
	      || (AT_class (enumerator_value)
		  == dw_val_class_unsigned_const_implicit))
	    value_wide_int = AT_unsigned (enumerator_value);
	  else
	    value_wide_int = AT_int (enumerator_value);

	  ctf_add_enumerator (ctfc, enumeration_type_id,
			      enumerator_name, value_wide_int, enumeration);
	}
      while (c != dw_get_die_child (enumeration));
  }

  return enumeration_type_id;
}

/* Add a CTF variable record for the given input DWARF DIE.  */

static void
gen_ctf_variable (ctf_container_ref ctfc, dw_die_ref die)
{
  const char *var_name = get_AT_string (die, DW_AT_name);
  dw_die_ref var_type = ctf_get_AT_type (die);
  unsigned int external_vis = get_AT_flag (die, DW_AT_external);
  ctf_id_t var_type_id;

  /* Avoid duplicates.  */
  if (ctf_dvd_lookup (ctfc, die))
    return;

  /* Do not generate CTF variable records for non-defining incomplete
     declarations.  Such declarations can be known via the DWARF
     DW_AT_specification attribute.  */
  if (ctf_dvd_ignore_lookup (ctfc, die))
    return;

  /* The value of the DW_AT_specification attribute, if present, is a
     reference to the debugging information entry representing the
     non-defining declaration.  */
  dw_die_ref decl = get_AT_ref (die, DW_AT_specification);

  /* Add the type of the variable.  */
  var_type_id = gen_ctf_type (ctfc, var_type);

  /* Generate the new CTF variable and update global counter.  */
  (void) ctf_add_variable (ctfc, var_name, var_type_id, die, external_vis,
			   decl);
  /* Skip updating the number of global objects at this time.  This is updated
     later after pre-processing as some CTF variable records although
     generated now, will not be emitted later.  [PR105089].  */
}

/* Add a CTF function record for the given input DWARF DIE.  */

static void
gen_ctf_function (ctf_container_ref ctfc, dw_die_ref die)
{
  ctf_id_t function_type_id;
  /* Type de-duplication.
     Consult the ctfc_types hash before adding the CTF function type.  */
  if (ctf_type_exists (ctfc, die, &function_type_id))
    return;

  /* Add the type of the function and update the global functions
     counter.  Note that DWARF encodes function types in both
     DW_TAG_subroutine_type and DW_TAG_subprogram in exactly the same
     way.  */
  (void) gen_ctf_function_type (ctfc, die, true /* from_global_func */);
  ctfc->ctfc_num_global_funcs += 1;
}

/* Add CTF type record(s) for the given input DWARF DIE and return its type id.

   If there is already a CTF type corresponding to the given DIE, then
   this function returns the type id of the existing type.

   If the given DIE is not recognized as a type, then this function
   returns CTF_NULL_TYPEID.  */

static ctf_id_t
gen_ctf_type (ctf_container_ref ctfc, dw_die_ref die)
{
  ctf_id_t type_id;
  int unrecog_die = false;

  if (ctf_type_exists (ctfc, die, &type_id))
    return type_id;

  switch (dw_get_die_tag (die))
    {
    case DW_TAG_base_type:
      type_id = gen_ctf_base_type (ctfc, die);
      break;
    case DW_TAG_pointer_type:
      type_id = gen_ctf_pointer_type (ctfc, die);
      break;
    case DW_TAG_typedef:
      type_id = gen_ctf_typedef (ctfc, die);
      break;
    case DW_TAG_array_type:
      type_id = gen_ctf_array_type (ctfc, die);
      break;
    case DW_TAG_structure_type:
      type_id = gen_ctf_sou_type (ctfc, die, CTF_K_STRUCT);
      break;
    case DW_TAG_union_type:
      type_id = gen_ctf_sou_type (ctfc, die, CTF_K_UNION);
      break;
    case DW_TAG_subroutine_type:
      type_id = gen_ctf_function_type (ctfc, die,
				       false /* from_global_func */);
      break;
    case DW_TAG_enumeration_type:
      type_id = gen_ctf_enumeration_type (ctfc, die);
      break;
    case DW_TAG_atomic_type:
      /* FALLTHROUGH */
    case DW_TAG_const_type:
      /* FALLTHROUGH */
    case DW_TAG_restrict_type:
      /* FALLTHROUGH */
    case DW_TAG_volatile_type:
      type_id = gen_ctf_modifier_type (ctfc, die);
      break;
    case DW_TAG_unspecified_type:
      {
	const char *name = get_AT_string (die, DW_AT_name);

	if (name && strcmp (name, "void") == 0)
	  type_id = gen_ctf_void_type (ctfc);
	else
	  type_id = CTF_NULL_TYPEID;

	break;
      }
    case DW_TAG_reference_type:
      type_id = CTF_NULL_TYPEID;
      break;
    default:
      /* Unrecognized DIE.  */
      unrecog_die = true;
      type_id = CTF_NULL_TYPEID;
      break;
    }

  /* For all types unrepresented in CTF, use an explicit CTF type of kind
     CTF_K_UNKNOWN.  */
  if ((type_id == CTF_NULL_TYPEID) && (!unrecog_die))
    type_id = gen_ctf_unknown_type (ctfc);

  return type_id;
}

/* Prepare for output and write out the CTF debug information.  */

static void
ctf_debug_finalize (const char *filename, bool btf)
{
  if (btf)
    {
      btf_output (filename);
      btf_finalize ();
    }

  else
    {
      /* Emit the collected CTF information.  */
      ctf_output (filename);

      /* Reset the CTF state.  */
      ctf_finalize ();
    }
}

bool
ctf_do_die (dw_die_ref die)
{
  ctf_container_ref tu_ctfc = ctf_get_tu_ctfc ();

  /* Note how we tell the caller to continue traversing children DIEs
     if this DIE didn't result in CTF records being added.  */
  if (dw_get_die_tag (die) == DW_TAG_variable)
    {
      gen_ctf_variable (tu_ctfc, die);
      return false;
    }
  else if (dw_get_die_tag (die) == DW_TAG_subprogram)
    {
      gen_ctf_function (tu_ctfc, die);
      return false;
    }
  else
    return gen_ctf_type (tu_ctfc, die) == CTF_NULL_TYPEID;
}

/* Initialize CTF subsystem for CTF debug info generation.  */

void
ctf_debug_init (void)
{
  /* First, initialize the CTF subsystem.  */
  ctf_init ();

  /* Create a couple of DIE structures that we may need.  */
  ctf_void_die = new_die_raw (DW_TAG_unspecified_type);
  add_name_attribute (ctf_void_die, "void");
  ctf_array_index_die
    = base_type_die (integer_type_node, 0 /* reverse */);
  add_name_attribute (ctf_array_index_die, "int");
  ctf_unknown_die = new_die_raw (DW_TAG_unspecified_type);
  add_name_attribute (ctf_unknown_die, "unknown");
}

/* Preprocess the CTF debug information after initialization.  */

void
ctf_debug_init_postprocess (bool btf)
{
  /* Only BTF requires postprocessing right after init.  */
  if (btf)
    btf_init_postprocess ();
}

/* Early finish CTF/BTF debug info.  */

void
ctf_debug_early_finish (const char * filename)
{
  /* Emit CTF debug info early always.  */
  if (ctf_debug_info_level > CTFINFO_LEVEL_NONE
      /* Emit BTF debug info early if CO-RE relocations are not
	 required.  */
      || (btf_debuginfo_p () && !btf_with_core_debuginfo_p ()))
    ctf_debug_finalize (filename, btf_debuginfo_p ());
}

/* Finish CTF/BTF debug info emission.  */

void
ctf_debug_finish (const char * filename)
{
  /* Emit BTF debug info here when CO-RE relocations need to be generated.
     BTF with CO-RE relocations needs to be generated when CO-RE is in effect
     for the BPF target.  */
  if (btf_with_core_debuginfo_p ())
    {
      gcc_assert (btf_debuginfo_p ());
      ctf_debug_finalize (filename, btf_debuginfo_p ());
    }
}

#include "gt-dwarf2ctf.h"
