Example #1
0
static void
pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
{
  tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
  tree types =
    TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
  const bool abstract = args == NULL
    || pp_c_base (pp)->flags & pp_c_flag_abstract;
  bool first = true;

  /* Skip artificial parameter for nonstatic member functions.  */
  if (TREE_CODE (t) == METHOD_TYPE)
    types = TREE_CHAIN (types);

  pp_cxx_left_paren (pp);
  for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
    {
      if (!first)
	pp_cxx_separate_with (pp, ',');
      first = false;
      pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
      if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument)
	{
	  pp_cxx_whitespace (pp);
	  pp_equal (pp);
	  pp_cxx_whitespace (pp);
	  pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
	}
    }
  pp_cxx_right_paren (pp);
}
Example #2
0
static void
do_build_copy_constructor (tree fndecl)
{
    tree parm = FUNCTION_FIRST_USER_PARM (fndecl);

    parm = convert_from_reference (parm);

    if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)
            && is_empty_class (current_class_type))
        /* Don't copy the padding byte; it might not have been allocated
           if *this is a base subobject.  */;
    else if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type))
    {
        tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm);
        finish_expr_stmt (t);
    }
    else
    {
        tree fields = TYPE_FIELDS (current_class_type);
        tree member_init_list = NULL_TREE;
        int cvquals = cp_type_quals (TREE_TYPE (parm));
        int i;
        tree binfo, base_binfo;
        VEC(tree,gc) *vbases;

        /* Initialize all the base-classes with the parameter converted
        to their type so that we get their copy constructor and not
         another constructor that takes current_class_type.  We must
         deal with the binfo's directly as a direct base might be
         inaccessible due to ambiguity.  */
        for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
                VEC_iterate (tree, vbases, i, binfo); i++)
        {
            member_init_list
                = tree_cons (binfo,
                             build_tree_list (NULL_TREE,
                                              build_base_path (PLUS_EXPR, parm,
                                                      binfo, 1)),
                             member_init_list);
        }

        for (binfo = TYPE_BINFO (current_class_type), i = 0;
                BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
        {
            if (BINFO_VIRTUAL_P (base_binfo))
                continue;

            member_init_list
                = tree_cons (base_binfo,
                             build_tree_list (NULL_TREE,
                                              build_base_path (PLUS_EXPR, parm,
                                                      base_binfo, 1)),
                             member_init_list);
        }

        for (; fields; fields = TREE_CHAIN (fields))
        {
            tree init = parm;
            tree field = fields;
            tree expr_type;

            if (TREE_CODE (field) != FIELD_DECL)
                continue;

            expr_type = TREE_TYPE (field);
            if (DECL_NAME (field))
            {
                if (VFIELD_NAME_P (DECL_NAME (field)))
                    continue;
            }
            else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type))
                /* Just use the field; anonymous types can't have
                   nontrivial copy ctors or assignment ops.  */;
            else
                continue;

            /* Compute the type of "init->field".  If the copy-constructor
               parameter is, for example, "const S&", and the type of
               the field is "T", then the type will usually be "const
               T".  (There are no cv-qualified variants of reference
               types.)  */
            if (TREE_CODE (expr_type) != REFERENCE_TYPE)
            {
                int quals = cvquals;

                if (DECL_MUTABLE_P (field))
                    quals &= ~TYPE_QUAL_CONST;
                expr_type = cp_build_qualified_type (expr_type, quals);
            }

            init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
            init = build_tree_list (NULL_TREE, init);

            member_init_list = tree_cons (field, init, member_init_list);
        }
        finish_mem_initializers (member_init_list);
    }
}