/* Copyright (C) 2006-2021 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 COMMON_TDESC_H
#define COMMON_TDESC_H

struct tdesc_feature;
struct tdesc_type;
struct tdesc_type_builtin;
struct tdesc_type_vector;
struct tdesc_type_with_fields;
struct tdesc_reg;
struct target_desc;

/* The interface to visit different elements of target description.  */

class tdesc_element_visitor
{
public:
  virtual void visit_pre (const target_desc *e)
  {}

  virtual void visit_post (const target_desc *e)
  {}

  virtual void visit_pre (const tdesc_feature *e)
  {}

  virtual void visit_post (const tdesc_feature *e)
  {}

  virtual void visit (const tdesc_type_builtin *e)
  {}

  virtual void visit (const tdesc_type_vector *e)
  {}

  virtual void visit (const tdesc_type_with_fields *e)
  {}

  virtual void visit (const tdesc_reg *e)
  {}
};

class tdesc_element
{
public:
  virtual void accept (tdesc_element_visitor &v) const = 0;
};

/* An individual register from a target description.  */

struct tdesc_reg : tdesc_element
{
  tdesc_reg (struct tdesc_feature *feature, const std::string &name_,
	     int regnum, int save_restore_, const char *group_,
	     int bitsize_, const char *type_);

  virtual ~tdesc_reg () = default;

  DISABLE_COPY_AND_ASSIGN (tdesc_reg);

  /* The name of this register.  In standard features, it may be
     recognized by the architecture support code, or it may be purely
     for the user.  */
  std::string name;

  /* The register number used by this target to refer to this
     register.  This is used for remote p/P packets and to determine
     the ordering of registers in the remote g/G packets.  */
  long target_regnum;

  /* If this flag is set, GDB should save and restore this register
     around calls to an inferior function.  */
  int save_restore;

  /* The name of the register group containing this register, or empty
     if the group should be automatically determined from the
     register's type.  If this is "general", "float", or "vector", the
     corresponding "info" command should display this register's
     value.  It can be an arbitrary string, but should be limited to
     alphanumeric characters and internal hyphens.  Currently other
     strings are ignored (treated as empty).  */
  std::string group;

  /* The size of the register, in bits.  */
  int bitsize;

  /* The type of the register.  This string corresponds to either
     a named type from the target description or a predefined
     type from GDB.  */
  std::string type;

  /* The target-described type corresponding to TYPE, if found.  */
  struct tdesc_type *tdesc_type;

  void accept (tdesc_element_visitor &v) const override
  {
    v.visit (this);
  }

  bool operator== (const tdesc_reg &other) const
  {
    return (name == other.name
       && target_regnum == other.target_regnum
       && save_restore == other.save_restore
       && bitsize == other.bitsize
       && group == other.group
       && type == other.type);
  }

  bool operator!= (const tdesc_reg &other) const
  {
    return !(*this == other);
  }
};

typedef std::unique_ptr<tdesc_reg> tdesc_reg_up;

/* Declaration of a structure that holds information about one
   "compatibility" entry within a target description.  */

struct tdesc_compatible_info;

/* A pointer to a single piece of compatibility information.  */

typedef std::unique_ptr<tdesc_compatible_info> tdesc_compatible_info_up;

/* Return a vector of compatibility information pointers from the target
   description TARGET_DESC.  */

const std::vector<tdesc_compatible_info_up> &tdesc_compatible_info_list
	(const target_desc *target_desc);

/* Return the architecture name from a compatibility information
   COMPATIBLE.  */

const char *tdesc_compatible_info_arch_name
	(const tdesc_compatible_info_up &compatible);

enum tdesc_type_kind
{
  /* Predefined types.  */
  TDESC_TYPE_BOOL,
  TDESC_TYPE_INT8,
  TDESC_TYPE_INT16,
  TDESC_TYPE_INT32,
  TDESC_TYPE_INT64,
  TDESC_TYPE_INT128,
  TDESC_TYPE_UINT8,
  TDESC_TYPE_UINT16,
  TDESC_TYPE_UINT32,
  TDESC_TYPE_UINT64,
  TDESC_TYPE_UINT128,
  TDESC_TYPE_CODE_PTR,
  TDESC_TYPE_DATA_PTR,
  TDESC_TYPE_IEEE_HALF,
  TDESC_TYPE_IEEE_SINGLE,
  TDESC_TYPE_IEEE_DOUBLE,
  TDESC_TYPE_ARM_FPA_EXT,
  TDESC_TYPE_I387_EXT,
  TDESC_TYPE_BFLOAT16,

