/* Declarations and definitions dealing with attribute handling.
   Copyright (C) 2013-2024 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/>.  */

#ifndef GCC_ATTRIBS_H
#define GCC_ATTRIBS_H

/* A set of attributes that belong to the same namespace, given by NS.  */
struct scoped_attribute_specs
{
  const char *ns;
  array_slice<const attribute_spec> attributes;
};

extern const struct attribute_spec *lookup_attribute_spec (const_tree);
extern void free_attr_data ();
extern void init_attributes (void);

/* Process the attributes listed in ATTRIBUTES and install them in *NODE,
   which is either a DECL (including a TYPE_DECL) or a TYPE.  If a DECL,
   it should be modified in place; if a TYPE, a copy should be created
   unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS.  FLAGS gives further
   information, in the form of a bitwise OR of flags in enum attribute_flags
   from tree.h.  Depending on these flags, some attributes may be
   returned to be applied at a later stage (for example, to apply
   a decl attribute to the declaration rather than to its type).  */
extern tree decl_attributes (tree *, tree, int, tree = NULL_TREE);

extern bool cxx11_attribute_p (const_tree);
extern tree get_attribute_name (const_tree);
extern tree get_attribute_namespace (const_tree);
extern void apply_tm_attr (tree, tree);
extern tree make_attribute (const char *, const char *, tree);
extern bool attribute_ignored_p (tree);
extern bool attribute_ignored_p (const attribute_spec *const);
extern bool any_nonignored_attribute_p (tree);

extern struct scoped_attributes *
  register_scoped_attributes (const scoped_attribute_specs &, bool = false);

extern char *sorted_attr_string (tree);
extern bool common_function_versions (tree, tree);
extern tree make_dispatcher_decl (const tree);
extern bool is_function_default_version (const tree);
extern void handle_ignored_attributes_option (vec<char *> *);

/* Return a type like TTYPE except that its TYPE_ATTRIBUTES
   is ATTRIBUTE.

   Such modified types already made are recorded so that duplicates
   are not made.  */

extern tree build_type_attribute_variant (tree, tree);
extern tree build_decl_attribute_variant (tree, tree);
extern tree build_type_attribute_qual_variant (tree, tree, int);

extern bool simple_cst_list_equal (const_tree, const_tree);
extern bool attribute_value_equal (const_tree, const_tree);

/* Return 0 if the attributes for two types are incompatible, 1 if they
   are compatible, and 2 if they are nearly compatible (which causes a
   warning to be generated).  */
extern int comp_type_attributes (const_tree, const_tree);

extern tree affects_type_identity_attributes (tree, bool = true);
extern tree restrict_type_identity_attributes_to (tree, tree);

/* Default versions of target-overridable functions.  */
extern tree merge_decl_attributes (tree, tree);
extern tree merge_type_attributes (tree, tree);

/* Remove any instances of attribute ATTR_NAME in LIST and return the
   modified list.  */

extern tree remove_attribute (const char *, tree);

/* Similarly but also with specific attribute namespace.  */

extern tree remove_attribute (const char *, const char *, tree);

/* Given two attributes lists, return a list of their union.  */

extern tree merge_attributes (tree, tree);

/* Duplicate all attributes with name NAME in ATTR list to *ATTRS if
   they are missing there.  */

extern void duplicate_one_attribute (tree *, tree, const char *);

/* Duplicate all attributes from user DECL to the corresponding
   builtin that should be propagated.  */

extern void copy_attributes_to_builtin (tree);

/* Given two Windows decl attributes lists, possibly including
   dllimport, return a list of their union .  */
extern tree merge_dllimport_decl_attributes (tree, tree);

/* Handle a "dllimport" or "dllexport" attribute.  */
extern tree handle_dll_attribute (tree *, tree, tree, int, bool *);

extern int attribute_list_equal (const_tree, const_tree);
extern int attribute_list_contained (const_tree, const_tree);

/* The backbone of lookup_attribute().  ATTR_LEN is the string length
   of ATTR_NAME, and LIST is not NULL_TREE.

   The function is called from lookup_attribute in order to optimize
   for size.  */
extern tree private_lookup_attribute (const char *attr_name, size_t attr_len,
				      tree list);
extern tree private_lookup_attribute (const char *attr_ns,
				      const char *attr_name,
				      size_t attr_ns_len, size_t attr_len,
				      tree list);

extern unsigned decls_mismatched_attributes (tree, tree, tree,
					     const char* const[],
					     pretty_printer*);

extern void maybe_diag_alias_attributes (tree, tree);

/* For a given string S of length L, strip leading and trailing '_' characters
   so that we have a canonical form of attribute names.  NB: This function may
   change S and L.  */

