/* Generate CTF.
   Copyright (C) 2019-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 "toplev.h"
#include "ctfc.h"
#include "diagnostic-core.h"

/* A CTF container object - one per translation unit.  */

ctf_container_ref tu_ctfc;

ctf_container_ref
ctf_get_tu_ctfc (void)
{
  return tu_ctfc;
}

/* If the next ctf type id is still set to the init value, no ctf records to
   report.  */
bool
ctfc_is_empty_container (ctf_container_ref ctfc)
{
  return ((ctfc)->ctfc_nextid == CTF_INIT_TYPEID);
}

/* Get the total number of CTF types in the container.  */

unsigned int
ctfc_get_num_ctf_types (ctf_container_ref ctfc)
{
  return ctfc->ctfc_types->elements ();
}

/* Get the total number of CTF variables in the container.  */

unsigned int ctfc_get_num_ctf_vars (ctf_container_ref ctfc)
{
  return ctfc->ctfc_vars->elements ();
}

/* Get reference to the CTF string table or the CTF auxilliary
   string table.  */

ctf_strtable_t *
ctfc_get_strtab (ctf_container_ref ctfc, int aux)
{
  return aux ? &(ctfc)->ctfc_aux_strtable : &(ctfc->ctfc_strtable);
}

/* Get the length of the specified string table of the CTF container.  */

size_t
ctfc_get_strtab_len (ctf_container_ref ctfc, int aux)
{
  ctf_strtable_t * strtab = ctfc_get_strtab (ctfc, aux);
  return strtab->ctstab_len;
}

/* Get the number of bytes to represent the variable length portion of all CTF
   types in the CTF container.  */

size_t ctfc_get_num_vlen_bytes (ctf_container_ref ctfc)
{
  return ctfc->ctfc_num_vlen_bytes;
}

/* Return which member of the union is used in CTFTYPE.  Used for garbage
   collection.  */

enum ctf_dtu_d_union_enum
ctf_dtu_d_union_selector (ctf_dtdef_ref ctftype)
{
  uint32_t kind = CTF_V2_INFO_KIND (ctftype->dtd_data.ctti_info);
  switch (kind)
    {
    case CTF_K_UNKNOWN:
    case CTF_K_INTEGER:
    case CTF_K_FLOAT:
      return CTF_DTU_D_ENCODING;
    case CTF_K_STRUCT:
    case CTF_K_UNION:
    case CTF_K_ENUM:
      return CTF_DTU_D_MEMBERS;
    case CTF_K_ARRAY:
      return CTF_DTU_D_ARRAY;
    case CTF_K_FUNCTION:
      return CTF_DTU_D_ARGUMENTS;
    case CTF_K_SLICE:
      return CTF_DTU_D_SLICE;
    default:
      /* The largest member as default.  */
      return CTF_DTU_D_ARRAY;
    }
}

/* Insert CTF type into the CTF container.  */

