FreeBSD/contrib/gcc/cp/call.c
/* Build a call to a constructor, destructor, or an assignment
   operator for INSTANCE, an expression with class type.  NAME
   indicates the special member function to call; ARGS are the
   arguments.  BINFO indicates the base of INSTANCE that is to be
   passed as the `this' parameter to the member function called.

   FLAGS are the LOOKUP_* flags to use when processing the call.

   If NAME indicates a complete object constructor, INSTANCE may be
   NULL_TREE.  In this case, the caller will call build_cplus_new to
   store the newly constructed object into a VAR_DECL.  */
Build a call to a constructor, destructor, or an assignment
operator for INSTANCE, an expression with class type.  NAME
indicates the special member function to call; ARGS are the
arguments.  BINFO indicates the base of INSTANCE that is to be
passed as the `this' parameter to the member function called.

FLAGS are the LOOKUP_* flags to use when processing the call.

If NAME indicates a complete object constructor, INSTANCE may be
NULL_TREE.  In this case, the caller will call build_cplus_new to
store the newly constructed object into a VAR_DECL.
Build a call to a constructor destructor or an assignment operator for INSTANCE an expression with class type . NAME indicates the special member function to call ; ARGS are the arguments . BINFO indicates the base of INSTANCE that is to be passed as the ` this ' parameter to the member function called . FLAGS are the LOOKUP_ * flags to use when processing the call . If NAME indicates a complete object constructor INSTANCE may be NULL_TREE . In this case the caller will call build_cplus_new to store the newly constructed object into a VAR_DECL .
tree
build_special_member_call (tree instance, tree name, tree args,
			   tree binfo, int flags)
{
  tree fns;
  tree class_type;
  gcc_assert (name == complete_ctor_identifier
	      || name == base_ctor_identifier
	      || name == complete_dtor_identifier
	      || name == base_dtor_identifier
	      || name == deleting_dtor_identifier
	      || name == ansi_assopname (NOP_EXPR));
  if (TYPE_P (binfo))
    {
      if (!complete_type_or_else (binfo, NULL_TREE))
	return error_mark_node;
      binfo = TYPE_BINFO (binfo);
    }
  gcc_assert (binfo != NULL_TREE);
  class_type = BINFO_TYPE (binfo);
  if (name == complete_ctor_identifier && !instance)
    {
      instance = build_int_cst (build_pointer_type (class_type), 0);
      instance = build1 (INDIRECT_REF, class_type, instance);
    }
  else
    {
      if (name == complete_dtor_identifier
	  || name == base_dtor_identifier
	  || name == deleting_dtor_identifier)
	gcc_assert (args == NULL_TREE);
      if (!same_type_ignoring_top_level_qualifiers_p
	  (TREE_TYPE (instance), BINFO_TYPE (binfo)))
	{
	  if (name != ansi_assopname (NOP_EXPR))
	    instance = convert_to_base_statically (instance, binfo);
	  else
	    instance = build_base_path (PLUS_EXPR, instance,
					binfo, 1);
	}
    }
  gcc_assert (instance != NULL_TREE);
  fns = lookup_fnfields (binfo, name, 1);
  if ((name == base_ctor_identifier
       || name == base_dtor_identifier)
      && CLASSTYPE_VBASECLASSES (class_type))
    {
      tree vtt;
      tree sub_vtt;
      vtt = TREE_CHAIN (CLASSTYPE_VTABLES (current_class_type));
      vtt = decay_conversion (vtt);
      vtt = build3 (COND_EXPR, TREE_TYPE (vtt),
		    build2 (EQ_EXPR, boolean_type_node,
			    current_in_charge_parm, integer_zero_node),
		    current_vtt_parm,
		    vtt);
      gcc_assert (BINFO_SUBVTT_INDEX (binfo));
      sub_vtt = build2 (PLUS_EXPR, TREE_TYPE (vtt), vtt,
			BINFO_SUBVTT_INDEX (binfo));
      args = tree_cons (NULL_TREE, sub_vtt, args);
    }
  return build_new_method_call (instance, fns, args,
				TYPE_BINFO (BINFO_TYPE (binfo)),
				flags, NULL);
}
tree build_special_member_call ( tree instance , tree name , tree args , tree binfo , int flags ) { tree fns ; tree class_type ; gcc_assert ( name == complete_ctor_identifier || name == base_ctor_identifier || name == complete_dtor_identifier || name == base_dtor_identifier || name == deleting_dtor_identifier || name == ansi_assopname ( NOP_EXPR ) ) ; if ( TYPE_P ( binfo ) ) { if ( ! complete_type_or_else ( binfo , NULL_TREE ) ) return error_mark_node ; binfo = TYPE_BINFO ( binfo ) ; } gcc_assert ( binfo != NULL_TREE ) ; class_type = BINFO_TYPE ( binfo ) ; if ( name == complete_ctor_identifier && ! instance ) { instance = build_int_cst ( build_pointer_type ( class_type ) , 0 ) ; instance = build1 ( INDIRECT_REF , class_type , instance ) ; } else { if ( name == complete_dtor_identifier || name == base_dtor_identifier || name == deleting_dtor_identifier ) gcc_assert ( args == NULL_TREE ) ; if ( ! same_type_ignoring_top_level_qualifiers_p ( TREE_TYPE ( instance ) , BINFO_TYPE ( binfo ) ) ) { if ( name != ansi_assopname ( NOP_EXPR ) ) instance = convert_to_base_statically ( instance , binfo ) ; else instance = build_base_path ( PLUS_EXPR , instance , binfo , 1 ) ; } } gcc_assert ( instance != NULL_TREE ) ; fns = lookup_fnfields ( binfo , name , 1 ) ; if ( ( name == base_ctor_identifier || name == base_dtor_identifier ) && CLASSTYPE_VBASECLASSES ( class_type ) ) { tree vtt ; tree sub_vtt ; vtt = TREE_CHAIN ( CLASSTYPE_VTABLES ( current_class_type ) ) ; vtt = decay_conversion ( vtt ) ; vtt = build3 ( COND_EXPR , TREE_TYPE ( vtt ) , build2 ( EQ_EXPR , boolean_type_node , current_in_charge_parm , integer_zero_node ) , current_vtt_parm , vtt ) ; gcc_assert ( BINFO_SUBVTT_INDEX ( binfo ) ) ; sub_vtt = build2 ( PLUS_EXPR , TREE_TYPE ( vtt ) , vtt , BINFO_SUBVTT_INDEX ( binfo ) ) ; args = tree_cons ( NULL_TREE , sub_vtt , args ) ; } return build_new_method_call ( instance , fns , args , TYPE_BINFO ( BINFO_TYPE ( binfo ) ) , flags , NULL ) ; }
Build a call to a constructor, destructor, or an assignment
operator for INSTANCE, an expression with class type.
Build a call to a constructor destructor or an assignment operator for INSTANCE an expression with class type .
/* The type of the subobject to be constructed or destroyed.  */ /* Resolve the name.  */ /* Handle the special case where INSTANCE is NULL_TREE.  */ /* Convert to the base class, if necessary.  */ /* For constructors and destructors, either the base is
	       non-virtual, or it is virtual but we are doing the
	       conversion from a constructor or destructor for the
	       complete object.  In either case, we can convert
	       statically.  */ /* However, for assignment operators, we must convert
	       dynamically if the base is virtual.  */ /*nonnull=*/ /* When making a call to a constructor or destructor for a subobject
     that uses virtual base classes, pass down a pointer to a VTT for
     the subobject.  */ /* If the current function is a complete object constructor
	 or destructor, then we fetch the VTT directly.
	 Otherwise, we look it up using the VTT we were given.  */ /*fn=*/