template <typename T>
inline bool
canonicalize_attr_name (const char *&s, T &l)
{
  if (l > 4 && s[0] == '_' && s[1] == '_' && s[l - 1] == '_' && s[l - 2] == '_')
    {
      s += 2;
      l -= 4;
      return true;
    }
  return false;
}

/* For a given IDENTIFIER_NODE, strip leading and trailing '_' characters
   so that we have a canonical form of attribute names.  */

inline tree
canonicalize_attr_name (tree attr_name)
{
  size_t l = IDENTIFIER_LENGTH (attr_name);
  const char *s = IDENTIFIER_POINTER (attr_name);

  if (canonicalize_attr_name (s, l))
    return get_identifier_with_length (s, l);

  return attr_name;
}

/* Compare attribute identifiers ATTR1 and ATTR2 with length ATTR1_LEN and
   ATTR2_LEN.  */

inline bool
cmp_attribs (const char *attr1, size_t attr1_len,
	     const char *attr2, size_t attr2_len)
{
  return attr1_len == attr2_len && strncmp (attr1, attr2, attr1_len) == 0;
}

/* Compare attribute identifiers ATTR1 and ATTR2.  */

inline bool
cmp_attribs (const char *attr1, const char *attr2)
{
  return cmp_attribs (attr1, strlen (attr1), attr2, strlen (attr2));
}

/* Given an identifier node IDENT and a string ATTR_NAME, return true
   if the identifier node is a valid attribute name for the string.  */

inline bool
is_attribute_p (const char *attr_name, const_tree ident)
{
  return cmp_attribs (attr_name, strlen (attr_name),
		      IDENTIFIER_POINTER (ident), IDENTIFIER_LENGTH (ident));
}

/* Given an attribute ATTR and a string ATTR_NS, return true
   if the attribute namespace is valid for the string.  ATTR_NS "" stands
   for standard attribute (NULL get_attribute_namespace) or "gnu"
   namespace.  */

inline bool
is_attribute_namespace_p (const char *attr_ns, const_tree attr)
{
  tree ident = get_attribute_namespace (attr);
  if (attr_ns == NULL)
    return ident == NULL_TREE;
  if (attr_ns[0])
    return ident && is_attribute_p (attr_ns, ident);
  return ident == NULL_TREE || is_attribute_p ("gnu", ident);
}

/* Given an attribute name ATTR_NAME and a list of attributes LIST,
   return a pointer to the attribute's list element if the attribute
   is part of the list, or NULL_TREE if not found.  If the attribute
   appears more than once, this only returns the first occurrence; the
   TREE_CHAIN of the return value should be passed back in if further
   occurrences are wanted.  ATTR_NAME must be in the form 'text' (not
   '__text__').  */

inline tree
lookup_attribute (const char *attr_name, tree list)
{
  if (CHECKING_P && attr_name[0] != '_')
    {
      size_t attr_len = strlen (attr_name);
      gcc_checking_assert (!canonicalize_attr_name (attr_name, attr_len));
    }
  /* In most cases, list is NULL_TREE.  */
  if (list == NULL_TREE)
    return NULL_TREE;
  else
    {
      size_t attr_len = strlen (attr_name);
      /* Do the strlen() before calling the out-of-line implementation.
	 In most cases attr_name is a string constant, and the compiler
	 will optimize the strlen() away.  */
      return private_lookup_attribute (attr_name, attr_len, list);
    }
}

/* Similar to lookup_attribute, but also match the attribute namespace.
   ATTR_NS "" stands for either standard attribute or "gnu" namespace.  */

inline tree
lookup_attribute (const char *attr_ns, const char *attr_name, tree list)
{
  if (CHECKING_P && attr_name[0] != '_')
    {
      size_t attr_len = strlen (attr_name);
      gcc_checking_assert (!canonicalize_attr_name (attr_name, attr_len));
    }
  if (CHECKING_P && attr_ns && attr_ns[0] != '_')
    {
      size_t attr_ns_len = strlen (attr_ns);
      gcc_checking_assert (!canonicalize_attr_name (attr_ns, attr_ns_len));
    }
  /* In most cases, list is NULL_TREE.  */
  if (list == NULL_TREE)
    return NULL_TREE;
  else
    {
      size_t attr_ns_len = attr_ns ? strlen (attr_ns) : 0;
      size_t attr_len = strlen (attr_name);
      /* Do the strlen() before calling the out-of-line implementation.
	 In most cases attr_name is a string constant, and the compiler
	 will optimize the strlen() away.  */
      return private_lookup_attribute (attr_ns, attr_name,
				       attr_ns_len, attr_len, list);
    }
}