static void
ctf_dtd_insert (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
{
  bool existed = false;
  ctf_dtdef_ref entry = dtd;

  ctf_dtdef_ref * item = ctfc->ctfc_types->find_slot (entry, INSERT);
  if (*item == NULL)
     *item = dtd;
  else
    existed = true;
  /* Duplicate CTF type records not expected to be inserted.  */
  gcc_assert (!existed);
}

/* Lookup CTF type given a DWARF die for the type.  */

ctf_dtdef_ref
ctf_dtd_lookup (const ctf_container_ref ctfc, const dw_die_ref type)
{
  ctf_dtdef_t entry;
  entry.dtd_key = type;

  ctf_dtdef_ref * slot = ctfc->ctfc_types->find_slot (&entry, NO_INSERT);

  if (slot)
    return (ctf_dtdef_ref)*slot;

  return NULL;
}

/* Insert CTF variable into the CTF container.  */

static void
ctf_dvd_insert (ctf_container_ref ctfc, ctf_dvdef_ref dvd)
{
  bool existed = false;
  ctf_dvdef_ref entry = dvd;

  ctf_dvdef_ref * item = ctfc->ctfc_vars->find_slot (entry, INSERT);
  if (*item == NULL)
     *item = dvd;
  else
    existed = true;
  /* Duplicate variable records not expected to be inserted.  */
  gcc_assert (!existed);
}

/* Lookup CTF variable given a DWARF die for the decl.  */

ctf_dvdef_ref
ctf_dvd_lookup (const ctf_container_ref ctfc, dw_die_ref die)
{
  ctf_dvdef_t entry;
  entry.dvd_key = die;

  ctf_dvdef_ref * slot = ctfc->ctfc_vars->find_slot (&entry, NO_INSERT);

  if (slot)
    return (ctf_dvdef_ref)*slot;

  return NULL;
}

/* Insert a dummy CTF variable into the list of variables to be ignored.  */

static void
ctf_dvd_ignore_insert (ctf_container_ref ctfc, ctf_dvdef_ref dvd)
{
  bool existed = false;
  ctf_dvdef_ref entry = dvd;

  ctf_dvdef_ref * item = ctfc->ctfc_ignore_vars->find_slot (entry, INSERT);
  if (*item == NULL)
     *item = dvd;
  else
    existed = true;
  /* Duplicate variable records not expected to be inserted.  */
  gcc_assert (!existed);
}

/* Lookup the dummy CTF variable given the DWARF die for the non-defining
   decl to be ignored.  */

bool
ctf_dvd_ignore_lookup (const ctf_container_ref ctfc, dw_die_ref die)
{
  ctf_dvdef_t entry;
  entry.dvd_key = die;

  ctf_dvdef_ref * slot = ctfc->ctfc_ignore_vars->find_slot (&entry, NO_INSERT);

  if (slot)
    return true;

  return false;
}

/* Append member definition to the list.  Member list is a singly-linked list
   with list start pointing to the head.  */

static void
ctf_dmd_list_append (ctf_dmdef_t ** dmd, ctf_dmdef_t * elem)
{
  ctf_dmdef_t * tail = (dmd && *dmd) ? *dmd : NULL;
  if (tail)
    {
      while (tail->dmd_next)
	tail = tail->dmd_next;

      tail->dmd_next = elem;
    }
  else
    *dmd = elem;

  elem->dmd_next = NULL;
}

/* Append function argument to the list.  Member list is a singly-linked list
   with list start pointing to the head.  */

static void
ctf_farg_list_append (ctf_func_arg_t ** farg, ctf_func_arg_t * elem)
{
  ctf_func_arg_t * tail = (farg && *farg) ? *farg : NULL;
  if (tail)
    {
      while (tail->farg_next)
	tail = tail->farg_next;

      tail->farg_next = elem;
    }
  else
    *farg = elem;

  elem->farg_next = NULL;
}

/* Append str to the CTF string table.  */

static void
ctfc_strtable_append_str (ctf_strtable_t * str_table, const char * str)
{
  ctf_string_t * ctf_string = ggc_cleared_alloc<ctf_string_t> ();
  /* Keep a reference to the input STR.  */
  ctf_string->cts_str = str;
  ctf_string->cts_next = NULL;

  if (!str_table->ctstab_head)
    str_table->ctstab_head = ctf_string;

  /* Append to the end of the list.  */
  if (str_table->ctstab_tail)
    str_table->ctstab_tail->cts_next = ctf_string;

  str_table->ctstab_tail = ctf_string;
}

/* Wrapper function to add str to the CTF string table.  No de-duplication of
   CTF strings is done by the compiler.  */

static const char *
ctfc_strtable_add_str (ctf_strtable_t * str_table, const char * name,
		      uint32_t * name_offset)
{
  size_t len;
  char * ctf_string;
  /* Return value is the offset to the string in the string table.  */
  uint32_t str_offset = str_table->ctstab_len;

  /* Add empty string only once at the beginning of the string table.  Also, do
     not add null strings, return the offset to the empty string for them.  */
  if ((!name || (name != NULL && !strcmp (name, ""))) && str_offset)
    {
      ctf_string = CONST_CAST (char *, str_table->ctstab_estr);
      str_offset = 0;
    }
  else
    {
      gcc_assert (name);
      /* Add null-terminated strings to the string table.  */
      len = strlen (name) + 1;
      ctf_string = CONST_CAST (char *, ggc_strdup (name));

      ctfc_strtable_append_str (str_table, ctf_string);
      /* Add string to the string table.  Keep number of strings updated.  */
      str_table->ctstab_num++;
      /* Keep the number of bytes contained in the string table updated.  */
      str_table->ctstab_len += len;
    }

  *name_offset = str_offset;

  return (const char *) ctf_string;

}

/* Add string to the appropriate string table in the CTF container.  */

const char *
ctf_add_string (ctf_container_ref ctfc, const char * name,
		uint32_t * name_offset, int aux_str = CTF_STRTAB)
{
  /* Get the CTF string table or the CTF auxilliary string table,
     as applicable.  */
  ctf_strtable_t *str_table = ctfc_get_strtab (ctfc, aux_str);
  return ctfc_strtable_add_str (str_table, name, name_offset);
}

/* Add the compilation unit (CU) name string to the the CTF string table.  The
   CU name has a prepended pwd string if it is a relative path.  Also set the
   CU name offset in the CTF container.  */

void
ctf_add_cuname (ctf_container_ref ctfc, const char * filename)
{
  char * cuname = NULL;

  /* (filename at this point of compilation cannot be null).  */

  if (!IS_DIR_SEPARATOR (filename[0]))
    {
      /* Filename is a relative path.  */
      const char * cu_pwd = get_src_pwd ();
      const int cu_pwd_len = strlen (cu_pwd);

      /* Add a DIR_SEPARATOR char before the filename.  */
      const int len = cu_pwd_len + 2 + strlen (filename);

      cuname = (char *) ggc_alloc_atomic (len);
      memset (cuname, 0, len);

      strcpy (cuname, cu_pwd);
      cuname[cu_pwd_len] = DIR_SEPARATOR;
      cuname[cu_pwd_len+1] = 0;
      strcat (cuname, filename);
    }
  else
    /* Filename is an absolute path.  */
    cuname = CONST_CAST (char *, ggc_strdup (filename));

  ctf_add_string (ctfc, cuname, &(ctfc->ctfc_cuname_offset));
  /* Add 1 as CTF strings in the CTF string table are null-terminated
     strings.  */
  ctfc->ctfc_strlen += strlen (cuname) + 1;

  /* Mark cuname for garbage collection.  */
  cuname = NULL;
}

/* Functions to create CTF types.

   These functions perform the task of adding CTF types to the CTF container.
   No de-duplication is done by them; the onus is on the calling function to do
   so.  The caller must first do a lookup via ctf_dtd_lookup or
   ctf_dvd_lookup, as applicable, to ascertain that the CTF type or the CTF
   variable respectively does not already exist, and then add it.  */

static ctf_id_t
ctf_add_generic (ctf_container_ref ctfc, uint32_t flag, const char * name,
		 ctf_dtdef_ref * rp, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;

  gcc_assert (flag == CTF_ADD_NONROOT || flag == CTF_ADD_ROOT);

  dtd = ggc_cleared_alloc<ctf_dtdef_t> ();

  type = ctfc->ctfc_nextid++;
  gcc_assert (type < CTF_MAX_TYPE); /* CTF type ID overflow.  */

  /* Buffer the strings in the CTF string table.  */
  dtd->dtd_name = ctf_add_string (ctfc, name, &(dtd->dtd_data.ctti_name));
  dtd->dtd_type = type;
  dtd->dtd_key = die;

  if ((name != NULL) && strcmp (name, ""))
    ctfc->ctfc_strlen += strlen (name) + 1;

  ctf_dtd_insert (ctfc, dtd);

  *rp = dtd;
  return type;
}

static ctf_id_t
ctf_add_encoded (ctf_container_ref ctfc, uint32_t flag, const char * name,
		 const ctf_encoding_t * ep, uint32_t kind, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;

  type = ctf_add_generic (ctfc, flag, name, &dtd, die);

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, flag, 0);

  uint32_t roundup_nbytes = (ROUND_UP (ep->cte_bits, BITS_PER_UNIT)
				    / BITS_PER_UNIT);

  /* FIXME, stay close to what libctf does.  But by getting next power of two,
     aren't we conveying less precise information.  E.g. floating point mode
     XF has a size of 12 bytes.  */
  dtd->dtd_data.ctti_size = roundup_nbytes ? (1 << ceil_log2 (roundup_nbytes))
			   : roundup_nbytes;
  dtd->dtd_u.dtu_enc = *ep;

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_reftype (ctf_container_ref ctfc, uint32_t flag, ctf_id_t ref,
		 uint32_t kind, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;

  gcc_assert (ref <= CTF_MAX_TYPE);

  type = ctf_add_generic (ctfc, flag, NULL, &dtd, die);
  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, flag, 0);
  /* Caller of this API must guarantee that a CTF type with id = ref already
     exists.  This will also be validated for us at link-time.  */
  dtd->dtd_data.ctti_type = (uint32_t) ref;

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_forward (ctf_container_ref ctfc, uint32_t flag, const char * name,
		 uint32_t kind, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type = 0;

  type = ctf_add_generic (ctfc, flag, name, &dtd, die);

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_FORWARD, flag, 0);
  dtd->dtd_data.ctti_type = kind;

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_typedef (ctf_container_ref ctfc, uint32_t flag, const char * name,
		 ctf_id_t ref, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;

  gcc_assert (ref <= CTF_MAX_TYPE);
  /* Nameless Typedefs are not expected.  */
  gcc_assert ((name != NULL) && strcmp (name, ""));

  type = ctf_add_generic (ctfc, flag, name, &dtd, die);
  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_TYPEDEF, flag, 0);
  /* Caller of this API must guarantee that a CTF type with id = ref already
     exists.  This will also be validated for us at link-time.  */
  dtd->dtd_data.ctti_type = (uint32_t) ref;

  gcc_assert (dtd->dtd_type != dtd->dtd_data.ctti_type);

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_slice (ctf_container_ref ctfc, uint32_t flag, ctf_id_t ref,
	       uint32_t bit_offset, uint32_t bit_size, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;
  uint32_t roundup_nbytes;

  gcc_assert ((bit_size <= 255) && (bit_offset <= 255));

  gcc_assert (ref <= CTF_MAX_TYPE);

  type = ctf_add_generic (ctfc, flag, NULL, &dtd, die);

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_SLICE, flag, 0);

  roundup_nbytes = (ROUND_UP (bit_size, BITS_PER_UNIT) / BITS_PER_UNIT);
  /* FIXME, stay close to what libctf does.  But by getting next power of two,
     aren't we conveying less precise information, especially for bitfields.
     For example, cte_bits = 33, roundup_nbytes = 5, ctti_size = 8 in the
     implementation below.  */
  dtd->dtd_data.ctti_size = roundup_nbytes ? (1 << ceil_log2 (roundup_nbytes))
					   : 0;

  /* Caller of this API must guarantee that a CTF type with id = ref already
     exists.  This will also be validated for us at link-time.  */
  dtd->dtd_u.dtu_slice.cts_type = (uint32_t) ref;
  dtd->dtd_u.dtu_slice.cts_bits = bit_size;
  dtd->dtd_u.dtu_slice.cts_offset = bit_offset;

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_float (ctf_container_ref ctfc, uint32_t flag,
	       const char * name, const ctf_encoding_t * ep, dw_die_ref die)
{
  return (ctf_add_encoded (ctfc, flag, name, ep, CTF_K_FLOAT, die));
}

ctf_id_t
ctf_add_integer (ctf_container_ref ctfc, uint32_t flag,
		 const char * name, const ctf_encoding_t * ep, dw_die_ref die)
{
  return (ctf_add_encoded (ctfc, flag, name, ep, CTF_K_INTEGER, die));
}

ctf_id_t
ctf_add_unknown (ctf_container_ref ctfc, uint32_t flag,
		 const char * name, const ctf_encoding_t * ep, dw_die_ref die)
{
  return (ctf_add_encoded (ctfc, flag, name, ep, CTF_K_UNKNOWN, die));
}

ctf_id_t
ctf_add_pointer (ctf_container_ref ctfc, uint32_t flag, ctf_id_t ref,
		 dw_die_ref die)
{
  return (ctf_add_reftype (ctfc, flag, ref, CTF_K_POINTER, die));
}

ctf_id_t
ctf_add_array (ctf_container_ref ctfc, uint32_t flag, const ctf_arinfo_t * arp,
	       dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;

  gcc_assert (arp);

  /* Caller of this API must make sure CTF type for arp->ctr_contents and
     arp->ctr_index are already added.  This will also be validated for us at
     link-time.  */

  type = ctf_add_generic (ctfc, flag, NULL, &dtd, die);

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_ARRAY, flag, 0);
  dtd->dtd_data.ctti_size = 0;
  dtd->dtd_u.dtu_arr = *arp;

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_enum (ctf_container_ref ctfc, uint32_t flag, const char * name,
	      HOST_WIDE_INT size, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;

  /* In the compiler, no need to handle the case of promoting forwards to
     enums.  This comment is simply to note a divergence from libctf.  */

  /* The compiler does, however, update any previously existing forward types
     to non-root.  CTF does not allow existence of two root types with the same
     name.  */
  ctf_dtdef_ref enum_fwd_type = ctf_dtd_lookup (ctfc, die);
  if (enum_fwd_type)
    {
      enum_fwd_type->dtd_data.ctti_info
	= CTF_TYPE_INFO (CTF_K_FORWARD, CTF_ADD_NONROOT, 0);
    }

  type = ctf_add_generic (ctfc, flag, name, &dtd, die);

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_ENUM, flag, 0);

  /* Size in bytes should always fit, of course.
     TBD WARN - warn instead?  */
  gcc_assert (size <= CTF_MAX_SIZE);

  dtd->dtd_data.ctti_size = size;

  ctfc->ctfc_num_stypes++;

  return type;
}

