/* Help friends in C++.
   Copyright (C) 1997-2021 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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "cp-tree.h"

/* Friend data structures are described in cp-tree.h.  */


/* The GLOBAL_FRIEND scope (functions, classes, or templates) is
   regarded as a friend of every class.  This is only used by libcc1,
   to enable GDB's code snippets to access private members without
   disabling access control in general, which could cause different
   template overload resolution results when accessibility matters
   (e.g. tests for an accessible member).  */

static GTY(()) tree global_friend;

/* Set the GLOBAL_FRIEND for this compilation session.  It might be
   set multiple times, but always to the same scope.  */

void
set_global_friend (tree scope)
{
  gcc_checking_assert (scope != NULL_TREE);
  gcc_assert (!global_friend || global_friend == scope);
  global_friend = scope;
}

/* Return TRUE if SCOPE is the global friend.  */

bool
is_global_friend (tree scope)
{
  gcc_checking_assert (scope != NULL_TREE);

  if (global_friend == scope)
    return true;

  if (!global_friend)
    return false;

  if (is_specialization_of_friend (global_friend, scope))
    return true;

  return false;
}

/* Returns nonzero if SUPPLICANT is a friend of TYPE.  */

int
is_friend (tree type, tree supplicant)
{
  int declp;
  tree list;
  tree context;

  if (supplicant == NULL_TREE || type == NULL_TREE)
    return 0;

  if (is_global_friend (supplicant))
    return 1;

  declp = DECL_P (supplicant);

  if (declp)
    /* It's a function decl.  */
    {
      tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type));
      tree name = DECL_NAME (supplicant);

      for (; list ; list = TREE_CHAIN (list))
	{
	  if (name == FRIEND_NAME (list))
	    {
	      tree friends = FRIEND_DECLS (list);
	      for (; friends ; friends = TREE_CHAIN (friends))
		{
		  tree this_friend = TREE_VALUE (friends);

		  if (this_friend == NULL_TREE)
		    continue;

		  if (supplicant == this_friend)
		    return 1;

		  if (is_specialization_of_friend (supplicant, this_friend))
		    return 1;
		}
	      break;
	    }
	}
    }
  else
    /* It's a type.  */
    {
      if (same_type_p (supplicant, type))
	return 1;

      list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type)));
      for (; list ; list = TREE_CHAIN (list))
	{
	  tree t = TREE_VALUE (list);

	  if (TREE_CODE (t) == TEMPLATE_DECL ?
	      is_specialization_of_friend (TYPE_MAIN_DECL (supplicant), t) :
	      same_type_p (supplicant, t))
	    return 1;
	}
    }

  if (declp)
    {
      if (DECL_FUNCTION_MEMBER_P (supplicant))
	context = DECL_CONTEXT (supplicant);
      else
	context = NULL_TREE;
    }
  else
    {
      if (TYPE_CLASS_SCOPE_P (supplicant))
	/* Nested classes get the same access as their enclosing types, as
	   per DR 45 (this is a change from the standard).  */
	context = TYPE_CONTEXT (supplicant);
      else
	/* Local classes have the same access as the enclosing function.  */
	context = decl_function_context (TYPE_MAIN_DECL (supplicant));
    }

  /* A namespace is not friend to anybody.  */
  if (context && TREE_CODE (context) == NAMESPACE_DECL)
    context = NULL_TREE;

  if (context)
    return is_friend (type, context);

  return 0;
}

/* Add a new friend to the friends of the aggregate type TYPE.
   DECL is the FUNCTION_DECL of the friend being added.

   If COMPLAIN is true, warning about duplicate friend is issued.
   We want to have this diagnostics during parsing but not
   when a template is being instantiated.  */

