/* A scope ref in a template, left as SCOPE_REF to support later
access checking. */
case SCOPE_REF:
- gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE(ref)));
- return lvalue_kind (TREE_OPERAND (ref, 1));
+ {
+ tree op = TREE_OPERAND (ref, 1);
+ /* The member must be an lvalue; assume it isn't a bit-field. */
+ if (TREE_CODE (op) == IDENTIFIER_NODE)
+ return clk_ordinary;
+ gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE (ref)));
+ return lvalue_kind (op);
+ }
case MAX_EXPR:
case MIN_EXPR:
return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)));
case NON_DEPENDENT_EXPR:
- /* We used to just return clk_ordinary for NON_DEPENDENT_EXPR because
- it was safe enough for C++98, but in C++0x lvalues don't bind to
- rvalue references, so we get bogus errors (c++/44870). */
- return lvalue_kind (TREE_OPERAND (ref, 0));
+ /* We just return clk_ordinary for NON_DEPENDENT_EXPR in C++98, but
+ in C++11 lvalues don't bind to rvalue references, so we need to
+ work harder to avoid bogus errors (c++/44870). */
+ if (cxx_dialect < cxx0x)
+ return clk_ordinary;
+ else
+ return lvalue_kind (TREE_OPERAND (ref, 0));
default:
if (!TREE_TYPE (ref))
tree type = TREE_TYPE (VEC_INIT_EXPR_SLOT (expr));
tree init, elt_init;
if (VEC_INIT_EXPR_VALUE_INIT (expr))
- init = void_zero_node;
+ init = void_type_node;
else
init = VEC_INIT_EXPR_INIT (expr);
}
}
else
- t = build_array_type (elt_type, index_type);
+ {
+ if (!TYPE_STRUCTURAL_EQUALITY_P (elt_type)
+ && !(index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type))
+ && (TYPE_CANONICAL (elt_type) != elt_type
+ || (index_type && TYPE_CANONICAL (index_type) != index_type)))
+ /* Make sure that the canonical type is on the appropriate
+ variants list. */
+ build_cplus_array_type
+ (TYPE_CANONICAL (elt_type),
+ index_type ? TYPE_CANONICAL (index_type) : index_type);
+ t = build_array_type (elt_type, index_type);
+ }
/* We want TYPE_MAIN_VARIANT of an array to strip cv-quals from the
element type as well, so fix it up if needed. */
{
tree m = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type),
index_type);
+
if (TYPE_MAIN_VARIANT (t) != m)
{
TYPE_MAIN_VARIANT (t) = m;
TREE_CHAIN (*igo_prev) = new_binfo;
*igo_prev = new_binfo;
- if (binfo)
+ if (binfo && !BINFO_DEPENDENT_BASE_P (binfo))
{
int ix;
tree base_binfo;
- gcc_assert (!BINFO_DEPENDENT_BASE_P (binfo));
gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), type));
BINFO_OFFSET (new_binfo) = BINFO_OFFSET (binfo);
for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
{
tree new_base_binfo;
-
- gcc_assert (!BINFO_DEPENDENT_BASE_P (base_binfo));
new_base_binfo = copy_binfo (base_binfo, BINFO_TYPE (base_binfo),
t, igo_prev,
BINFO_VIRTUAL_P (base_binfo));
|| TREE_CODE (x) == OVERLOAD);
}
+/* X is the CALL_EXPR_FN of a CALL_EXPR. If X represents a dependent name
+ (14.6.2), return the IDENTIFIER_NODE for that name. Otherwise, return
+ NULL_TREE. */
+
+tree
+dependent_name (tree x)
+{
+ if (TREE_CODE (x) == IDENTIFIER_NODE)
+ return x;
+ if (TREE_CODE (x) != COMPONENT_REF
+ && TREE_CODE (x) != OFFSET_REF
+ && TREE_CODE (x) != BASELINK
+ && is_overloaded_fn (x))
+ return DECL_NAME (get_first_fn (x));
+ return NULL_TREE;
+}
+
/* Returns true iff X is an expression for an overloaded function
whose type cannot be known without performing overload
resolution. */
return ovl_cons (decl, chain);
}
+/* Return the scope where the overloaded functions OVL were found. */
+
+tree
+ovl_scope (tree ovl)
+{
+ if (TREE_CODE (ovl) == OFFSET_REF
+ || TREE_CODE (ovl) == COMPONENT_REF)
+ ovl = TREE_OPERAND (ovl, 1);
+ if (TREE_CODE (ovl) == BASELINK)
+ return BINFO_TYPE (BASELINK_BINFO (ovl));
+ if (TREE_CODE (ovl) == TEMPLATE_ID_EXPR)
+ ovl = TREE_OPERAND (ovl, 0);
+ /* Skip using-declarations. */
+ while (TREE_CODE (ovl) == OVERLOAD && OVL_USED (ovl) && OVL_CHAIN (ovl))
+ ovl = OVL_CHAIN (ovl);
+ return CP_DECL_CONTEXT (OVL_CURRENT (ovl));
+}
+
/* Return TRUE if FN is a non-static member function, FALSE otherwise.
This function looks into BASELINK and OVERLOAD nodes. */
if (!TYPE_P (t) && TREE_CONSTANT (t) && !TREE_SIDE_EFFECTS (t))
{
- /* There can't be any TARGET_EXPRs or their slot variables below
- this point. */
+ /* There can't be any TARGET_EXPRs or their slot variables below this
+ point. But we must make a copy, in case subsequent processing
+ alters any part of it. For example, during gimplification a cast
+ of the form (T) &X::f (where "f" is a member function) will lead
+ to replacing the PTRMEM_CST for &X::f with a VAR_DECL. */
*walk_subtrees = 0;
+ *tp = unshare_expr (t);
return NULL_TREE;
}
if (TREE_CODE (t) == TARGET_EXPR)
tree u;
if (TREE_CODE (TREE_OPERAND (t, 1)) == AGGR_INIT_EXPR)
- u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1),
- tf_warning_or_error);
+ {
+ u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1),
+ tf_warning_or_error);
+ if (AGGR_INIT_ZERO_FIRST (TREE_OPERAND (t, 1)))
+ AGGR_INIT_ZERO_FIRST (TREE_OPERAND (u, 1)) = true;
+ }
else
u = build_target_expr_with_type (TREE_OPERAND (t, 1), TREE_TYPE (t),
tf_warning_or_error);
+ TARGET_EXPR_IMPLICIT_P (u) = TARGET_EXPR_IMPLICIT_P (t);
+ TARGET_EXPR_LIST_INIT_P (u) = TARGET_EXPR_LIST_INIT_P (t);
+ TARGET_EXPR_DIRECT_INIT_P (u) = TARGET_EXPR_DIRECT_INIT_P (t);
+
/* Map the old variable to the new one. */
splay_tree_insert (target_remap,
(splay_tree_key) TREE_OPERAND (t, 0),
}
/* Make a copy of this node. */
- return copy_tree_r (tp, walk_subtrees, NULL);
+ t = copy_tree_r (tp, walk_subtrees, NULL);
+ if (TREE_CODE (*tp) == CALL_EXPR)
+ set_flags_from_callee (*tp);
+ return t;
}
/* Replace all remapped VAR_DECLs in T with their new equivalents.
if (n)
*t = (tree) n->value;
}
+ else if (TREE_CODE (*t) == PARM_DECL
+ && DECL_NAME (*t) == this_identifier)
+ {
+ /* In an NSDMI we need to replace the 'this' parameter we used for
+ parsing with the real one for this function. */
+ *t = current_class_ptr;
+ }
+ else if (TREE_CODE (*t) == CONVERT_EXPR
+ && CONVERT_EXPR_VBASE_PATH (*t))
+ {
+ /* In an NSDMI build_base_path defers building conversions to virtual
+ bases, and we handle it here. */
+ tree basetype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (*t)));
+ VEC(tree,gc) *vbases = CLASSTYPE_VBASECLASSES (current_class_type);
+ int i; tree binfo;
+ FOR_EACH_VEC_ELT (tree, vbases, i, binfo)
+ if (BINFO_TYPE (binfo) == basetype)
+ break;
+ *t = build_base_path (PLUS_EXPR, TREE_OPERAND (*t, 0), binfo, true,
+ tf_warning_or_error);
+ }
return NULL_TREE;
}
/* When we parse a default argument expression, we may create
temporary variables via TARGET_EXPRs. When we actually use the
- default-argument expression, we make a copy of the expression, but
- we must replace the temporaries with appropriate local versions. */
+ default-argument expression, we make a copy of the expression
+ and replace the temporaries with appropriate local versions. */
tree
break_out_target_exprs (tree t)
}
}
+/* Subroutine of cp_tree_equal: t1 and t2 are the CALL_EXPR_FNs of two
+ CALL_EXPRS. Return whether they are equivalent. */
+
+static bool
+called_fns_equal (tree t1, tree t2)
+{
+ /* Core 1321: dependent names are equivalent even if the overload sets
+ are different. But do compare explicit template arguments. */
+ tree name1 = dependent_name (t1);
+ tree name2 = dependent_name (t2);
+ if (name1 || name2)
+ {
+ tree targs1 = NULL_TREE, targs2 = NULL_TREE;
+
+ if (name1 != name2)
+ return false;
+
+ if (TREE_CODE (t1) == TEMPLATE_ID_EXPR)
+ targs1 = TREE_OPERAND (t1, 1);
+ if (TREE_CODE (t2) == TEMPLATE_ID_EXPR)
+ targs2 = TREE_OPERAND (t2, 1);
+ return cp_tree_equal (targs1, targs2);
+ }
+ else
+ return cp_tree_equal (t1, t2);
+}
+
/* Return truthvalue of whether T1 is the same tree structure as T2.
Return 1 if they are the same. Return 0 if they are different. */
{
tree arg1, arg2;
call_expr_arg_iterator iter1, iter2;
- if (!cp_tree_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
+ if (!called_fns_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
return false;
for (arg1 = first_call_expr_arg (t1, &iter1),
arg2 = first_call_expr_arg (t2, &iter2);
case BASELINK:
return (BASELINK_BINFO (t1) == BASELINK_BINFO (t2)
&& BASELINK_ACCESS_BINFO (t1) == BASELINK_ACCESS_BINFO (t2)
+ && BASELINK_QUALIFIED_P (t1) == BASELINK_QUALIFIED_P (t2)
&& cp_tree_equal (BASELINK_FUNCTIONS (t1),
BASELINK_FUNCTIONS (t2)));
TREE_TYPE (TEMPLATE_PARM_DECL (t2))));
case TEMPLATE_ID_EXPR:
+ return (cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0))
+ && cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)));
+
+ case TREE_VEC:
{
unsigned ix;
- tree vec1, vec2;
-
- if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+ if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2))
return false;
- vec1 = TREE_OPERAND (t1, 1);
- vec2 = TREE_OPERAND (t2, 1);
-
- if (!vec1 || !vec2)
- return !vec1 && !vec2;
-
- if (TREE_VEC_LENGTH (vec1) != TREE_VEC_LENGTH (vec2))
- return false;
-
- for (ix = TREE_VEC_LENGTH (vec1); ix--;)
- if (!cp_tree_equal (TREE_VEC_ELT (vec1, ix),
- TREE_VEC_ELT (vec2, ix)))
+ for (ix = TREE_VEC_LENGTH (t1); ix--;)
+ if (!cp_tree_equal (TREE_VEC_ELT (t1, ix),
+ TREE_VEC_ELT (t2, ix)))
return false;
-
return true;
}
case REINTERPRET_CAST_EXPR:
case CONST_CAST_EXPR:
case DYNAMIC_CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
case NEW_EXPR:
if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
return false;
case TYPE_PACK_EXPANSION:
WALK_SUBTREE (TREE_TYPE (*tp));
+ WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
*walk_subtrees_p = 0;
break;
case EXPR_PACK_EXPANSION:
WALK_SUBTREE (TREE_OPERAND (*tp, 0));
+ WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
*walk_subtrees_p = 0;
break;
case STATIC_CAST_EXPR:
case CONST_CAST_EXPR:
case DYNAMIC_CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
if (TREE_TYPE (*tp))
WALK_SUBTREE (TREE_TYPE (*tp));
if (!TREE_SIDE_EFFECTS (exp))
init_expr = NULL_TREE;
+ else if (VOID_TYPE_P (TREE_TYPE (exp)))
+ {
+ *initp = exp;
+ return void_zero_node;
+ }
/* There are no expressions with REFERENCE_TYPE, but there can be call
arguments with such a type; just treat it as a pointer. */
else if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE
if (TREE_CODE (t) == INIT_EXPR
&& TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR
+ && TREE_CODE (TREE_OPERAND (t, 1)) != CONSTRUCTOR
&& TREE_CODE (TREE_OPERAND (t, 1)) != AGGR_INIT_EXPR)
{
TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
/* Aggregate initialization: stabilize each of the field
initializers. */
unsigned i;
- tree value;
+ constructor_elt *ce;
bool good = true;
- FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, value)
- if (!stabilize_init (value, initp))
- good = false;
+ VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (t);
+ for (i = 0; VEC_iterate (constructor_elt, v, i, ce); ++i)
+ {
+ tree type = TREE_TYPE (ce->value);
+ tree subinit;
+ if (TREE_CODE (type) == REFERENCE_TYPE
+ || SCALAR_TYPE_P (type))
+ ce->value = stabilize_expr (ce->value, &subinit);
+ else if (!stabilize_init (ce->value, &subinit))
+ good = false;
+ *initp = add_stmt_to_compound (*initp, subinit);
+ }
return good;
}
/* The initialization is being performed via a bitwise copy -- and
the item copied may have side effects. */
- return TREE_SIDE_EFFECTS (init);
+ return !TREE_SIDE_EFFECTS (init);
}
/* Like "fold", but should be used whenever we might be processing the
DECL_EXTERNAL (t) = 1;
TREE_STATIC (t) = 0;
}
- if (CP_AGGREGATE_TYPE_P (t)
- && TYPE_NAME (t))
- {
- tree name = TYPE_NAME (t);
- if (TREE_CODE (name) == TYPE_DECL)
- name = DECL_NAME (name);
- /* Drop anonymous names. */
- if (name != NULL_TREE
- && ANON_AGGRNAME_P (name))
- TYPE_NAME (t) = NULL_TREE;
- }
if (TREE_CODE (t) == NAMESPACE_DECL)
{
/* The list of users of a namespace isn't useful for the middle-end