int
ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name,
		    HOST_WIDE_INT value, dw_die_ref die)
{
  ctf_dmdef_t * dmd;
  uint32_t kind, vlen, root;

  /* Callers of this API must make sure that CTF_K_ENUM with enid has been
     addded.  This will also be validated for us at link-time.  */
  ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, die);
  gcc_assert (dtd);
  gcc_assert (dtd->dtd_type == enid);
  gcc_assert (name);

  kind = CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info);
  root = CTF_V2_INFO_ISROOT (dtd->dtd_data.ctti_info);
  vlen = CTF_V2_INFO_VLEN (dtd->dtd_data.ctti_info);

  gcc_assert (kind == CTF_K_ENUM && vlen < CTF_MAX_VLEN);

  /* Enum value is of type HOST_WIDE_INT in the compiler, dmd_value is int32_t
     on the other hand.  Check bounds and skip adding this enum value if out of
     bounds.  */
  if ((value > INT_MAX) || (value < INT_MIN))
    {
      /* FIXME - Note this TBD_CTF_REPRESENTATION_LIMIT.  */
      return (1);
    }

  dmd = ggc_cleared_alloc<ctf_dmdef_t> ();

  /* Buffer the strings in the CTF string table.  */
  dmd->dmd_name = ctf_add_string (ctfc, name, &(dmd->dmd_name_offset));
  dmd->dmd_type = CTF_NULL_TYPEID;
  dmd->dmd_offset = 0;

  dmd->dmd_value = value;

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, root, vlen + 1);
  ctf_dmd_list_append (&dtd->dtd_u.dtu_members, dmd);

  if ((name != NULL) && strcmp (name, ""))
    ctfc->ctfc_strlen += strlen (name) + 1;

  return (0);
}