void
add_friend (tree type, tree decl, bool complain)
{
  tree typedecl;
  tree list;
  tree name;
  tree ctx;

  if (decl == error_mark_node)
    return;

  typedecl = TYPE_MAIN_DECL (type);
  list = DECL_FRIENDLIST (typedecl);
  name = DECL_NAME (decl);
  type = TREE_TYPE (typedecl);

  while (list)
    {
      if (name == FRIEND_NAME (list))
	{
	  tree friends = FRIEND_DECLS (list);
	  for (; friends ; friends = TREE_CHAIN (friends))
	    {
	      if (decl == TREE_VALUE (friends))
		{
		  if (complain)
		    warning (OPT_Wredundant_decls,
			     "%qD is already a friend of class %qT",
			     decl, type);
		  return;
		}
	    }

	  TREE_VALUE (list) = tree_cons (NULL_TREE, decl,
					 TREE_VALUE (list));
	  break;
	}
      list = TREE_CHAIN (list);
    }

  ctx = DECL_CONTEXT (decl);
  if (ctx && CLASS_TYPE_P (ctx) && !uses_template_parms (ctx))
    perform_or_defer_access_check (TYPE_BINFO (ctx), decl, decl,
				   tf_warning_or_error);

  maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);

  if (!list)
    DECL_FRIENDLIST (typedecl)
      = tree_cons (DECL_NAME (decl), build_tree_list (NULL_TREE, decl),
		   DECL_FRIENDLIST (typedecl));
  if (!uses_template_parms (type))
    DECL_BEFRIENDING_CLASSES (decl)
      = tree_cons (NULL_TREE, type,
		   DECL_BEFRIENDING_CLASSES (decl));
}

/* Make FRIEND_TYPE a friend class to TYPE.  If FRIEND_TYPE has already
   been defined, we make all of its member functions friends of
   TYPE.  If not, we make it a pending friend, which can later be added
   when its definition is seen.  If a type is defined, then its TYPE_DECL's
   DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend
   classes that are not defined.  If a type has not yet been defined,
   then the DECL_WAITING_FRIENDS contains a list of types
   waiting to make it their friend.  Note that these two can both
   be in use at the same time!

   If COMPLAIN is true, warning about duplicate friend is issued.
   We want to have this diagnostics during parsing but not
   when a template is being instantiated.  */

