@@ -297,13 +297,8 @@ void gather_methods_lazilyt::initialize_needed_classes_from_pointer(
297
297
{
298
298
const symbol_typet &class_type=to_symbol_type (pointer_type.subtype ());
299
299
const auto ¶m_classid=class_type.get_identifier ();
300
- std::vector<irep_idt> class_and_parents=
301
- class_hierarchy.get_parents_trans (param_classid);
302
300
303
- class_and_parents.push_back (param_classid);
304
-
305
- for (const auto &classid : class_and_parents)
306
- lazy_methods.add_needed_class (classid);
301
+ lazy_methods.add_needed_class (param_classid);
307
302
308
303
gather_field_types (pointer_type.subtype (), ns, lazy_methods);
309
304
}
@@ -360,6 +355,15 @@ void gather_methods_lazilyt::get_virtual_method_targets(
360
355
361
356
auto old_size=needed_methods.size ();
362
357
358
+ const irep_idt &self_method=
359
+ get_virtual_method_target (
360
+ needed_classes, call_basename, call_class, symbol_table);
361
+
362
+ if (!self_method.empty ())
363
+ {
364
+ needed_methods.push_back (self_method);
365
+ }
366
+
363
367
auto child_classes=class_hierarchy.get_children_trans (call_class);
364
368
for (const auto &child_class : child_classes)
365
369
{
@@ -373,36 +377,6 @@ void gather_methods_lazilyt::get_virtual_method_targets(
373
377
needed_methods.push_back (child_method);
374
378
}
375
379
376
- irep_idt parent_class_id=call_class;
377
- while (1 )
378
- {
379
- auto parent_method=
380
- get_virtual_method_target (
381
- needed_classes,
382
- call_basename,
383
- parent_class_id,
384
- symbol_table);
385
- if (!parent_method.empty ())
386
- {
387
- needed_methods.push_back (parent_method);
388
- break ;
389
- }
390
- else
391
- {
392
- auto findit=class_hierarchy.class_map .find (parent_class_id);
393
- if (findit==class_hierarchy.class_map .end ())
394
- break ;
395
- else
396
- {
397
- const auto &entry=findit->second ;
398
- if (entry.parents .empty ())
399
- break ;
400
- else
401
- parent_class_id=entry.parents [0 ];
402
- }
403
- }
404
- }
405
-
406
380
if (needed_methods.size ()==old_size)
407
381
{
408
382
// Didn't find any candidate callee. Generate a stub.
@@ -494,9 +468,41 @@ irep_idt gather_methods_lazilyt::get_virtual_method_target(
494
468
// Program-wide, is this class ever instantiated?
495
469
if (!needed_classes.count (classname))
496
470
return irep_idt ();
497
- auto methodid=id2string (classname)+ " . " + id2string ( call_basename);
471
+ auto methodid=build_virtual_method_name (classname, call_basename);
498
472
if (symbol_table.has_symbol (methodid))
499
473
return methodid;
500
474
else
475
+ {
476
+ // no method found for this specific classs, but a call to this class
477
+ // will be resolved in one of its base classes so we should work up the
478
+ // heirarchy to see if one resovles
479
+ class_hierarchyt::idst parent_classes=
480
+ class_hierarchy.get_parents_trans (classname);
481
+ for (const irep_idt &parent_class_id : parent_classes)
482
+ {
483
+ auto parent_method_id=
484
+ build_virtual_method_name (parent_class_id, call_basename);
485
+ if (symbol_table.has_symbol (parent_method_id))
486
+ {
487
+ return parent_method_id;
488
+ }
489
+ }
501
490
return irep_idt ();
491
+ }
492
+ }
493
+
494
+
495
+ // / Build a method name as found in a GOTO symbol table equivalent to the name
496
+ // / of a concrete call of method component_method_name on class class_name
497
+ // / \param component_method_name: The name of the function
498
+ // / \param class_name: The class the implementation would be found on.
499
+ // / \return A name for looking up in the symbol table for classes `class_name`'s
500
+ // / implementation of `component_name`
501
+ irep_idt gather_methods_lazilyt::build_virtual_method_name (
502
+ const irep_idt &class_name, const irep_idt &component_method_name)
503
+ {
504
+ // Verify the parameters are called in the correct order.
505
+ PRECONDITION (id2string (class_name).find (" ::" )!=std::string::npos);
506
+ PRECONDITION (id2string (component_method_name).find (" (" )!=std::string::npos);
507
+ return id2string (class_name)+' .' +id2string (component_method_name);
502
508
}
0 commit comments