int
ctf_add_member_offset (ctf_container_ref ctfc, dw_die_ref sou,
		       const char * name, ctf_id_t type,
		       uint64_t bit_offset)
{
  ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, sou);
  ctf_dmdef_t * dmd;

  uint32_t kind, vlen, root;

  /* The type of the member being added must already exist.  */
  gcc_assert (dtd);

  kind = CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info);
  root = CTF_V2_INFO_ISROOT (dtd->dtd_data.ctti_info);
  vlen = CTF_V2_INFO_VLEN (dtd->dtd_data.ctti_info);

  gcc_assert (kind == CTF_K_STRUCT || kind == CTF_K_UNION);
  gcc_assert (vlen < CTF_MAX_VLEN);

  dmd = ggc_cleared_alloc<ctf_dmdef_t> ();

  /* Buffer the strings in the CTF string table.  */
  dmd->dmd_name = ctf_add_string (ctfc, name, &(dmd->dmd_name_offset));
  dmd->dmd_type = type;
  dmd->dmd_value = -1;

  if (kind == CTF_K_STRUCT && vlen != 0)
    dmd->dmd_offset = bit_offset;
  else
    dmd->dmd_offset = 0;

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, root, vlen + 1);
  ctf_dmd_list_append (&dtd->dtd_u.dtu_members, dmd);

  if ((name != NULL) && strcmp (name, ""))
    ctfc->ctfc_strlen += strlen (name) + 1;

  return 0;
}

