/* Representation of thunks inside symbol table.
   Copyright (C) 2003-2021 Free Software Foundation, Inc.
   Contributed by Jan Hubicka

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/>.  */

#ifndef GCC_SYMTAB_THUNKS_H
#define GCC_SYMTAB_THUNKS_H

/* This symbol annotation holds information about thunk.

   Thunks are basically wrappers around methods which are introduced in case
   of multiple inheritance in order to adjust the value of the "this" pointer
   or of the returned value.

   In the case of this-adjusting thunks, each back-end can override the
   can_output_mi_thunk/output_mi_thunk target hooks to generate a minimal thunk
   (with a tail call for instance) directly as assembly.  For the default hook
   or for the case where the can_output_mi_thunk hooks return false, the thunk
   is gimplified and lowered using the regular machinery.  */

struct GTY(()) thunk_info {
  /* Constructor.  */
  thunk_info ()
    : fixed_offset (0),
      virtual_value (0),
      indirect_offset (0),
      alias (NULL),
      this_adjusting (false),
      virtual_offset_p (false)
  {
  }
  /* Copy constructor.  */
  thunk_info (const thunk_info &t)
    : fixed_offset (t.fixed_offset),
      virtual_value (t.virtual_value),
      indirect_offset (t.indirect_offset),
      alias (t.alias),
      this_adjusting (t.this_adjusting),
      virtual_offset_p (t.virtual_offset_p)
  {
  }

  /* Compare for equiality.  */
  bool
  operator==(const thunk_info &other) const
  {
    return fixed_offset == other.fixed_offset
	   && virtual_value == other.virtual_value
	   && indirect_offset == other.indirect_offset
	   && this_adjusting == other.this_adjusting
	   && virtual_offset_p == other.virtual_offset_p;
  }
  bool
  operator!=(const thunk_info &other) const
  {
    return !(*this == other);
  }
  /* Copy operator.  */
  thunk_info &
  operator=(const thunk_info &other)
  {
    fixed_offset = other.fixed_offset;
    virtual_value = other.virtual_value;
    indirect_offset = other.indirect_offset;
    alias = other.alias;
    this_adjusting = other.this_adjusting;
    virtual_offset_p = other.virtual_offset_p;
    return *this;
  }

  /* Offset used to adjust "this".  */
  HOST_WIDE_INT fixed_offset;

  /* Offset in the virtual table to get the offset to adjust "this".  Valid iff
     VIRTUAL_OFFSET_P is true.  */
  HOST_WIDE_INT virtual_value;

  /* Offset from "this" to get the offset to adjust "this".  Zero means: this
     offset is to be ignored.  */
  HOST_WIDE_INT indirect_offset;

  /* Thunk target, i.e. the method that this thunk wraps.  Depending on the
     TARGET_USE_LOCAL_THUNK_ALIAS_P macro, this may have to be a new alias.  */
  tree alias;

  /* Nonzero for a "this" adjusting thunk and zero for a result adjusting
     thunk.  */
  bool this_adjusting;

  /* If true, this thunk is what we call a virtual thunk.  In this case:
     * for this-adjusting thunks, after the FIXED_OFFSET based adjustment is
       done, add to the result the offset found in the vtable at:
	 vptr + VIRTUAL_VALUE
     * for result-adjusting thunks, the FIXED_OFFSET adjustment is done after
       the virtual one.  */
  bool virtual_offset_p;



  /* Dump thunk_info.  */
  void dump (FILE *);

  /* Stream out thunk_info.  */
  void stream_out (class lto_simple_output_block *);

  /* Stream in trunk_info.  */
  void stream_in (class lto_input_block *);

  hashval_t hash ();



  /* Return thunk_info, if available.  */
  static thunk_info *get (cgraph_node *node);

  /* Return thunk_info possibly creating new one.  */
  static thunk_info *get_create (cgraph_node *node);

  /* Remove thunk_info.  */
  static void remove (cgraph_node *node);

  /* Add unprocessed thunk.  */
  void register_early (cgraph_node *node);

  /* Attach recorded thunks to cgraph_nodes.  */
  static void process_early_thunks ();

  /* Release all thunk_infos.  */
  static void release (void);
};

bool expand_thunk (cgraph_node *, bool, bool);

/* Return thunk_info, if available.  */
inline thunk_info *
thunk_info::get (cgraph_node *node)
{
  if (!symtab->m_thunks)
    return NULL;
  return symtab->m_thunks->get (node);
}

/* Remove thunk_info association for NODE.  */
inline void
thunk_info::remove (cgraph_node *node)
{
  symtab->m_thunks->remove (node);
}

/* Free thunk info summaries.  */
inline void
thunk_info::release ()
{
  if (symtab->m_thunks)
    ggc_delete (symtab->m_thunks);
  symtab->m_thunks = NULL;
}
#endif  /* GCC_SYMTAB_THUNKS_H  */
