/* Help friends in C++.
   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.

This file is part of GNU CC.

GNU CC 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 2, or (at your option)
any later version.

GNU CC 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 GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */

#include "config.h"
#include "system.h"
#include "tree.h"
#include "rtl.h"
#include "expr.h"
#include "cp-tree.h"
#include "flags.h"
#include "output.h"
#include "toplev.h"

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

/* Returns non-zero if SUPPLICANT is a friend of TYPE.  */

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

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

  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))
		{
		  if (TREE_VALUE (friends) == NULL_TREE)
		    continue;

		  if (supplicant == TREE_VALUE (friends))
		    return 1;

		  /* Temporarily, we are more lenient to deal with
		     nested friend functions, for which there can be
		     more than one FUNCTION_DECL, despite being the
		     same function.  When that's fixed, this bit can
		     go.  */
		  if (DECL_FUNCTION_MEMBER_P (supplicant)
		      && same_type_p (TREE_TYPE (supplicant),
				      TREE_TYPE (TREE_VALUE (friends))))
		    return 1;

		  if (TREE_CODE (TREE_VALUE (friends)) == TEMPLATE_DECL
		      && is_specialization_of (supplicant, 
					       TREE_VALUE (friends)))
		    return 1;
		}
	      break;
	    }
	}
    }
  else
    /* It's a type.  */
    {
      /* Nested classes are implicitly friends of their enclosing types, as
	 per core issue 45 (this is a change from the standard).  */
      for (context = supplicant;
	   context && TYPE_P (context);
	   context = TYPE_CONTEXT (context))
	if (type == context)
	  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 (TYPE_MAIN_DECL (supplicant), t) :
	      same_type_p (supplicant, t))
	    return 1;
	}
    }      

  if (declp && DECL_FUNCTION_MEMBER_P (supplicant))
    context = DECL_CONTEXT (supplicant);
  else if (! declp)
    /* Local classes have the same access as the enclosing function.  */
    context = decl_function_context (TYPE_MAIN_DECL (supplicant));
  else
    context = NULL_TREE;

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

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

  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))
		{
		  cp_warning ("`%D' is already a friend of class `%T'",
			      decl, type);
		  cp_warning_at ("previous friend declaration of `%D'",
				 TREE_VALUE (friends));
		  return;
		}
	    }
	  TREE_VALUE (list) = tree_cons (error_mark_node, decl,
					 TREE_VALUE (list));
	  return;
	}
      list = TREE_CHAIN (list);
    }

  DECL_FRIENDLIST (typedecl)
    = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, 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!  */

void
make_friend_class (type, friend_type)
     tree type, friend_type;
{
  tree classes;
  int is_template_friend;

  if (! IS_AGGR_TYPE (friend_type))
    {
      cp_error ("invalid type `%T' declared `friend'", friend_type);
      return;
    }

  if (CLASS_TYPE_P (friend_type)
      && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type)
      && uses_template_parms (friend_type))
    {
      /* [temp.friend]
	 
	 Friend declarations shall not declare partial
	 specializations.  */
      cp_error ("partial specialization `%T' declared `friend'",
		friend_type);
      return;
    }
  
  if (processing_template_decl > template_class_depth (type))
    /* If the TYPE is a template then it makes sense for it to be
       friends with itself; this means that each instantiation is
       friends with all other instantiations.  */
    is_template_friend = 1;
  else if (same_type_p (type, friend_type))
    {
      cp_pedwarn ("class `%T' is implicitly friends with itself",
	          type);
      return;
    }
  else
    is_template_friend = 0;

  /* [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 (!is_template_friend)
    ;/* ok */
  else if (TREE_CODE (friend_type) == TYPENAME_TYPE)
    {
      /* template <class T> friend typename S<T>::X; */
      cp_error ("typename type `%#T' declared `friend'", friend_type);
      return;
    }
  else if (TREE_CODE (friend_type) == TEMPLATE_TYPE_PARM)
    {
      /* template <class T> friend class T; */
      cp_error ("template parameter type `%T' declared `friend'", friend_type);
      return;
    }
  else if (!CLASSTYPE_TEMPLATE_INFO (friend_type))
    {
      /* template <class T> friend class A; where A is not a template */
      cp_error ("`%#T' is not a template", friend_type);
      return;
    }

  GNU_xref_hier (type, friend_type, 0, 0, 1);

  if (is_template_friend)
    friend_type = CLASSTYPE_TI_TEMPLATE (friend_type);

  classes = CLASSTYPE_FRIEND_CLASSES (type);
  while (classes 
	 /* Stop if we find the same type on the list.  */
	 && !(TREE_CODE (TREE_VALUE (classes)) == TEMPLATE_DECL ?
	      friend_type == TREE_VALUE (classes) :
	      same_type_p (TREE_VALUE (classes), friend_type)))
    classes = TREE_CHAIN (classes);
  if (classes) 
    cp_warning ("`%T' is already a friend of `%T'",
		TREE_VALUE (classes), type);
  else
    {
      CLASSTYPE_FRIEND_CLASSES (type)
	= tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
      if (is_template_friend)
	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)); 
    }
}

