check_for_override (decl, ctype)
tree decl, ctype;
{
- tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
- int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
- int virtualp = DECL_VIRTUAL_P (decl);
- int found_overriden_fn = 0;
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ /* In [temp.mem] we have:
- for (i = 0; i < n_baselinks; i++)
+ A specialization of a member function template does not
+ override a virtual function from a base class. */
+ return;
+ if ((DECL_DESTRUCTOR_P (decl)
+ || IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)))
+ && look_for_overrides (ctype, decl)
+ && !DECL_STATIC_FUNCTION_P (decl))
{
- tree base_binfo = TREE_VEC_ELT (binfos, i);
- if (TYPE_POLYMORPHIC_P (BINFO_TYPE (base_binfo)))
- {
- tree tmp = get_matching_virtual
- (base_binfo, decl, DECL_DESTRUCTOR_P (decl));
-
- if (tmp && !found_overriden_fn)
- {
- /* If this function overrides some virtual in some base
- class, then the function itself is also necessarily
- virtual, even if the user didn't explicitly say so. */
- DECL_VIRTUAL_P (decl) = 1;
-
- /* The TMP we really want is the one from the deepest
- baseclass on this path, taking care not to
- duplicate if we have already found it (via another
- path to its virtual baseclass. */
- if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
- {
- cp_error_at ("`static %#D' cannot be declared", decl);
- cp_error_at (" since `virtual %#D' declared in base class",
- tmp);
- break;
- }
- virtualp = 1;
-
- /* Set DECL_VINDEX to a value that is neither an
- INTEGER_CST nor the error_mark_node so that
- add_virtual_function will realize this is an
- overridden function. */
- DECL_VINDEX (decl)
- = tree_cons (tmp, NULL_TREE, DECL_VINDEX (decl));
-
- /* We now know that DECL overrides something,
- which is all that is important. But, we must
- continue to iterate through all the base-classes
- in order to allow get_matching_virtual to check for
- various illegal overrides. */
- found_overriden_fn = 1;
- }
- }
+ /* Set DECL_VINDEX to a value that is neither an
+ INTEGER_CST nor the error_mark_node so that
+ add_virtual_function will realize this is an
+ overriding function. */
+ DECL_VINDEX (decl) = decl;
}
- if (virtualp)
+ if (DECL_VIRTUAL_P (decl))
{
if (DECL_VINDEX (decl) == NULL_TREE)
DECL_VINDEX (decl) = error_mark_node;
TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings)
- {
- if (DECL_NAME (x))
- cp_warning_at ("non-static reference `%#D' in class without a constructor", x);
- else
- cp_warning_at ("non-static reference in class without a constructor", x);
- }
+ cp_warning_at ("non-static reference `%#D' in class without a constructor", x);
}
type = strip_array_types (type);
TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;
if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings)
- {
- if (DECL_NAME (x))
- cp_warning_at ("non-static const member `%#D' in class without a constructor", x);
- else
- cp_warning_at ("non-static const member in class without a constructor", x);
- }
+ cp_warning_at ("non-static const member `%#D' in class without a constructor", x);
}
/* A field that is pseudo-const makes the structure likewise. */
else if (IS_AGGR_TYPE (type))
{
tree clone;
+ /* Avoid inappropriate cloning. */
+ if (! flag_new_abi
+ || (TREE_CHAIN (fn)
+ && DECL_CLONED_FUNCTION (TREE_CHAIN (fn))))
+ return;
+
if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
{
/* For each constructor, we need two variants: an in-charge version
pushlevel_class ();
-#if 0
- if (CLASSTYPE_TEMPLATE_INFO (type))
- overload_template_name (type);
-#endif
-
if (modify)
{
if (type != previous_class_type || current_class_depth > 1)
target_fn_type = TREE_TYPE (target_type);
target_arg_types = TYPE_ARG_TYPES (target_fn_type);
target_ret_type = TREE_TYPE (target_fn_type);
+
+ /* Never do unification on the 'this' parameter. */
+ if (TREE_CODE (target_fn_type) == METHOD_TYPE)
+ target_arg_types = TREE_CHAIN (target_arg_types);
for (fns = overload; fns; fns = OVL_CHAIN (fns))
{
targs = make_tree_vec (DECL_NTPARMS (fn));
if (fn_type_unification (fn, explicit_targs, targs,
target_arg_types, target_ret_type,
- DEDUCE_EXACT) != 0)
+ DEDUCE_EXACT, -1) != 0)
/* Argument deduction failed. */
continue;
/* Now, remove all but the most specialized of the matches. */
if (matches)
{
- tree match = most_specialized_instantiation (matches,
- explicit_targs);
+ tree match = most_specialized_instantiation (matches);
if (match != error_mark_node)
matches = tree_cons (match, NULL_TREE, NULL_TREE);
in its context and when re-evaluated in the completed scope of
S. */
cp_error ("declaration of `%#D'", decl);
- cp_error_at ("changes meaning of `%s' from `%+#D'",
- IDENTIFIER_POINTER (DECL_NAME (OVL_CURRENT (decl))),
+ cp_error_at ("changes meaning of `%D' from `%+#D'",
+ DECL_NAME (OVL_CURRENT (decl)),
(tree) n->value);
}
}