-
Notifications
You must be signed in to change notification settings - Fork 285
Refinements to class_method_descriptor_exprt
#5145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
bfbcffd
2ac75d2
944a3f3
e720271
adab366
05930c3
dd07600
d2d7736
89d2d73
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -263,7 +263,7 @@ bool ci_lazy_methodst::handle_virtual_methods_with_no_callees( | |
| // didn't already exist. It can't be instantiated already, otherwise it | ||
| // would give a concrete definition of the called method, and | ||
| // candidate_target_methods would be non-empty. | ||
| const irep_idt &call_class = virtual_function.get_class_name(); | ||
| const irep_idt &call_class = virtual_function.class_id(); | ||
| bool was_missing = instantiated_classes.count(call_class) == 0; | ||
| CHECK_RETURN(was_missing); | ||
| any_new_classes = true; | ||
|
|
@@ -292,13 +292,13 @@ bool ci_lazy_methodst::handle_virtual_methods_with_no_callees( | |
| } | ||
|
|
||
| // Check that `get_virtual_method_target` returns a method now | ||
| const irep_idt &call_basename = virtual_function.get_component_name(); | ||
| const irep_idt method_name = get_virtual_method_target( | ||
| instantiated_classes, call_basename, call_class, symbol_table); | ||
| CHECK_RETURN(!method_name.empty()); | ||
| const irep_idt &method_name = virtual_function.mangled_method_name(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be easier if we used
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To me, |
||
| const irep_idt method_id = get_virtual_method_target( | ||
| instantiated_classes, method_name, call_class, symbol_table); | ||
| CHECK_RETURN(!method_id.empty()); | ||
|
|
||
| // Add what it returns to methods_to_convert_later | ||
| methods_to_convert_later.insert(method_name); | ||
| methods_to_convert_later.insert(method_id); | ||
| } | ||
| return any_new_classes; | ||
| } | ||
|
|
@@ -477,12 +477,12 @@ void ci_lazy_methodst::get_virtual_method_targets( | |
| std::unordered_set<irep_idt> &callable_methods, | ||
| symbol_tablet &symbol_table) | ||
| { | ||
| const auto &call_class = called_function.get_class_name(); | ||
| const auto &call_class = called_function.class_id(); | ||
| INVARIANT( | ||
| !call_class.empty(), "All virtual calls should be aimed at a class"); | ||
| const auto &call_basename = called_function.get_component_name(); | ||
| const auto &method_name = called_function.mangled_method_name(); | ||
| INVARIANT( | ||
| !call_basename.empty(), | ||
| !method_name.empty(), | ||
| "Virtual function must have a reasonable name after removing class"); | ||
|
|
||
| class_hierarchyt::idst self_and_child_classes = | ||
|
|
@@ -491,10 +491,10 @@ void ci_lazy_methodst::get_virtual_method_targets( | |
|
|
||
| for(const irep_idt &class_name : self_and_child_classes) | ||
| { | ||
| const irep_idt method_name = get_virtual_method_target( | ||
| instantiated_classes, call_basename, class_name, symbol_table); | ||
| if(!method_name.empty()) | ||
| callable_methods.insert(method_name); | ||
| const irep_idt method_id = get_virtual_method_target( | ||
| instantiated_classes, method_name, class_name, symbol_table); | ||
| if(!method_id.empty()) | ||
| callable_methods.insert(method_id); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4588,45 +4588,92 @@ inline array_comprehension_exprt &to_array_comprehension_expr(exprt &expr) | |
| return ret; | ||
| } | ||
|
|
||
| inline void validate_expr(const class class_method_descriptor_exprt &value); | ||
thk123 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /// An expression describing a method on a class | ||
| class class_method_descriptor_exprt : public nullary_exprt | ||
| { | ||
| public: | ||
| /// \param class_id: Unique identifier in the symbol table, of the compile | ||
| /// time type of the class which this expression is applied to. For example | ||
| /// this could be - `java::java.lang.Object`. | ||
| /// \param base_method_name: The name of the method to which this expression | ||
| /// is applied as would be seen in the source code. For example this could | ||
| /// be - `toString`. | ||
| /// \param mangled_method_name: The method name after mangling it by | ||
| /// combining it with the descriptor. The mangled name is distinguished from | ||
| /// other overloads of the method with different counts of or types of | ||
| /// parameters. It is not distinguished between different implementations | ||
| /// within a class hierarchy. For example if the overall expression refers | ||
| /// to the `java.lang.Object.toString` method, then the mangled_method_name | ||
| /// would be `toString:()Ljava/lang/String;` | ||
| explicit class_method_descriptor_exprt( | ||
| typet _type, | ||
| irep_idt component_name, | ||
| irep_idt class_name, | ||
| irep_idt base_name, | ||
| irep_idt identifier) | ||
| irep_idt mangled_method_name, | ||
| irep_idt class_id, | ||
| irep_idt base_method_name) | ||
| : nullary_exprt(ID_virtual_function, std::move(_type)) | ||
| { | ||
| set(ID_component_name, std::move(component_name)); | ||
| set(ID_C_class, std::move(class_name)); | ||
| set(ID_C_base_name, std::move(base_name)); | ||
| set(ID_identifier, std::move(identifier)); | ||
| irep_idt id = id2string(class_id) + "." + id2string(mangled_method_name); | ||
| set(ID_component_name, std::move(mangled_method_name)); | ||
| set(ID_C_class, std::move(class_id)); | ||
| set(ID_C_base_name, std::move(base_method_name)); | ||
| set(ID_identifier, std::move(id)); | ||
| validate_expr(*this); | ||
| } | ||
|
|
||
| const irep_idt &get_component_name() const | ||
| /// The method name after mangling it by combining it with the descriptor. | ||
| /// The mangled name is distinguished from other overloads of the method with | ||
| /// different counts of or types of parameters. It is not distinguished | ||
| /// between different implementations within a class hierarchy. For example if | ||
| /// the overall expression refers to the `java.lang.Object.toString` method, | ||
| /// then the mangled_method_name would be `toString:()Ljava/lang/String;` | ||
| const irep_idt &mangled_method_name() const | ||
thk123 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| return get(ID_component_name); | ||
| } | ||
|
|
||
| const irep_idt &get_class_name() const | ||
| /// Unique identifier in the symbol table, of the compile time type of the | ||
| /// class which this expression is applied to. For example this could be - | ||
| /// `java::java.lang.Object`. | ||
| const irep_idt &class_id() const | ||
thk123 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| return get(ID_C_class); | ||
| } | ||
|
|
||
| const irep_idt &get_base_name() const | ||
| /// The name of the method to which this expression is applied as would be | ||
| /// seen in the source code. For example this could be - `toString`. | ||
| const irep_idt &base_method_name() const | ||
thk123 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| return get(ID_C_base_name); | ||
| } | ||
|
|
||
| /// A unique identifier of the combination of class and method overload to | ||
| /// which this expression refers. For example this could be - | ||
| /// `java::java.lang.Object.toString:()Ljava/lang/String;`. | ||
| const irep_idt &get_identifier() const | ||
| { | ||
| return get(ID_identifier); | ||
| } | ||
| }; | ||
|
|
||
| inline void validate_expr(const class class_method_descriptor_exprt &value) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’m not sure what the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It isn't redundant. It is an inline forward declaration of the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW coding guidelines say forward declarations should be put at the top of the file with the includes
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I'll try and remember for next time. |
||
| { | ||
| validate_operands(value, 0, "class method descriptor must not have operands"); | ||
| DATA_INVARIANT( | ||
| !value.mangled_method_name().empty(), | ||
| "class method descriptor must have a mangled method name."); | ||
| DATA_INVARIANT( | ||
| !value.class_id().empty(), "class method descriptor must have a class id."); | ||
| DATA_INVARIANT( | ||
| !value.base_method_name().empty(), | ||
| "class method descriptor must have a base method name."); | ||
| DATA_INVARIANT( | ||
thk123 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| value.get_identifier() == id2string(value.class_id()) + "." + | ||
| id2string(value.mangled_method_name()), | ||
| "class method descriptor must have an identifier in the expected format."); | ||
| } | ||
|
|
||
| /// \brief Cast an exprt to a \ref class_method_descriptor_exprt | ||
| /// | ||
| /// \a expr must be known to be \ref class_method_descriptor_exprt. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⛏️ keep one rename per commit in future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓
method_nameandmethod_idis confusing as to what is the difference between them. Perhapsmethod_nameandresolved_method_symbol_id?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be an improvement if I renamed the
method_namevariable tomangled_method_name?