===================================================================
@@ -137,6 +137,8 @@ struct GTY(()) odr_type_d
int id;
/* Is it in anonymous namespace? */
bool anonymous_namespace;
+ /* Is it final type? */
+ bool final_type;
};
@@ -270,6 +272,7 @@ get_odr_type (tree type, bool insert)
val->bases = vNULL;
val->derived_types = vNULL;
val->anonymous_namespace = type_in_anonymous_namespace_p (type);
+ val->final_type = TYPE_FINAL_P (type);
*slot = val;
for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); i++)
/* For now record only polymorphic types. other are
@@ -300,7 +303,8 @@ dump_odr_type (FILE *f, odr_type t, int
unsigned int i;
fprintf (f, "%*s type %i: ", indent * 2, "", t->id);
print_generic_expr (f, t->type, TDF_SLIM);
- fprintf (f, "%s\n", t->anonymous_namespace ? " (anonymous namespace)":"");
+ fprintf (f, "%s%s\n", t->anonymous_namespace ? " (anonymous namespace)":"",
+ t->final_type ? " (final)":"");
if (TYPE_NAME (t->type))
{
fprintf (f, "%*s defined at: %s:%i\n", indent * 2, "",
@@ -598,7 +602,7 @@ possible_polymorphic_call_targets (tree
/* For anonymous namespace types we can attempt to build full type.
All derivations must be in this unit. */
- if (type->anonymous_namespace && finalp && !flag_ltrans)
+ if ((type->anonymous_namespace || type->final_type) && finalp && !flag_ltrans)
*finalp = true;
/* Initialize query cache. */
@@ -637,19 +641,24 @@ possible_polymorphic_call_targets (tree
target = gimple_get_virt_method_for_binfo (otr_token, binfo);
if (target)
maybe_record_node (nodes, target, inserted);
- pointer_set_insert (matched_vtables, BINFO_VTABLE (binfo));
- /* TODO: If method is final, we can stop here and signaize that
- list is final. We need C++ FE to pass our info about final
- methods and classes. */
+ /* If we failed to find the method, we no longer have final list
+ This can happen i.e. when we can not refer to decl from other unit. */
+ if (!nodes.length())
+ *finalp = false;
+ pointer_set_insert (matched_vtables, BINFO_VTABLE (binfo));
- /* Walk recursively all derived types. Here we need to lookup proper basetype
- via their BINFO walk that is done by record_binfo */
- for (i = 0; i < type->derived_types.length(); i++)
- possible_polymorphic_call_targets_1 (nodes, inserted,
- matched_vtables,
- otr_type, type->derived_types[i],
- otr_token);
+ /* If method is not final, walk recursively all derived types.
+ Here we need to lookup proper basetype via their BINFO walk that is done
+ by record_binfo */
+ if (!nodes.length () || !DECL_FINAL_P (nodes[0]->symbol.decl))
+ for (i = 0; i < type->derived_types.length(); i++)
+ possible_polymorphic_call_targets_1 (nodes, inserted,
+ matched_vtables,
+ otr_type, type->derived_types[i],
+ otr_token);
+ else if (finalp)
+ *finalp = true;
(*slot)->targets = nodes;
pointer_set_destroy (inserted);