/* Language independent support for printing types for GDB, the GNU debugger.
   Copyright (C) 1986-2024 Free Software Foundation, Inc.

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

#ifndef GDB_TYPEPRINT_H
#define GDB_TYPEPRINT_H

#include "gdbsupport/gdb_obstack.h"
#include "gdbsupport/unordered_set.h"
#include "gdbtypes.h"
#include "hashtab.h"

enum language;
struct ui_file;
struct typedef_hash_table;
struct ext_lang_type_printers;

struct type_print_options
{
  /* True means that no special printing flags should apply.  */
  unsigned int raw : 1;

  /* True means print methods in a class.  */
  unsigned int print_methods : 1;

  /* True means print typedefs in a class.  */
  unsigned int print_typedefs : 1;

  /* True means to print offsets, a la 'pahole'.  */
  unsigned int print_offsets : 1;

  /* True means to print offsets in hex, otherwise use decimal.  */
  unsigned int print_in_hex : 1;

  /* The number of nested type definitions to print.  -1 == all.  */
  int print_nested_type_limit;

  /* If not NULL, a local typedef hash table used when printing a
     type.  */
  typedef_hash_table *local_typedefs;

  /* If not NULL, a global typedef hash table used when printing a
     type.  */
  typedef_hash_table *global_typedefs;

  /* The list of type printers associated with the global typedef
     table.  This is intentionally opaque.  */
  struct ext_lang_type_printers *global_printers;
};

struct print_offset_data
{
  /* Indicate if the offset an d size fields should be printed in decimal
     (default) or hexadecimal.  */
  bool print_in_hex  = false;

  /* The offset to be applied to bitpos when PRINT_OFFSETS is true.
     This is needed for when we are printing nested structs and want
     to make sure that the printed offset for each field carries over
     the offset of the outer struct.  */
  unsigned int offset_bitpos = 0;

  /* END_BITPOS is the one-past-the-end bit position of the previous
     field (where we expect the current field to be if there is no
     hole).  */
  unsigned int end_bitpos = 0;

  /* Print information about field at index FIELD_IDX of the struct type
     TYPE and update this object.

     If the field is static, it simply prints the correct number of
     spaces.

     The output is strongly based on pahole(1).  */
  void update (struct type *type, unsigned int field_idx,
	       struct ui_file *stream);

  /* Call when all fields have been printed.  This will print
     information about any padding that may exist.  LEVEL is the
     desired indentation level.  */
  void finish (struct type *type, int level, struct ui_file *stream);

  /* When printing the offsets of a struct and its fields (i.e.,
     'ptype /o'; type_print_options::print_offsets), we use this many
     characters when printing the offset information at the beginning
     of the line.  This is needed in order to generate the correct
     amount of whitespaces when no offset info should be printed for a
     certain field.  */
  static const int indentation;

  explicit print_offset_data (const struct type_print_options *flags);

private:

  /* Helper function for ptype/o implementation that prints
     information about a hole, if necessary.  STREAM is where to
     print.  BITPOS is the bitpos of the current field.  FOR_WHAT is a
     string describing the purpose of the hole.  */

  void maybe_print_hole (struct ui_file *stream, unsigned int bitpos,
			 const char *for_what);
};

extern const struct type_print_options type_print_raw_options;

/* A hash table holding decl_field objects.  This is more complicated than an
   ordinary hash because it must also track the lifetime of some -- but not all
   -- of the contained objects.  */

class typedef_hash_table
{
public:

  /* Create a new typedef-lookup hash table.  */
  typedef_hash_table () = default;

  /* Copy a typedef hash.  */
  typedef_hash_table (const typedef_hash_table &other)
    : m_table (other.m_table)
  {}

  typedef_hash_table &operator= (const typedef_hash_table &) = delete;

  /* Add typedefs from T to the hash table TABLE.  */
  void recursively_update (struct type *);

  /* Add template parameters from T to the typedef hash TABLE.  */
  void add_template_parameters (struct type *t);

  /* Look up the type T in the typedef hash tables contained in FLAGS.
     The local table is searched first, then the global table (either
     table can be NULL, in which case it is skipped).  If T is in a
     table, return its short (class-relative) typedef name.  Otherwise
     return NULL.  */
  static const char *find_typedef (const struct type_print_options *flags,
				   struct type *t);

private:

  static const char *find_global_typedef (const struct type_print_options *flags,
					  struct type *t);

  struct decl_field_type_hash
  {
    using is_transparent = void;

    std::size_t operator() (type *t) const noexcept
    {
      /* Use check_typedef: the hash must agree with equals, and types_equal
	 strips typedefs.  */
      return htab_hash_string (TYPE_SAFE_NAME (check_typedef (t)));
    }

    std::size_t operator() (const decl_field *f) const noexcept
    { return (*this) (f->type); }
  };

  struct decl_field_type_eq
  {
    using is_transparent = void;

    bool operator () (type *t, const decl_field *f) const noexcept
    { return types_equal (t, f->type); }

    bool operator() (const decl_field *lhs,
		     const decl_field *rhs) const noexcept
    { return (*this) (lhs->type, rhs); }
  };

  /* The actual hash table of `decl_field *` identified by their type field.  */
  gdb::unordered_set<decl_field *, decl_field_type_hash, decl_field_type_eq>
    m_table;

  /* Storage for typedef_field objects that must be synthesized.  */
  auto_obstack m_storage;
};


void print_type_scalar (struct type * type, LONGEST, struct ui_file *);

/* Assuming the TYPE is a fixed point type, print its type description
   on STREAM.  */

void print_type_fixed_point (struct type *type, struct ui_file *stream);

void c_type_print_args (struct type *, struct ui_file *, int, enum language,
			const struct type_print_options *);

/* Print <unknown return type> to stream STREAM.  */

void type_print_unknown_return_type (struct ui_file *stream);

/* Throw an error indicating that the user tried to use a symbol that
   has unknown type.  SYM_PRINT_NAME is the name of the symbol, to be
   included in the error message.  */
extern void error_unknown_type (const char *sym_print_name);

extern void val_print_not_allocated (struct ui_file *stream);

extern void val_print_not_associated (struct ui_file *stream);

#endif /* GDB_TYPEPRINT_H */