  /* Types defined by a target feature.  */
  TDESC_TYPE_VECTOR,
  TDESC_TYPE_STRUCT,
  TDESC_TYPE_UNION,
  TDESC_TYPE_FLAGS,
  TDESC_TYPE_ENUM
};

struct tdesc_type : tdesc_element
{
  tdesc_type (const std::string &name_, enum tdesc_type_kind kind_)
    : name (name_), kind (kind_)
  {}

  virtual ~tdesc_type () = default;

  DISABLE_COPY_AND_ASSIGN (tdesc_type);

  /* The name of this type.  */
  std::string name;

  /* Identify the kind of this type.  */
  enum tdesc_type_kind kind;

  bool operator== (const tdesc_type &other) const
  {
    return name == other.name && kind == other.kind;
  }

  bool operator!= (const tdesc_type &other) const
  {
    return !(*this == other);
  }
};

typedef std::unique_ptr<tdesc_type> tdesc_type_up;

struct tdesc_type_builtin : tdesc_type
{
  tdesc_type_builtin (const std::string &name, enum tdesc_type_kind kind)
  : tdesc_type (name, kind)
  {}

  void accept (tdesc_element_visitor &v) const override
  {
    v.visit (this);
  }
};

/* tdesc_type for vector types.  */

struct tdesc_type_vector : tdesc_type
{
  tdesc_type_vector (const std::string &name, tdesc_type *element_type_,
		     int count_)
  : tdesc_type (name, TDESC_TYPE_VECTOR),
    element_type (element_type_), count (count_)
  {}

  void accept (tdesc_element_visitor &v) const override
  {
    v.visit (this);
  }

  struct tdesc_type *element_type;
  int count;
};

/* A named type from a target description.  */

struct tdesc_type_field
{
  tdesc_type_field (const std::string &name_, tdesc_type *type_,
		    int start_, int end_)
  : name (name_), type (type_), start (start_), end (end_)
  {}

  std::string name;
  struct tdesc_type *type;
  /* For non-enum-values, either both are -1 (non-bitfield), or both are
     not -1 (bitfield).  For enum values, start is the value (which could be
     -1), end is -1.  */
  int start, end;
};

/* tdesc_type for struct, union, flags, and enum types.  */

struct tdesc_type_with_fields : tdesc_type
{
  tdesc_type_with_fields (const std::string &name, tdesc_type_kind kind,
			  int size_ = 0)
  : tdesc_type (name, kind), size (size_)
  {}

  void accept (tdesc_element_visitor &v) const override
  {
    v.visit (this);
  }

  std::vector<tdesc_type_field> fields;
  int size;
};

/* A feature from a target description.  Each feature is a collection
   of other elements, e.g. registers and types.  */

struct tdesc_feature : tdesc_element
{
  tdesc_feature (const std::string &name_)
    : name (name_)
  {}

  virtual ~tdesc_feature () = default;

  DISABLE_COPY_AND_ASSIGN (tdesc_feature);

  /* The name of this feature.  It may be recognized by the architecture
     support code.  */
  std::string name;

  /* The registers associated with this feature.  */
  std::vector<tdesc_reg_up> registers;

  /* The types associated with this feature.  */
  std::vector<tdesc_type_up> types;

  void accept (tdesc_element_visitor &v) const override;

  bool operator== (const tdesc_feature &other) const;

  bool operator!= (const tdesc_feature &other) const
  {
    return !(*this == other);
  }
};

typedef std::unique_ptr<tdesc_feature> tdesc_feature_up;

/* A deleter adapter for a target_desc.  There are different
   implementations of this deleter class in gdb and gdbserver because even
   though the target_desc name is shared between the two projects, the
   actual implementations of target_desc are completely different.  */

struct target_desc_deleter
{
  void operator() (struct target_desc *desc) const;
};

/* A unique pointer specialization that holds a target_desc.  */

typedef std::unique_ptr<target_desc, target_desc_deleter> target_desc_up;

/* Allocate a new target_desc.  */
target_desc_up allocate_target_description (void);

/* Set TARGET_DESC's architecture by NAME.  */
void set_tdesc_architecture (target_desc *target_desc,
			     const char *name);

/* Return the architecture associated with this target description as a string,
   or NULL if no architecture was specified.  */
const char *tdesc_architecture_name (const struct target_desc *target_desc);

/* Set TARGET_DESC's osabi by NAME.  */
void set_tdesc_osabi (target_desc *target_desc, const char *name);

