/* DWARF attributes

   Copyright (C) 1994-2021 Free Software Foundation, Inc.

   Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
   Inc.  with support from Florida State University (under contract
   with the Ada Joint Program Office), and Silicon Graphics, Inc.
   Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
   based on Fred Fish's (Cygnus Support) implementation of DWARF 1
   support.

   This file is part of GDB.

   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 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "dwarf2/attribute.h"
#include "dwarf2/stringify.h"
#include "complaints.h"

/* See attribute.h.  */

CORE_ADDR
attribute::as_address () const
{
  CORE_ADDR addr;

  gdb_assert (!requires_reprocessing);

  if (form != DW_FORM_addr && form != DW_FORM_addrx
      && form != DW_FORM_GNU_addr_index)
    {
      /* Aside from a few clearly defined exceptions, attributes that
	 contain an address must always be in DW_FORM_addr form.
	 Unfortunately, some compilers happen to be violating this
	 requirement by encoding addresses using other forms, such
	 as DW_FORM_data4 for example.  For those broken compilers,
	 we try to do our best, without any guarantee of success,
	 to interpret the address correctly.  It would also be nice
	 to generate a complaint, but that would require us to maintain
	 a list of legitimate cases where a non-address form is allowed,
	 as well as update callers to pass in at least the CU's DWARF
	 version.  This is more overhead than what we're willing to
	 expand for a pretty rare case.  */
      addr = u.unsnd;
    }
  else
    addr = u.addr;

  return addr;
}

/* See attribute.h.  */

bool
attribute::form_is_string () const
{
  return (form == DW_FORM_strp || form == DW_FORM_line_strp
	  || form == DW_FORM_string
	  || form == DW_FORM_strx
	  || form == DW_FORM_strx1
	  || form == DW_FORM_strx2
	  || form == DW_FORM_strx3
	  || form == DW_FORM_strx4
	  || form == DW_FORM_GNU_str_index
	  || form == DW_FORM_GNU_strp_alt);
}

/* See attribute.h.  */

const char *
attribute::as_string () const
{
  gdb_assert (!requires_reprocessing);
  if (form_is_string ())
    return u.str;
  return nullptr;
}

/* See attribute.h.  */

bool
attribute::form_is_block () const
{
  return (form == DW_FORM_block1
	  || form == DW_FORM_block2
	  || form == DW_FORM_block4
	  || form == DW_FORM_block
	  || form == DW_FORM_exprloc
	  || form == DW_FORM_data16);
}

/* See attribute.h.  */

bool
attribute::form_is_section_offset () const
{
  return (form == DW_FORM_data4
	  || form == DW_FORM_data8
	  || form == DW_FORM_sec_offset
	  || form == DW_FORM_loclistx);
}

/* See attribute.h.  */

bool
attribute::form_is_constant () const
{
  switch (form)
    {
    case DW_FORM_sdata:
    case DW_FORM_udata:
    case DW_FORM_data1:
    case DW_FORM_data2:
    case DW_FORM_data4:
    case DW_FORM_data8:
    case DW_FORM_implicit_const:
      return true;
    default:
      return false;
    }
}

/* See attribute.h.  */

void
attribute::get_ref_die_offset_complaint () const
{
  complaint (_("unsupported die ref attribute form: '%s'"),
	     dwarf_form_name (form));
}

/* See attribute.h.  */

LONGEST
attribute::constant_value (int default_value) const
{
  if (form == DW_FORM_sdata || form == DW_FORM_implicit_const)
    return u.snd;
  else if (form == DW_FORM_udata
	   || form == DW_FORM_data1
	   || form == DW_FORM_data2
	   || form == DW_FORM_data4
	   || form == DW_FORM_data8)
    return u.unsnd;
  else
    {
      /* For DW_FORM_data16 see attribute::form_is_constant.  */
      complaint (_("Attribute value is not a constant (%s)"),
		 dwarf_form_name (form));
      return default_value;
    }
}

/* See attribute.h.  */

bool
attribute::form_is_unsigned () const
{
  return (form == DW_FORM_ref_addr
	  || form == DW_FORM_GNU_ref_alt
	  || form == DW_FORM_data2
	  || form == DW_FORM_data4
	  || form == DW_FORM_data8
	  || form == DW_FORM_sec_offset
	  || form == DW_FORM_data1
	  || form == DW_FORM_flag
	  || form == DW_FORM_flag_present
	  || form == DW_FORM_udata
	  || form == DW_FORM_rnglistx
	  || form == DW_FORM_loclistx
	  || form == DW_FORM_ref1
	  || form == DW_FORM_ref2
	  || form == DW_FORM_ref4
	  || form == DW_FORM_ref8
	  || form == DW_FORM_ref_udata);
}

/* See attribute.h.  */

bool
attribute::form_is_signed () const
{
  return form == DW_FORM_sdata || form == DW_FORM_implicit_const;
}

/* See attribute.h.  */

bool
attribute::form_requires_reprocessing () const
{
  return (form == DW_FORM_strx
	  || form == DW_FORM_strx1
	  || form == DW_FORM_strx2
	  || form == DW_FORM_strx3
	  || form == DW_FORM_strx4
	  || form == DW_FORM_GNU_str_index
	  || form == DW_FORM_addrx
	  || form == DW_FORM_GNU_addr_index
	  || form == DW_FORM_rnglistx
	  || form == DW_FORM_loclistx);
}

/* See attribute.h.  */

dwarf_defaulted_attribute
attribute::defaulted () const
{
  LONGEST value = constant_value (-1);

  switch (value)
    {
    case DW_DEFAULTED_no:
    case DW_DEFAULTED_in_class:
    case DW_DEFAULTED_out_of_class:
      return (dwarf_defaulted_attribute) value;
    }

  /* If the form was not constant, we already complained in
     constant_value, so there's no need to complain again.  */
  if (form_is_constant ())
    complaint (_("unrecognized DW_AT_defaulted value (%s)"),
	       plongest (value));
  return DW_DEFAULTED_no;
}

/* See attribute.h.  */

dwarf_virtuality_attribute
attribute::as_virtuality () const
{
  LONGEST value = constant_value (-1);

  switch (value)
    {
    case DW_VIRTUALITY_none:
    case DW_VIRTUALITY_virtual:
    case DW_VIRTUALITY_pure_virtual:
      return (dwarf_virtuality_attribute) value;
    }

  /* If the form was not constant, we already complained in
     constant_value, so there's no need to complain again.  */
  if (form_is_constant ())
    complaint (_("unrecognized DW_AT_virtuality value (%s)"),
	       plongest (value));
  return DW_VIRTUALITY_none;
}

/* See attribute.h.  */

bool
attribute::as_boolean () const
{
  if (form == DW_FORM_flag_present)
    return true;
  else if (form == DW_FORM_flag)
    return u.unsnd != 0;
  return constant_value (0) != 0;
}