int
ctf_add_variable (ctf_container_ref ctfc, const char * name, ctf_id_t ref,
		  dw_die_ref die, unsigned int external_vis,
		  dw_die_ref die_var_decl)
{
  ctf_dvdef_ref dvd, dvd_ignore;

  gcc_assert (name);

  if (name != NULL)
    {
      dvd = ggc_cleared_alloc<ctf_dvdef_t> ();
      dvd->dvd_key = die;
      /* Buffer the strings in the CTF string table.  */
      dvd->dvd_name = ctf_add_string (ctfc, name, &(dvd->dvd_name_offset));
      dvd->dvd_visibility = external_vis;
      dvd->dvd_type = ref;

      /* If DW_AT_specification attribute exists, keep track of it as this is
	 the non-defining declaration corresponding to the variable.  We will
	 skip emitting CTF variable for such incomplete, non-defining
	 declarations.
	 There could be some non-defining declarations, however, for which a
	 defining declaration does not show up in the same CU.  For such
	 cases, the compiler continues to emit CTF variable record as
	 usual.  */
      if (die_var_decl)
	{
	  dvd_ignore = ggc_cleared_alloc<ctf_dvdef_t> ();
	  dvd_ignore->dvd_key = die_var_decl;
	  /* It's alright to leave other fields as zero.  No valid CTF
	     variable will be added for these DW_TAG_variable DIEs.  */
	  ctf_dvd_ignore_insert (ctfc, dvd_ignore);
	}

      ctf_dvd_insert (ctfc, dvd);

      if (strcmp (name, ""))
	ctfc->ctfc_strlen += strlen (name) + 1;
    }

  return 0;
}

