/* 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:
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));
(14.6.2), return the IDENTIFIER_NODE for that name. Otherwise, return
NULL_TREE. */
-static 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;
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. */
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;
}
}
}
+/* 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;
- /* Core 1321: dependent names are equivalent even if the
- overload sets are different. */
- tree name1 = dependent_name (CALL_EXPR_FN (t1));
- tree name2 = dependent_name (CALL_EXPR_FN (t2));
- if (!(name1 && name2 && name1 == name2)
- && !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 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;
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);
/* 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