/* Return the osabi associated with this target description as a string,
   or NULL if no osabi was specified.  */
const char *tdesc_osabi_name (const struct target_desc *target_desc);

/* Return the type associated with ID in the context of FEATURE, or
   NULL if none.  */
struct tdesc_type *tdesc_named_type (const struct tdesc_feature *feature,
				     const char *id);

/* Return the created feature named NAME in target description TDESC.  */
struct tdesc_feature *tdesc_create_feature (struct target_desc *tdesc,
					    const char *name);

/* Return the created vector tdesc_type named NAME in FEATURE.  */
struct tdesc_type *tdesc_create_vector (struct tdesc_feature *feature,
					const char *name,
					struct tdesc_type *field_type,
					int count);

/* Return the created struct tdesc_type named NAME in FEATURE.  */
tdesc_type_with_fields *tdesc_create_struct (struct tdesc_feature *feature,
					     const char *name);

/* Return the created union tdesc_type named NAME in FEATURE.  */
tdesc_type_with_fields *tdesc_create_union (struct tdesc_feature *feature,
					    const char *name);

/* Return the created flags tdesc_type named NAME in FEATURE.  */
tdesc_type_with_fields *tdesc_create_flags (struct tdesc_feature *feature,
					    const char *name,
					    int size);

/* Return the created enum tdesc_type named NAME in FEATURE.  */
tdesc_type_with_fields *tdesc_create_enum (struct tdesc_feature *feature,
					   const char *name,
					   int size);

/* Add a new field to TYPE.  FIELD_NAME is its name, and FIELD_TYPE is
   its type.  */
void tdesc_add_field (tdesc_type_with_fields *type, const char *field_name,
		      struct tdesc_type *field_type);

/* Add a new bitfield to TYPE, with range START to END.  FIELD_NAME is its name,
   and FIELD_TYPE is its type.  */
void tdesc_add_typed_bitfield (tdesc_type_with_fields *type,
			       const char *field_name,
			       int start, int end,
			       struct tdesc_type *field_type);

/* Set the total length of TYPE.  Structs which contain bitfields may
   omit the reserved bits, so the end of the last field may not
   suffice.  */
void tdesc_set_struct_size (tdesc_type_with_fields *type, int size);

/* Add a new untyped bitfield to TYPE.
   Untyped bitfields become either uint32 or uint64 depending on the size
   of the underlying type.  */
void tdesc_add_bitfield (tdesc_type_with_fields *type, const char *field_name,
			 int start, int end);

/* A flag is just a typed(bool) single-bit bitfield.
   This function is kept to minimize changes in generated files.  */
void tdesc_add_flag (tdesc_type_with_fields *type, int start,
		     const char *flag_name);

/* Add field with VALUE and NAME to the enum TYPE.  */
void tdesc_add_enum_value (tdesc_type_with_fields *type, int value,
			   const char *name);

/* Create a register in feature FEATURE.  */
void tdesc_create_reg (struct tdesc_feature *feature, const char *name,
		       int regnum, int save_restore, const char *group,
		       int bitsize, const char *type);

/* Return the tdesc in string XML format.  */

const char *tdesc_get_features_xml (const target_desc *tdesc);

/* Print target description as xml.  */

class print_xml_feature : public tdesc_element_visitor
{
public:
  print_xml_feature (std::string *buffer_)
    : m_buffer (buffer_),
      m_depth (0)
  {}

  void visit_pre (const target_desc *e) override;
  void visit_post (const target_desc *e) override;
  void visit_pre (const tdesc_feature *e) override;
  void visit_post (const tdesc_feature *e) override;
  void visit (const tdesc_type_builtin *type) override;
  void visit (const tdesc_type_vector *type) override;
  void visit (const tdesc_type_with_fields *type) override;
  void visit (const tdesc_reg *reg) override;

private:

  /* Called with a positive value of ADJUST when we move inside an element,
     for example inside <target>, and with a negative value when we leave
     the element.  In this class this function does nothing, but a
     sub-class can override this to track the current level of nesting.  */
  void indent (int adjust)
  {
    m_depth += (adjust * 2);
  }

  /* Functions to add lines to the output buffer M_BUFFER.  Each of these
     functions appends a newline, so don't include one in the strings being
     passed.  */
  void add_line (const std::string &str);
  void add_line (const char *fmt, ...) ATTRIBUTE_PRINTF (2, 3);

  /* The buffer we are writing too.  */
  std::string *m_buffer;

  /* The current indentation depth.  */
  int m_depth;
};

#endif /* COMMON_TDESC_H */