int
ctf_add_function_arg (ctf_container_ref ctfc, dw_die_ref func,
		      const char * name, ctf_id_t type)
{
  ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, func);
  ctf_func_arg_t * farg;
  uint32_t vlen;

  /* The function to which argument is being added must already exist.  */
  gcc_assert (dtd);
  /* The number of args must have been non-zero.  */
  vlen = CTF_V2_INFO_VLEN (dtd->dtd_data.ctti_info);
  gcc_assert (vlen);

  farg = ggc_cleared_alloc<ctf_func_arg_t> ();

  /* Buffer the strings in the auxilliary string table.  CTF V3 format does not
     require function argument names.  Use auxilliary string table to keep
     these strings to avoid unnecessary bloat in CTF section in CTF V3.  */
  farg->farg_name = ctf_add_string (ctfc, name, &(farg->farg_name_offset),
				    CTF_AUX_STRTAB);
  farg->farg_type = type;

  ctf_farg_list_append (&dtd->dtd_u.dtu_argv, farg);

  /* For aux_str, keep ctfc_aux_strlen updated for debugging.  */
  if ((name != NULL) && strcmp (name, ""))
    ctfc->ctfc_aux_strlen += strlen (name) + 1;

  return 0;
}

ctf_id_t
ctf_add_function (ctf_container_ref ctfc, uint32_t flag, const char * name,
		  const ctf_funcinfo_t * ctc, dw_die_ref die,
		  bool from_global_func)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type;
  uint32_t vlen;

  gcc_assert (ctc);

  vlen = ctc->ctc_argc;
  gcc_assert (vlen <= CTF_MAX_VLEN);

  type = ctf_add_generic (ctfc, flag, name, &dtd, die);

  dtd->from_global_func = from_global_func;
  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen);
  /* Caller must make sure CTF types for ctc->ctc_return are already added.  */
  dtd->dtd_data.ctti_type = (uint32_t) ctc->ctc_return;
  /* Caller must make sure CTF types for function arguments are already added
     via ctf_add_function_arg () API.  */

  ctfc->ctfc_num_stypes++;

  return type;
}

