/* Language-level data type conversion for GNU C++.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
tree
convert_from_reference (tree val)
{
- if (TREE_CODE (TREE_TYPE (val)) == REFERENCE_TYPE)
+ if (TREE_TYPE (val)
+ && TREE_CODE (TREE_TYPE (val)) == REFERENCE_TYPE)
{
- tree t = canonical_type_variant (TREE_TYPE (TREE_TYPE (val)));
+ tree t = TREE_TYPE (TREE_TYPE (val));
tree ref = build1 (INDIRECT_REF, t, val);
/* We *must* set TREE_READONLY when dereferencing a pointer to const,
return expr;
}
+
\f
+/* Fold away simple conversions, but make sure the result is an rvalue. */
+
+tree
+cp_fold_convert (tree type, tree expr)
+{
+ return rvalue (fold_convert (type, expr));
+}
+
/* C++ conversions, preference to static cast conversions. */
tree
result = cp_convert (type, expr);
- if (!skip_evaluation && !TREE_OVERFLOW_P (expr) && result != error_mark_node)
+ if (c_inhibit_evaluation_warnings == 0
+ && !TREE_OVERFLOW_P (expr)
+ && result != error_mark_node)
warnings_for_convert_and_check (type, expr, result);
return result;
tree e = expr;
enum tree_code code = TREE_CODE (type);
const char *invalid_conv_diag;
+ tree e1;
if (error_operand_p (e) || type == error_mark_node)
return error_mark_node;
}
}
+ e1 = targetm.convert_to_type (type, e);
+ if (e1)
+ return e1;
+
if (code == VOID_TYPE && (convtype & CONV_STATIC))
{
e = convert_to_void (e, /*implicit=*/NULL, tf_warning_or_error);
the target with the temp (see [dcl.init]). */
ctor = build_user_type_conversion (type, ctor, flags);
else
- ctor = build_special_member_call (NULL_TREE,
- complete_ctor_identifier,
- build_tree_list (NULL_TREE, ctor),
- type, flags,
- tf_warning_or_error);
+ {
+ VEC(tree,gc) *ctor_vec = make_tree_vector_single (ctor);
+ ctor = build_special_member_call (NULL_TREE,
+ complete_ctor_identifier,
+ &ctor_vec,
+ type, flags,
+ tf_warning_or_error);
+ release_tree_vector (ctor_vec);
+ }
if (ctor)
return build_cplus_new (type, ctor);
}
/* The two parts of a cond expr might be separate lvalues. */
tree op1 = TREE_OPERAND (expr,1);
tree op2 = TREE_OPERAND (expr,2);
+ bool side_effects = TREE_SIDE_EFFECTS (op1) || TREE_SIDE_EFFECTS (op2);
tree new_op1 = convert_to_void
- (op1, (implicit && !TREE_SIDE_EFFECTS (op2)
+ (op1, (implicit && !side_effects
? "second operand of conditional" : NULL), complain);
tree new_op2 = convert_to_void
- (op2, (implicit && !TREE_SIDE_EFFECTS (op1)
+ (op2, (implicit && !side_effects
? "third operand of conditional" : NULL), complain);
expr = build3 (COND_EXPR, TREE_TYPE (new_op1),
&& !AGGR_INIT_VIA_CTOR_P (init))
{
tree fn = AGGR_INIT_EXPR_FN (init);
- expr = build_call_array (TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
- fn,
- aggr_init_expr_nargs (init),
- AGGR_INIT_EXPR_ARGP (init));
+ expr = build_call_array_loc (input_location,
+ TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
+ fn,
+ aggr_init_expr_nargs (init),
+ AGGR_INIT_EXPR_ARGP (init));
}
}
break;
default:;
}
+ expr = resolve_nondeduced_context (expr);
{
tree probe = expr;
if (!TYPE_HAS_CONVERSION (basetype))
return NULL_TREE;
- for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))
+ for (conv = lookup_conversions (basetype, /*lookup_template_convs_p=*/true);
+ conv;
+ conv = TREE_CHAIN (conv))
{
int win = 0;
tree candidate;
tree cand = TREE_VALUE (conv);
+ cand = OVL_CURRENT (cand);
if (winner && winner == cand)
continue;
tree
type_promotes_to (tree type)
{
+ tree promoted_type;
+
if (type == error_mark_node)
return error_mark_node;
type = TYPE_MAIN_VARIANT (type);
+ /* Check for promotions of target-defined types first. */
+ promoted_type = targetm.promoted_type (type);
+ if (promoted_type)
+ return promoted_type;
+
/* bool always promotes to int (not unsigned), even if it's the same
size. */
- if (type == boolean_type_node)
+ if (TREE_CODE (type) == BOOLEAN_TYPE)
type = integer_type_node;
/* Normally convert enums to int, but convert wide enums to something