/* Main friend processor.  This is large, and for modularity purposes,
   has been removed from grokdeclarator.  It returns `void_type_node'
   to indicate that something happened, though a FIELD_DECL is
   not returned.

   CTYPE is the class this friend belongs to.

   DECLARATOR is the name of the friend.

   DECL is the FUNCTION_DECL that the friend is.

   In case we are parsing a friend which is part of an inline
   definition, we will need to store PARM_DECL chain that comes
   with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL.

   FLAGS is just used for `grokclassfn'.

   QUALS say what special qualifies should apply to the object
   pointed to by `this'.  */

tree
do_friend (ctype, declarator, decl, parmdecls, attrlist,
	   flags, quals, funcdef_flag)
     tree ctype, declarator, decl, parmdecls, attrlist;
     enum overload_flags flags;
     tree quals;
     int funcdef_flag;
{
  int is_friend_template = 0;
  tree prefix_attributes, attributes;

  /* Every decl that gets here is a friend of something.  */
  DECL_FRIEND_P (decl) = 1;

  if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
    {
      declarator = TREE_OPERAND (declarator, 0);
      if (TREE_CODE (declarator) == LOOKUP_EXPR)
	declarator = TREE_OPERAND (declarator, 0);
      if (is_overloaded_fn (declarator))
	declarator = DECL_NAME (get_first_fn (declarator));
    }

  if (TREE_CODE (decl) != FUNCTION_DECL)
    my_friendly_abort (990513);

  is_friend_template = PROCESSING_REAL_TEMPLATE_DECL_P ();

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

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

      /* This will set up DECL_ARGUMENTS for us.  */
      grokclassfn (ctype, decl, flags, quals);

      if (is_friend_template)
	decl = DECL_TI_TEMPLATE (push_template_decl (decl));
      else if (template_class_depth (current_class_type))
	decl = push_template_decl_real (decl, /*is_friend=*/1);

      /* We can't do lookup in a type that involves template
	 parameters.  Instead, we rely on tsubst_friend_function
	 to check the validity of the declaration later.  */
      if (processing_template_decl)
	add_friend (current_class_type, decl);
      /* 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.  */
      else if (COMPLETE_TYPE_P (ctype) || TYPE_BEING_DEFINED (ctype))
	{
	  decl = check_classfn (ctype, decl);

	  if (decl)
	    add_friend (current_class_type, decl);
	}
      else
	cp_error ("member `%D' declared as friend before type `%T' defined",
		  decl, ctype);
    }
  /* A global friend.
     @@ or possibly a friend from a base class ?!?  */
  else if (TREE_CODE (decl) == FUNCTION_DECL)
    {
      /* Friends must all go through the overload machinery,
	 even though they may not technically be overloaded.

	 Note that because classes all wind up being top-level
	 in their scope, their friend wind up in top-level scope as well.  */
      DECL_ARGUMENTS (decl) = parmdecls;
      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_real 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));

	  /* We can call pushdecl here, because the TREE_CHAIN of this
	     FUNCTION_DECL is not needed for other purposes.  Don't do
	     this for a template instantiation.  However, we don't
	     call pushdecl() for a friend function of a template
	     class, since in general, such a declaration depends on
	     template parameters.  Instead, we call pushdecl when the
	     class is instantiated.  */
	  if (!is_friend_template
	      && template_class_depth (current_class_type) == 0)
	    decl = pushdecl (decl);
	  else 
	    decl = push_template_decl_real (decl, /*is_friend=*/1); 

	  if (warn)
	    {
	      static int explained;
	      cp_warning ("friend declaration `%#D' declares a non-template function", decl);
	      if (! explained)
		{
		  warning ("(if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning.");
		  explained = 1;
		}
	    }
	}

      add_friend (current_class_type, 
		  is_friend_template ? DECL_TI_TEMPLATE (decl) : decl);
      DECL_FRIEND_P (decl) = 1;
    }

  /* Unfortunately, we have to handle attributes here.  Normally we would
     handle them in start_decl_1, but since this is a friend decl start_decl_1
     never gets to see it.  */

  if (attrlist)
    {
      attributes = TREE_PURPOSE (attrlist);
      prefix_attributes = TREE_VALUE (attrlist);
    }
  else
    {
      attributes = NULL_TREE;
      prefix_attributes = NULL_TREE;
    } 

#ifdef SET_DEFAULT_DECL_ATTRIBUTES
  SET_DEFAULT_DECL_ATTRIBUTES (decl, attributes);
#endif
  
  /* Set attributes here so if duplicate decl, will have proper attributes.  */
  cplus_decl_attributes (decl, attributes, prefix_attributes);

  return decl;
}