ctf_id_t
ctf_add_sou (ctf_container_ref ctfc, uint32_t flag, const char * name,
	     uint32_t kind, size_t size, dw_die_ref die)
{
  ctf_dtdef_ref dtd;
  ctf_id_t type = 0;

  gcc_assert ((kind == CTF_K_STRUCT) || (kind == CTF_K_UNION));

  /* In the compiler, no need to handle the case of promoting forwards to
     structs.  This comment is simply to note a divergence from libctf.  */

  /* The compiler does, however, update any previously existing forward types
     to non-root.  CTF does not allow existence of two root types with the same
     name.  */
  ctf_dtdef_ref sou_fwd_type = ctf_dtd_lookup (ctfc, die);
  if (sou_fwd_type)
    {
      sou_fwd_type->dtd_data.ctti_info
	= CTF_TYPE_INFO (CTF_K_FORWARD, CTF_ADD_NONROOT, 0);
    }

  type = ctf_add_generic (ctfc, flag, name, &dtd, die);

  dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, flag, 0);

  if (size > CTF_MAX_SIZE)
    {
      dtd->dtd_data.ctti_size = CTF_LSIZE_SENT;
      dtd->dtd_data.ctti_lsizehi = CTF_SIZE_TO_LSIZE_HI (size);
      dtd->dtd_data.ctti_lsizelo = CTF_SIZE_TO_LSIZE_LO (size);
      ctfc->ctfc_num_types++;
    }
  else
    {
      dtd->dtd_data.ctti_size = (uint32_t) size;
      ctfc->ctfc_num_stypes++;
    }

  return type;
}

/* Given a TREE_TYPE node, return the CTF type ID for that type.  */

ctf_id_t
ctf_lookup_tree_type (ctf_container_ref ctfc, const tree type)
{
  dw_die_ref die = lookup_type_die (type);
  if (die == NULL)
    return CTF_NULL_TYPEID;

  ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, die);
  if (dtd == NULL)
    return CTF_NULL_TYPEID;

  return dtd->dtd_type;
}

/* Check if CTF for TYPE has already been generated.  Mainstay for
   de-duplication.  If CTF type already exists, returns TRUE and updates
   the TYPE_ID for the caller.  */

bool
ctf_type_exists (ctf_container_ref ctfc, dw_die_ref type,
		 ctf_id_t * type_id)
{
  bool exists = false;
  ctf_dtdef_ref ctf_type_seen = ctf_dtd_lookup (ctfc, type);

  if (ctf_type_seen)
    {
      exists = true;
      /* CTF type for this type exists.  */
      *type_id = ctf_type_seen->dtd_type;
    }

  return exists;
}

/* Location information for CTF Types and CTF Variables.  CTF section does not
   emit location information; at this time, location information is needed for
   BTF CO-RE use-cases.  */

int
ctfc_get_dtd_srcloc (ctf_dtdef_ref dtd, ctf_srcloc_ref loc)
{
  loc->ctsloc_file = ctf_get_die_loc_file (dtd->dtd_key);
  loc->ctsloc_line = ctf_get_die_loc_line (dtd->dtd_key);
  loc->ctsloc_col = ctf_get_die_loc_col (dtd->dtd_key);

  if (loc->ctsloc_file == NULL)
    return 1;

  return 0;
}

int
ctfc_get_dvd_srcloc (ctf_dvdef_ref dvd, ctf_srcloc_ref loc)
{
  loc->ctsloc_file = ctf_get_die_loc_file (dvd->dvd_key);
  loc->ctsloc_line = ctf_get_die_loc_line (dvd->dvd_key);
  loc->ctsloc_col = ctf_get_die_loc_col (dvd->dvd_key);

  if (loc->ctsloc_file == NULL)
    return 1;

  return 0;
}