void
make_friend_class (tree type, tree friend_type, bool complain)
{
  tree classes;

  /* CLASS_TEMPLATE_DEPTH counts the number of template headers for
     the enclosing class.  FRIEND_DEPTH counts the number of template
     headers used for this friend declaration.  TEMPLATE_MEMBER_P,
     defined inside the `if' block for TYPENAME_TYPE case, is true if
     a template header in FRIEND_DEPTH is intended for DECLARATOR.
     For example, the code

       template <class T> struct A {
	 template <class U> struct B {
	   template <class V> template <class W>
	     friend class C<V>::D;
	 };
       };

     will eventually give the following results

     1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U').
     2. FRIEND_DEPTH equals 2 (for `V' and `W').
     3. TEMPLATE_MEMBER_P is true (for `W').

     The friend is a template friend iff FRIEND_DEPTH is nonzero.  */

  int class_template_depth = template_class_depth (type);
  int friend_depth = processing_template_decl - class_template_depth;

  if (! MAYBE_CLASS_TYPE_P (friend_type)
      && TREE_CODE (friend_type) != TEMPLATE_TEMPLATE_PARM)
    {
      /* N1791: If the type specifier in a friend declaration designates a
	 (possibly cv-qualified) class type, that class is declared as a
	 friend; otherwise, the friend declaration is ignored.

         So don't complain in C++11 mode.  */
      if (cxx_dialect < cxx11)
	pedwarn (input_location, complain ? 0 : OPT_Wpedantic,
		 "invalid type %qT declared %<friend%>", friend_type);
      return;
    }

  friend_type = cv_unqualified (friend_type);

  if (check_for_bare_parameter_packs (friend_type))
    return;

  if (friend_depth)
    {
      /* [temp.friend] Friend declarations shall not declare partial
	 specializations.  */
      if (CLASS_TYPE_P (friend_type)
	  && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type)
	  && uses_template_parms (friend_type))
	{
	  error ("partial specialization %qT declared %<friend%>",
		 friend_type);
	  return;
	}

      if (TYPE_TEMPLATE_INFO (friend_type)
	  && !PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (friend_type)))
	{
	  auto_diagnostic_group d;
	  error ("%qT is not a template", friend_type);
	  inform (location_of (friend_type), "previous declaration here");
	  if (TYPE_CLASS_SCOPE_P (friend_type)
	      && CLASSTYPE_TEMPLATE_INFO (TYPE_CONTEXT (friend_type))
	      && currently_open_class (TYPE_CONTEXT (friend_type)))
	    inform (input_location, "perhaps you need explicit template "
		    "arguments in your nested-name-specifier");
	  return;
	}
    }

  /* It makes sense for a template class to be friends with itself,
     that means the instantiations can be friendly.  Other cases are
     not so meaningful.  */
  if (!friend_depth && same_type_p (type, friend_type))
    {
      if (complain)
	warning (0, "class %qT is implicitly friends with itself",
		 type);
      return;
    }

  /* [temp.friend]

     A friend of a class or class template can be a function or
     class template, a specialization of a function template or
     class template, or an ordinary (nontemplate) function or
     class.  */
  if (!friend_depth)
    ;/* ok */
  else if (TREE_CODE (friend_type) == TYPENAME_TYPE)
    {
      if (TREE_CODE (TYPENAME_TYPE_FULLNAME (friend_type))
	  == TEMPLATE_ID_EXPR)
	{
	  /* template <class U> friend class T::X<U>; */
	  /* [temp.friend]
	     Friend declarations shall not declare partial
	     specializations.  */
	  error ("partial specialization %qT declared %<friend%>",
		 friend_type);
	  return;
	}
      else
	{
	  /* We will figure this out later.  */
	  bool template_member_p = false;

	  tree ctype = TYPE_CONTEXT (friend_type);
	  tree name = TYPE_IDENTIFIER (friend_type);
	  tree decl;

	  if (!uses_template_parms_level (ctype, class_template_depth
						 + friend_depth))
	    template_member_p = true;

	  if (class_template_depth)
	    {
	      /* We rely on tsubst_friend_class to check the
		 validity of the declaration later.  */
	      if (template_member_p)
		friend_type
		  = make_unbound_class_template (ctype,
						 name,
						 current_template_parms,
						 tf_error);
	      else
		friend_type
		  = make_typename_type (ctype, name, class_type, tf_error);
	    }
	  else
	    {
	      decl = lookup_member (ctype, name, 0, true, tf_warning_or_error);
	      if (!decl)
		{
		  error ("%qT is not a member of %qT", name, ctype);
		  return;
		}
	      if (template_member_p && !DECL_CLASS_TEMPLATE_P (decl))
		{
		  auto_diagnostic_group d;
		  error ("%qT is not a member class template of %qT",
			 name, ctype);
		  inform (DECL_SOURCE_LOCATION (decl),
			  "%qD declared here", decl);
		  return;
		}
	      if (!template_member_p && (TREE_CODE (decl) != TYPE_DECL
					 || !CLASS_TYPE_P (TREE_TYPE (decl))))
		{
		  auto_diagnostic_group d;
		  error ("%qT is not a nested class of %qT",
			 name, ctype);
		  inform (DECL_SOURCE_LOCATION (decl),
			  "%qD declared here", decl);
		  return;
		}

	      friend_type = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl));
	    }
	}
    }
  else if (TREE_CODE (friend_type) == TEMPLATE_TYPE_PARM)
    {
      /* template <class T> friend class T; */
      error ("template parameter type %qT declared %<friend%>", friend_type);
      return;
    }
  else if (TREE_CODE (friend_type) == TEMPLATE_TEMPLATE_PARM)
    friend_type = TYPE_NAME (friend_type);
  else if (!CLASSTYPE_TEMPLATE_INFO (friend_type))
    {
      /* template <class T> friend class A; where A is not a template */
      error ("%q#T is not a template", friend_type);
      return;
    }
  else
    /* template <class T> friend class A; where A is a template */
    friend_type = CLASSTYPE_TI_TEMPLATE (friend_type);

  if (friend_type == error_mark_node)
    return;

  /* See if it is already a friend.  */
  for (classes = CLASSTYPE_FRIEND_CLASSES (type);
       classes;
       classes = TREE_CHAIN (classes))
    {
      tree probe = TREE_VALUE (classes);

      if (TREE_CODE (friend_type) == TEMPLATE_DECL)
	{
	  if (friend_type == probe)
	    {
	      if (complain)
		warning (OPT_Wredundant_decls,
			 "%qD is already a friend of %qT", probe, type);
	      break;
	    }
	}
      else if (TREE_CODE (probe) != TEMPLATE_DECL)
	{
	  if (same_type_p (probe, friend_type))
	    {
	      if (complain)
		warning (OPT_Wredundant_decls,
			 "%qT is already a friend of %qT", probe, type);
	      break;
	    }
	}
    }

  if (!classes)
    {
      maybe_add_class_template_decl_list (type, friend_type, /*friend_p=*/1);

      CLASSTYPE_FRIEND_CLASSES (type)
	= tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
      if (TREE_CODE (friend_type) == TEMPLATE_DECL)
	friend_type = TREE_TYPE (friend_type);
      if (!uses_template_parms (type))
	CLASSTYPE_BEFRIENDING_CLASSES (friend_type)
	  = tree_cons (NULL_TREE, type,
		       CLASSTYPE_BEFRIENDING_CLASSES (friend_type));
    }
}

