FreeBSD/contrib/gcc/cp/method.c
/* Implicitly declare the special function indicated by KIND, as a
   member of TYPE.  For copy constructors and assignment operators,
   CONST_P indicates whether these functions should take a const
   reference argument or a non-const reference.  Returns the
   FUNCTION_DECL for the implicitly declared function.  */
Implicitly declare the special function indicated by KIND, as a
member of TYPE.  For copy constructors and assignment operators,
CONST_P indicates whether these functions should take a const
reference argument or a non-const reference.  Returns the
FUNCTION_DECL for the implicitly declared function.
Implicitly declare the special function indicated by KIND as a member of TYPE . For copy constructors and assignment operators CONST_P indicates whether these functions should take a const reference argument or a non - const reference . Returns the FUNCTION_DECL for the implicitly declared function .
static tree
implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
{
  tree fn;
  tree parameter_types = void_list_node;
  tree return_type;
  tree fn_type;
  tree raises = empty_except_spec;
  tree rhs_parm_type = NULL_TREE;
  tree this_parm;
  tree name;
  HOST_WIDE_INT saved_processing_template_decl;
  gcc_assert (!dependent_type_p (type));
  saved_processing_template_decl = processing_template_decl;
  processing_template_decl = 0;
  type = TYPE_MAIN_VARIANT (type);
  if (targetm.cxx.cdtor_returns_this () && !TYPE_FOR_JAVA (type))
    {
      if (kind == sfk_destructor)
	return_type = build_pointer_type (void_type_node);
      else
	return_type = build_pointer_type (type);
    }
  else
    return_type = void_type_node;
  switch (kind)
    {
    case sfk_destructor:
      name = constructor_name (type);
      raises = synthesize_exception_spec (type, &locate_dtor, 0);
      break;
    case sfk_constructor:
      name = constructor_name (type);
      raises = synthesize_exception_spec (type, &locate_ctor, 0);
      break;
    case sfk_copy_constructor:
    case sfk_assignment_operator:
    {
      struct copy_data data;
      data.name = NULL;
      data.quals = 0;
      if (kind == sfk_assignment_operator)
	{
	  return_type = build_reference_type (type);
	  name = ansi_assopname (NOP_EXPR);
	  data.name = name;
	}
      else
	name = constructor_name (type);
      if (const_p)
	{
	  data.quals = TYPE_QUAL_CONST;
	  rhs_parm_type = build_qualified_type (type, TYPE_QUAL_CONST);
	}
      else
	rhs_parm_type = type;
      rhs_parm_type = build_reference_type (rhs_parm_type);
      parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
      raises = synthesize_exception_spec (type, &locate_copy, &data);
      break;
    }
    default:
      gcc_unreachable ();
    }
  fn_type = build_method_type_directly (type, return_type, parameter_types);
  if (raises)
    fn_type = build_exception_variant (fn_type, raises);
  fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
  DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
  if (kind == sfk_constructor || kind == sfk_copy_constructor)
    DECL_CONSTRUCTOR_P (fn) = 1;
  else if (kind == sfk_destructor)
    DECL_DESTRUCTOR_P (fn) = 1;
  else
    {
      DECL_ASSIGNMENT_OPERATOR_P (fn) = 1;
      SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR);
    }
  if (rhs_parm_type)
    {
      DECL_ARGUMENTS (fn) = cp_build_parm_decl (NULL_TREE, rhs_parm_type);
      TREE_READONLY (DECL_ARGUMENTS (fn)) = 1;
    }
  this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED);
  TREE_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
  DECL_ARGUMENTS (fn) = this_parm;
  grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL);
  set_linkage_according_to_type (type, fn);
  rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
  DECL_IN_AGGR_P (fn) = 1;
  DECL_ARTIFICIAL (fn) = 1;
  DECL_NOT_REALLY_EXTERN (fn) = 1;
  DECL_DECLARED_INLINE_P (fn) = 1;
  DECL_INLINE (fn) = 1;
  gcc_assert (!TREE_USED (fn));
  processing_template_decl = saved_processing_template_decl;
  return fn;
}
static tree implicitly_declare_fn ( special_function_kind kind , tree type , bool const_p ) { tree fn ; tree parameter_types = void_list_node ; tree return_type ; tree fn_type ; tree raises = empty_except_spec ; tree rhs_parm_type = NULL_TREE ; tree this_parm ; tree name ; HOST_WIDE_INT saved_processing_template_decl ; gcc_assert ( ! dependent_type_p ( type ) ) ; saved_processing_template_decl = processing_template_decl ; processing_template_decl = 0 ; type = TYPE_MAIN_VARIANT ( type ) ; if ( targetm . cxx . cdtor_returns_this ( ) && ! TYPE_FOR_JAVA ( type ) ) { if ( kind == sfk_destructor ) return_type = build_pointer_type ( void_type_node ) ; else return_type = build_pointer_type ( type ) ; } else return_type = void_type_node ; switch ( kind ) { case sfk_destructor : name = constructor_name ( type ) ; raises = synthesize_exception_spec ( type , & locate_dtor , 0 ) ; break ; case sfk_constructor : name = constructor_name ( type ) ; raises = synthesize_exception_spec ( type , & locate_ctor , 0 ) ; break ; case sfk_copy_constructor : case sfk_assignment_operator : { struct copy_data data ; data . name = NULL ; data . quals = 0 ; if ( kind == sfk_assignment_operator ) { return_type = build_reference_type ( type ) ; name = ansi_assopname ( NOP_EXPR ) ; data . name = name ; } else name = constructor_name ( type ) ; if ( const_p ) { data . quals = TYPE_QUAL_CONST ; rhs_parm_type = build_qualified_type ( type , TYPE_QUAL_CONST ) ; } else rhs_parm_type = type ; rhs_parm_type = build_reference_type ( rhs_parm_type ) ; parameter_types = tree_cons ( NULL_TREE , rhs_parm_type , parameter_types ) ; raises = synthesize_exception_spec ( type , & locate_copy , & data ) ; break ; } default : gcc_unreachable ( ) ; } fn_type = build_method_type_directly ( type , return_type , parameter_types ) ; if ( raises ) fn_type = build_exception_variant ( fn_type , raises ) ; fn = build_lang_decl ( FUNCTION_DECL , name , fn_type ) ; DECL_SOURCE_LOCATION ( fn ) = DECL_SOURCE_LOCATION ( TYPE_NAME ( type ) ) ; if ( kind == sfk_constructor || kind == sfk_copy_constructor ) DECL_CONSTRUCTOR_P ( fn ) = 1 ; else if ( kind == sfk_destructor ) DECL_DESTRUCTOR_P ( fn ) = 1 ; else { DECL_ASSIGNMENT_OPERATOR_P ( fn ) = 1 ; SET_OVERLOADED_OPERATOR_CODE ( fn , NOP_EXPR ) ; } if ( rhs_parm_type ) { DECL_ARGUMENTS ( fn ) = cp_build_parm_decl ( NULL_TREE , rhs_parm_type ) ; TREE_READONLY ( DECL_ARGUMENTS ( fn ) ) = 1 ; } this_parm = build_this_parm ( fn_type , TYPE_UNQUALIFIED ) ; TREE_CHAIN ( this_parm ) = DECL_ARGUMENTS ( fn ) ; DECL_ARGUMENTS ( fn ) = this_parm ; grokclassfn ( type , fn , kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL ) ; set_linkage_according_to_type ( type , fn ) ; rest_of_decl_compilation ( fn , toplevel_bindings_p ( ) , at_eof ) ; DECL_IN_AGGR_P ( fn ) = 1 ; DECL_ARTIFICIAL ( fn ) = 1 ; DECL_NOT_REALLY_EXTERN ( fn ) = 1 ; DECL_DECLARED_INLINE_P ( fn ) = 1 ; DECL_INLINE ( fn ) = 1 ; gcc_assert ( ! TREE_USED ( fn ) ) ; processing_template_decl = saved_processing_template_decl ; return fn ; }
Implicitly declare the special function indicated by KIND, as a
member of TYPE.
Implicitly declare the special function indicated by KIND as a member of TYPE .
/* Because we create declarations for implicitly declared functions
     lazily, we may be creating the declaration for a member of TYPE
     while in some completely different context.  However, TYPE will
     never be a dependent class (because we never want to do lookups
     for implicitly defined functions in a dependent class).
     Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here
     because we only create clones for constructors and destructors
     when not in a template.  */ /* See comment in check_special_function_return_type.  */ /* Destructor.  */ /* Default constructor.  */ /* Create the function.  */ /* Create the explicit arguments.  */ /* Note that this parameter is *not* marked DECL_ARTIFICIAL; we
	 want its type to be included in the mangled function
	 name.  */ /* Add the "this" parameter.  */ /* Restore PROCESSING_TEMPLATE_DECL.  */