FreeBSD/contrib/gcc/cp/class.c
/* FN is a constructor or destructor.  Clone the declaration to create
   a specialized in-charge or not-in-charge version, as indicated by
   NAME.  */
FN is a constructor or destructor.  Clone the declaration to create
a specialized in-charge or not-in-charge version, as indicated by
NAME.
FN is a constructor or destructor . Clone the declaration to create a specialized in - charge or not - in - charge version as indicated by NAME .
static tree
build_clone (tree fn, tree name)
{
  tree parms;
  tree clone;
  clone = copy_decl (fn);
  DECL_CLONED_FUNCTION (clone) = fn;
  DECL_ABSTRACT_ORIGIN (clone) = fn;
  DECL_NAME (clone) = name;
  SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
  DECL_PENDING_INLINE_INFO (clone) = NULL;
  DECL_PENDING_INLINE_P (clone) = 0;
  DECL_DEFERRED_FN (clone) = 0;
  if (name == base_dtor_identifier)
    {
      DECL_VIRTUAL_P (clone) = 0;
      if (TREE_CODE (clone) != TEMPLATE_DECL)
	DECL_VINDEX (clone) = NULL_TREE;
    }
  if (DECL_HAS_IN_CHARGE_PARM_P (clone))
    {
      tree basetype;
      tree parmtypes;
      tree exceptions;
      exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone));
      basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
      parmtypes = TYPE_ARG_TYPES (TREE_TYPE (clone));
      parmtypes = TREE_CHAIN (parmtypes);
      parmtypes = TREE_CHAIN (parmtypes);
      if (DECL_HAS_VTT_PARM_P (fn)
	  && ! DECL_NEEDS_VTT_PARM_P (clone))
	parmtypes = TREE_CHAIN (parmtypes);
      TREE_TYPE (clone)
	= build_method_type_directly (basetype,
				      TREE_TYPE (TREE_TYPE (clone)),
				      parmtypes);
      if (exceptions)
	TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone),
						     exceptions);
      TREE_TYPE (clone)
	= cp_build_type_attribute_variant (TREE_TYPE (clone),
					   TYPE_ATTRIBUTES (TREE_TYPE (fn)));
    }
  if (TREE_CODE (clone) != TEMPLATE_DECL)
    {
      DECL_ARGUMENTS (clone) = copy_list (DECL_ARGUMENTS (clone));
      if (DECL_HAS_IN_CHARGE_PARM_P (clone))
	{
	  TREE_CHAIN (DECL_ARGUMENTS (clone))
	    = TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
	  DECL_HAS_IN_CHARGE_PARM_P (clone) = 0;
	}
      if (DECL_HAS_VTT_PARM_P (fn))
	{
	  if (DECL_NEEDS_VTT_PARM_P (clone))
	    DECL_HAS_VTT_PARM_P (clone) = 1;
	  else
	    {
	      TREE_CHAIN (DECL_ARGUMENTS (clone))
		= TREE_CHAIN (TREE_CHAIN (DECL_ARGUMENTS (clone)));
	      DECL_HAS_VTT_PARM_P (clone) = 0;
	    }
	}
      for (parms = DECL_ARGUMENTS (clone); parms; parms = TREE_CHAIN (parms))
	{
	  DECL_CONTEXT (parms) = clone;
	  cxx_dup_lang_specific_decl (parms);
	}
    }
  SET_DECL_RTL (clone, NULL_RTX);
  rest_of_decl_compilation (clone, 1, at_eof);
  TREE_CHAIN (clone) = TREE_CHAIN (fn);
  TREE_CHAIN (fn) = clone;
  if (TREE_CODE (clone) == TEMPLATE_DECL)
    {
      tree result;
      DECL_TEMPLATE_RESULT (clone)
	= build_clone (DECL_TEMPLATE_RESULT (clone), name);
      result = DECL_TEMPLATE_RESULT (clone);
      DECL_TEMPLATE_INFO (result) = copy_node (DECL_TEMPLATE_INFO (result));
      DECL_TI_TEMPLATE (result) = clone;
    }
  else if (pch_file)
    note_decl_for_pch (clone);
  return clone;
}
static tree build_clone ( tree fn , tree name ) { tree parms ; tree clone ; clone = copy_decl ( fn ) ; DECL_CLONED_FUNCTION ( clone ) = fn ; DECL_ABSTRACT_ORIGIN ( clone ) = fn ; DECL_NAME ( clone ) = name ; SET_DECL_ASSEMBLER_NAME ( clone , NULL_TREE ) ; DECL_PENDING_INLINE_INFO ( clone ) = NULL ; DECL_PENDING_INLINE_P ( clone ) = 0 ; DECL_DEFERRED_FN ( clone ) = 0 ; if ( name == base_dtor_identifier ) { DECL_VIRTUAL_P ( clone ) = 0 ; if ( TREE_CODE ( clone ) != TEMPLATE_DECL ) DECL_VINDEX ( clone ) = NULL_TREE ; } if ( DECL_HAS_IN_CHARGE_PARM_P ( clone ) ) { tree basetype ; tree parmtypes ; tree exceptions ; exceptions = TYPE_RAISES_EXCEPTIONS ( TREE_TYPE ( clone ) ) ; basetype = TYPE_METHOD_BASETYPE ( TREE_TYPE ( clone ) ) ; parmtypes = TYPE_ARG_TYPES ( TREE_TYPE ( clone ) ) ; parmtypes = TREE_CHAIN ( parmtypes ) ; parmtypes = TREE_CHAIN ( parmtypes ) ; if ( DECL_HAS_VTT_PARM_P ( fn ) && ! DECL_NEEDS_VTT_PARM_P ( clone ) ) parmtypes = TREE_CHAIN ( parmtypes ) ; TREE_TYPE ( clone ) = build_method_type_directly ( basetype , TREE_TYPE ( TREE_TYPE ( clone ) ) , parmtypes ) ; if ( exceptions ) TREE_TYPE ( clone ) = build_exception_variant ( TREE_TYPE ( clone ) , exceptions ) ; TREE_TYPE ( clone ) = cp_build_type_attribute_variant ( TREE_TYPE ( clone ) , TYPE_ATTRIBUTES ( TREE_TYPE ( fn ) ) ) ; } if ( TREE_CODE ( clone ) != TEMPLATE_DECL ) { DECL_ARGUMENTS ( clone ) = copy_list ( DECL_ARGUMENTS ( clone ) ) ; if ( DECL_HAS_IN_CHARGE_PARM_P ( clone ) ) { TREE_CHAIN ( DECL_ARGUMENTS ( clone ) ) = TREE_CHAIN ( TREE_CHAIN ( DECL_ARGUMENTS ( clone ) ) ) ; DECL_HAS_IN_CHARGE_PARM_P ( clone ) = 0 ; } if ( DECL_HAS_VTT_PARM_P ( fn ) ) { if ( DECL_NEEDS_VTT_PARM_P ( clone ) ) DECL_HAS_VTT_PARM_P ( clone ) = 1 ; else { TREE_CHAIN ( DECL_ARGUMENTS ( clone ) ) = TREE_CHAIN ( TREE_CHAIN ( DECL_ARGUMENTS ( clone ) ) ) ; DECL_HAS_VTT_PARM_P ( clone ) = 0 ; } } for ( parms = DECL_ARGUMENTS ( clone ) ; parms ; parms = TREE_CHAIN ( parms ) ) { DECL_CONTEXT ( parms ) = clone ; cxx_dup_lang_specific_decl ( parms ) ; } } SET_DECL_RTL ( clone , NULL_RTX ) ; rest_of_decl_compilation ( clone , 1 , at_eof ) ; TREE_CHAIN ( clone ) = TREE_CHAIN ( fn ) ; TREE_CHAIN ( fn ) = clone ; if ( TREE_CODE ( clone ) == TEMPLATE_DECL ) { tree result ; DECL_TEMPLATE_RESULT ( clone ) = build_clone ( DECL_TEMPLATE_RESULT ( clone ) , name ) ; result = DECL_TEMPLATE_RESULT ( clone ) ; DECL_TEMPLATE_INFO ( result ) = copy_node ( DECL_TEMPLATE_INFO ( result ) ) ; DECL_TI_TEMPLATE ( result ) = clone ; } else if ( pch_file ) note_decl_for_pch ( clone ) ; return clone ; }
FN is a constructor or destructor.
FN is a constructor or destructor .
/* Copy the function.  */ /* Remember where this function came from.  */ /* Reset the function name.  */ /* There's no pending inline data for this function.  */ /* And it hasn't yet been deferred.  */ /* The base-class destructor is not virtual.  */ /* If there was an in-charge parameter, drop it from the function
     type.  */ /* Skip the `this' parameter.  */ /* Skip the in-charge parameter.  */ /* And the VTT parm, in a complete [cd]tor.  */ /* If this is subobject constructor or destructor, add the vtt
	 parameter.  */ /* Copy the function parameters.  But, DECL_ARGUMENTS on a TEMPLATE_DECL
     aren't function parameters; those are the template parameters.  */ /* Remove the in-charge parameter.  */ /* And the VTT parm, in a complete [cd]tor.  */ /* Create the RTL for this function.  */ /*top_level=*/ /* Make it easy to find the CLONE given the FN.  */ /* If this is a template, handle the DECL_TEMPLATE_RESULT as well.  */