/* Record DECL (a FUNCTION_DECL) as a friend of the
   CURRENT_CLASS_TYPE.  If DECL is a member function, CTYPE is the
   class of which it is a member, as named in the friend declaration.
   DECLARATOR is the name of the friend.  FUNCDEF_FLAG is true if the
   friend declaration is a definition of the function.  FLAGS is as
   for grokclass fn.  */

tree
do_friend (tree ctype, tree declarator, tree decl,
	   enum overload_flags flags,
	   bool funcdef_flag)
{
  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
  gcc_assert (!ctype || MAYBE_CLASS_TYPE_P (ctype));

  /* Friend functions are unique, until proved otherwise.  */
  DECL_UNIQUE_FRIEND_P (decl) = 1;

  if (DECL_OVERRIDE_P (decl) || DECL_FINAL_P (decl))
    error ("friend declaration %qD may not have virt-specifiers",
	   decl);

  if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
    {
      declarator = TREE_OPERAND (declarator, 0);
      if (!identifier_p (declarator))
	declarator = OVL_NAME (declarator);
    }

  if (ctype)
    {
      /* CLASS_TEMPLATE_DEPTH counts the number of template headers for
	 the enclosing class.  FRIEND_DEPTH counts the number of template
	 headers used for this friend declaration.  TEMPLATE_MEMBER_P is
	 true if a template header in FRIEND_DEPTH is intended for
	 DECLARATOR.  For example, the code

	   template <class T> struct A {
	     template <class U> struct B {
	       template <class V> template <class W>
		 friend void C<V>::f(W);
	     };
	   };

	 will eventually give the following results

	 1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U').
	 2. FRIEND_DEPTH equals 2 (for `V' and `W').
	 3. TEMPLATE_MEMBER_P is true (for `W').  */

      int class_template_depth = template_class_depth (current_class_type);
      int friend_depth = processing_template_decl - class_template_depth;
      /* We will figure this out later.  */
      bool template_member_p = false;

      tree cname = TYPE_NAME (ctype);
      if (TREE_CODE (cname) == TYPE_DECL)
	cname = DECL_NAME (cname);

      /* A method friend.  */
      if (flags == NO_SPECIAL && declarator == cname)
	DECL_CXX_CONSTRUCTOR_P (decl) = 1;

      grokclassfn (ctype, decl, flags);

      if (friend_depth)
	{
	  if (!uses_template_parms_level (ctype, class_template_depth
						 + friend_depth))
	    template_member_p = true;
	}

      /* A nested class may declare a member of an enclosing class
	 to be a friend, so we do lookup here even if CTYPE is in
	 the process of being defined.  */
      if (class_template_depth
	  || COMPLETE_OR_OPEN_TYPE_P (ctype))
	{
	  if (DECL_TEMPLATE_INFO (decl))
	    /* DECL is a template specialization.  No need to
	       build a new TEMPLATE_DECL.  */
	    ;
	  else if (class_template_depth)
	    /* We rely on tsubst_friend_function to check the
	       validity of the declaration later.  */
	    decl = push_template_decl (decl, /*is_friend=*/true);
	  else
	    decl = check_classfn (ctype, decl,
				  template_member_p
				  ? current_template_parms
				  : NULL_TREE);

	  if ((template_member_p
	       /* Always pull out the TEMPLATE_DECL if we have a friend
		  template in a class template so that it gets tsubsted
		  properly later on (59956).  tsubst_friend_function knows
		  how to tell this apart from a member template.  */
	       || (class_template_depth && friend_depth))
	      && decl && TREE_CODE (decl) == FUNCTION_DECL)
	    decl = DECL_TI_TEMPLATE (decl);

	  if (decl)
	    add_friend (current_class_type, decl, /*complain=*/true);
	}
      else
	error ("member %qD declared as friend before type %qT defined",
		  decl, ctype);
    }
  else
    {
      /* Namespace-scope friend function.  */
      int is_friend_template = PROCESSING_REAL_TEMPLATE_DECL_P ();

      if (funcdef_flag)
	SET_DECL_FRIEND_CONTEXT (decl, current_class_type);

      if (! DECL_USE_TEMPLATE (decl))
	{
	  /* We must check whether the decl refers to template
	     arguments before push_template_decl adds a reference to
	     the containing template class.  */
	  int warn = (warn_nontemplate_friend
		      && ! funcdef_flag && ! is_friend_template
		      && current_template_parms
		      && uses_template_parms (decl));

	  if (is_friend_template
	      || template_class_depth (current_class_type) != 0)
	    /* We can't call pushdecl for a template class, since in
	       general, such a declaration depends on template
	       parameters.  Instead, we call pushdecl when the class
	       is instantiated.  */
	    decl = push_template_decl (decl, /*is_friend=*/true);
	  else if (current_function_decl)
	    /* pushdecl will check there's a local decl already.  */
	    decl = pushdecl (decl, /*hiding=*/true);
	  else
	    {
	      /* We can't use pushdecl, as we might be in a template
		 class specialization, and pushdecl will insert an
		 unqualified friend decl into the template parameter
		 scope, rather than the namespace containing it.  */
	      tree ns = decl_namespace_context (decl);

	      push_nested_namespace (ns);
	      decl = pushdecl_namespace_level (decl, /*hiding=*/true);
	      pop_nested_namespace (ns);
	    }

	  if (warn)
	    {
	      static int explained;
	      bool warned;

	      auto_diagnostic_group d;
	      warned = warning (OPT_Wnon_template_friend, "friend declaration "
				"%q#D declares a non-template function", decl);
	      if (! explained && warned)
		{
		  inform (input_location, "(if this is not what you intended, "
			  "make sure the function template has already been "
			  "declared and add %<<>%> after the function name "
			  "here)");
		  explained = 1;
		}
	    }
	}

      if (decl == error_mark_node)
	return error_mark_node;

      add_friend (current_class_type,
		  is_friend_template ? DECL_TI_TEMPLATE (decl) : decl,
		  /*complain=*/true);
    }

  return decl;
}

#include "gt-cp-friend.h"
