Skip to content

Commit bd4b15e

Browse files
committed
Add get-inherited-method utility
This takes inheritance from interface default methods into account.
1 parent fd32f9b commit bd4b15e

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

src/goto-programs/resolve_inherited_component.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,43 @@ irep_idt resolve_inherited_componentt::inherited_componentt::
106106
return resolve_inherited_componentt::build_full_component_identifier(
107107
class_identifier, component_identifier);
108108
}
109+
110+
/// Given a class and a component, identify the concrete method it is
111+
/// resolved to. For example, a reference Child.abc refers to Child's method or
112+
/// field if it exists, or else Parent.abc, and so on regarding Parent's
113+
/// ancestors. If none are found, an empty string will be returned.
114+
/// This looks first for non-abstract methods inherited from the first base
115+
/// (i.e., for Java the superclass), then for non-abstract methods inherited
116+
/// otherwise (for Java, interface default methods), then for any abstract
117+
/// declaration.
118+
/// \param classname: The name of the class the function is being called on
119+
/// \param call_basename: The base name of the component (i.e. without the
120+
/// class specifier)
121+
/// \param symbol_table: Global symbol table
122+
/// \return The concrete component that has been resolved
123+
optionalt<resolve_inherited_componentt::inherited_componentt>
124+
get_inherited_method_implementation(
125+
const irep_idt &call_basename,
126+
const irep_idt &classname,
127+
const symbol_tablet &symbol_table)
128+
{
129+
resolve_inherited_componentt call_resolver{symbol_table};
130+
auto exclude_abstract_methods = [&](const symbolt &symbol) {
131+
return !symbol.type.get_bool(ID_C_abstract);
132+
};
133+
134+
auto resolved_call =
135+
call_resolver(classname, call_basename, false, exclude_abstract_methods);
136+
if(!resolved_call)
137+
{
138+
// Check for a default implementation:
139+
resolved_call =
140+
call_resolver(classname, call_basename, true, exclude_abstract_methods);
141+
}
142+
if(!resolved_call)
143+
{
144+
// Finally accept any abstract definition, which will likely get stubbed:
145+
resolved_call = call_resolver(classname, call_basename, true);
146+
}
147+
return resolved_call;
148+
}

src/goto-programs/resolve_inherited_component.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,10 @@ class resolve_inherited_componentt
5959
const symbol_tablet &symbol_table;
6060
};
6161

62+
optionalt<resolve_inherited_componentt::inherited_componentt>
63+
get_inherited_method_implementation(
64+
const irep_idt &call_basename,
65+
const irep_idt &classname,
66+
const symbol_tablet &symbol_table);
67+
6268
#endif // CPROVER_GOTO_PROGRAMS_RESOLVE_INHERITED_COMPONENT_H

0 commit comments

Comments
 (0)