/* CTF container setup and teardown routines.  */

/* Initialize the CTF string table.
   The first entry in the CTF string table (empty string) is added.  */

static void
init_ctf_strtable (ctf_strtable_t * strtab)
{
  strtab->ctstab_head = NULL;
  strtab->ctstab_tail = NULL;
  strtab->ctstab_num = 0;
  strtab->ctstab_len = 0;

  /* The first entry in the CTF string table is an empty string.  E.g., CTF
     type records with no name (like CTF_K_CONST, CTF_K_VOLATILE etc) point to
     this string.  */
  uint32_t estr_offset = 0;
  strtab->ctstab_estr = ctfc_strtable_add_str (strtab, "", &estr_offset);
}

/* Initialize the string tables in the CTF container.  */

static void
init_ctf_string_table (ctf_container_ref ctfc)
{
  init_ctf_strtable (&ctfc->ctfc_strtable);
  ctfc->ctfc_strlen++;

  init_ctf_strtable (&ctfc->ctfc_aux_strtable);
  ctfc->ctfc_aux_strlen++;
}

/* Allocate a new CTF container with the desired flags.  */

static inline ctf_container_ref
new_ctf_container (void)
{
  tu_ctfc = ggc_cleared_alloc<ctf_container_t> ();
  tu_ctfc->ctfc_types
    = hash_table<ctfc_dtd_hasher>::create_ggc (100);
  tu_ctfc->ctfc_vars
    = hash_table<ctfc_dvd_hasher>::create_ggc (100);
  tu_ctfc->ctfc_ignore_vars
    = hash_table<ctfc_dvd_hasher>::create_ggc (10);

  return tu_ctfc;
}

/* Initialize a CTF container per translation unit.  */

static void
init_ctf_container (void)
{
  tu_ctfc = new_ctf_container ();

  tu_ctfc->ctfc_magic = CTF_MAGIC;
  tu_ctfc->ctfc_version = CTF_VERSION;
  tu_ctfc->ctfc_flags = CTF_F_NEWFUNCINFO;
  tu_ctfc->ctfc_nextid = CTF_INIT_TYPEID;

  init_ctf_string_table (tu_ctfc);
}

void
ctfc_delete_strtab (ctf_strtable_t * strtab)
{
  ctf_string_t * str = NULL;
  ctf_string_t * next_str = NULL;

  str = strtab->ctstab_head;
  next_str = str;
  while (next_str != NULL)
    {
      next_str = str->cts_next;
      ggc_free (str);
      str = next_str;
    }

  strtab->ctstab_head = NULL;
  strtab->ctstab_tail = NULL;
  strtab->ctstab_estr = NULL;
}

/* Delete the CTF container's resources.  */

void
ctfc_delete_container (ctf_container_ref ctfc)
{
  if (ctfc)
    {
      ctfc->ctfc_types->empty ();
      ctfc->ctfc_types = NULL;

      ctfc->ctfc_vars->empty ();
      ctfc->ctfc_types = NULL;

      ctfc->ctfc_ignore_vars->empty ();
      ctfc->ctfc_ignore_vars = NULL;

      ctfc_delete_strtab (&ctfc->ctfc_strtable);
      ctfc_delete_strtab (&ctfc->ctfc_aux_strtable);
      if (ctfc->ctfc_vars_list)
	{
	  ggc_free (ctfc->ctfc_vars_list);
	  ctfc->ctfc_vars_list = NULL;
	}
      if (ctfc->ctfc_types_list)
	{
	  ggc_free (ctfc->ctfc_types_list);
	  ctfc->ctfc_types_list = NULL;
	}
      if (ctfc->ctfc_gfuncs_list)
	{
	  ggc_free (ctfc->ctfc_gfuncs_list);
	  ctfc->ctfc_gfuncs_list = NULL;
	}
      if (ctfc->ctfc_gobjts_list)
	{
	  ggc_free (ctfc->ctfc_gobjts_list);
	  ctfc->ctfc_gobjts_list = NULL;
	}

      ctfc= NULL;
    }
}

/* CTF routines interfacing to the compiler.  */

void
ctf_init (void)
{
  init_ctf_container ();
}