/* Given an attribute name ATTR_NAME and a list of attributes LIST,
   return a pointer to the attribute's list first element if the attribute
   starts with ATTR_NAME.  ATTR_NAME must be in the form 'text' (not
   '__text__').  */

inline tree
lookup_attribute_by_prefix (const char *attr_name, tree list)
{
  gcc_checking_assert (attr_name[0] != '_');
  /* In most cases, list is NULL_TREE.  */
  if (list == NULL_TREE)
    return NULL_TREE;
  else
    {
      size_t attr_len = strlen (attr_name);
      while (list)
	{
	  tree name = get_attribute_name (list);
	  size_t ident_len = IDENTIFIER_LENGTH (name);

	  if (attr_len > ident_len)
	    {
	      list = TREE_CHAIN (list);
	      continue;
	    }

	  const char *p = IDENTIFIER_POINTER (name);
	  gcc_checking_assert (attr_len == 0 || p[0] != '_'
			       || (ident_len > 1 && p[1] != '_'));
	  if (strncmp (attr_name, p, attr_len) == 0)
	    break;

	  list = TREE_CHAIN (list);
	}

      return list;
    }
}

/* Description of a function argument declared with attribute access.
   Used as an "iterator" over all such arguments in a function declaration
   or call.  */

struct attr_access
{
  /* The beginning and end of the internal string representation.  */
  const char *str, *end;
  /* The attribute pointer argument.  */
  tree ptr;
  /* For a declaration, a TREE_CHAIN of VLA bound expressions stored
     in TREE_VALUE and their positions in the argument list (stored
     in TREE_PURPOSE).  Each expression may be a PARM_DECL or some
     other DECL (for ordinary variables), or an EXPR for other
     expressions (e.g., function calls).  */
  tree size;

  /* The zero-based position of each of the formal function arguments.
     For the optional SIZARG, UINT_MAX when not specified.  For VLAs
     with multiple variable bounds, SIZARG is the position corresponding
     to the most significant bound in the argument list.  Positions of
     subsequent bounds are in the TREE_PURPOSE field of the SIZE chain.  */
  unsigned ptrarg;
  unsigned sizarg;
  /* For internal specifications only, the constant minimum size of
     the array, zero if not specified, and HWI_M1U for the unspecified
     VLA [*] notation.  Meaningless for external (explicit) access
     specifications.  */
  unsigned HOST_WIDE_INT minsize;

  /* The access mode.  */
  access_mode mode;

  /* Set for an attribute added internally rather than by an explicit
     declaration. */
  bool internal_p;
  /* Set for the T[static MINSIZE] array notation for nonzero MINSIZE
     less than HWI_M1U.  */
  bool static_p;

  /* Return the number of specified VLA bounds.  */
  unsigned vla_bounds (unsigned *) const;

  /* Return internal representation as STRING_CST.  */
  tree to_internal_string () const;

  /* Return the human-readable representation of the external attribute
     specification (as it might appear in the source code) as STRING_CST.  */
  tree to_external_string () const;

  /* Return argument of array type formatted as a readable string.  */
  std::string array_as_string (tree) const;

  /* Return the access mode corresponding to the character code.  */
  static access_mode from_mode_char (char);

  /* Reset front end-specific attribute access data from attributes.  */
  static void free_lang_data (tree);

  /* The character codes corresponding to all the access modes.  */
  static constexpr char mode_chars[5] = { '-', 'r', 'w', 'x', '^' };

  /* The strings corresponding to just the external access modes.  */
  static constexpr char mode_names[4][11] =
    {
     "none", "read_only", "write_only", "read_write"
    };
};

inline access_mode
attr_access::from_mode_char (char c)
{
  switch (c)
    {
    case mode_chars[access_none]: return access_none;
    case mode_chars[access_read_only]: return access_read_only;
    case mode_chars[access_write_only]: return access_write_only;
    case mode_chars[access_read_write]: return access_read_write;
    case mode_chars[access_deferred]: return access_deferred;
    }
  gcc_unreachable ();
}

/* Used to define rdwr_map below.  */
struct rdwr_access_hash: int_hash<int, -1> { };

/* A mapping between argument number corresponding to attribute access
   mode (read_only, write_only, or read_write) and operands.  */
struct attr_access;
typedef hash_map<rdwr_access_hash, attr_access> rdwr_map;

extern void init_attr_rdwr_indices (rdwr_map *, tree);
extern attr_access *get_parm_access (rdwr_map &, tree,
				     tree = current_function_decl);

#endif // GCC_ATTRIBS_H
