-
Notifications
You must be signed in to change notification settings - Fork 273
Factor class identifier extraction out of remove virtuals #471
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
Merged
peterschrammel
merged 2 commits into
diffblue:master
from
smowton:factor_class_identifier_master
Jan 30, 2017
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/*******************************************************************\ | ||
|
||
Module: Extract class identifier | ||
|
||
Author: Chris Smowton, [email protected] | ||
|
||
\*******************************************************************/ | ||
|
||
#include "class_identifier.h" | ||
|
||
#include <util/std_expr.h> | ||
#include <util/namespace.h> | ||
|
||
/*******************************************************************\ | ||
|
||
Function: build_class_identifier | ||
|
||
Inputs: Struct expression | ||
|
||
Outputs: Member expression giving the clsid field of the input, | ||
or its parent, grandparent, etc. | ||
|
||
Purpose: | ||
|
||
\*******************************************************************/ | ||
|
||
static exprt build_class_identifier( | ||
const exprt &src, | ||
const namespacet &ns) | ||
{ | ||
// the class identifier is in the root class | ||
exprt e=src; | ||
|
||
while(1) | ||
{ | ||
const typet &type=ns.follow(e.type()); | ||
const struct_typet &struct_type=to_struct_type(type); | ||
const struct_typet::componentst &components=struct_type.components(); | ||
assert(!components.empty()); | ||
|
||
const auto &first_member_name=components.front().get_name(); | ||
member_exprt member_expr( | ||
e, | ||
first_member_name, | ||
components.front().type()); | ||
|
||
if(first_member_name=="@class_identifier") | ||
{ | ||
// found it | ||
return member_expr; | ||
} | ||
else | ||
{ | ||
e.swap(member_expr); | ||
} | ||
} | ||
} | ||
|
||
/*******************************************************************\ | ||
|
||
Function: get_class_identifier_field | ||
|
||
Inputs: Pointer expression of any pointer type, including void*, | ||
and a recommended access type if the pointer is void-typed. | ||
|
||
Outputs: Member expression to access a class identifier, as above. | ||
|
||
Purpose: | ||
|
||
\*******************************************************************/ | ||
|
||
exprt get_class_identifier_field( | ||
const exprt &this_expr_in, | ||
const symbol_typet &suggested_type, | ||
const namespacet &ns) | ||
{ | ||
// Get a pointer from which we can extract a clsid. | ||
// If it's already a pointer to an object of some sort, just use it; | ||
// if it's void* then use the suggested type. | ||
|
||
exprt this_expr=this_expr_in; | ||
assert(this_expr.type().id()==ID_pointer && | ||
"Non-pointer this-arg in remove-virtuals?"); | ||
const auto &points_to=this_expr.type().subtype(); | ||
if(points_to==empty_typet()) | ||
this_expr=typecast_exprt(this_expr, pointer_typet(suggested_type)); | ||
exprt deref=dereference_exprt(this_expr, this_expr.type().subtype()); | ||
return build_class_identifier(deref, ns); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/*******************************************************************\ | ||
|
||
Module: Extract class identifier | ||
|
||
Author: Chris Smowton, [email protected] | ||
|
||
\*******************************************************************/ | ||
|
||
#ifndef CPROVER_GOTO_PROGRAMS_CLASS_IDENTIFIER_H | ||
#define CPROVER_GOTO_PROGRAMS_CLASS_IDENTIFIER_H | ||
|
||
class exprt; | ||
class namespacet; | ||
class symbol_typet; | ||
|
||
exprt get_class_identifier_field( | ||
const exprt &this_expr, | ||
const symbol_typet &suggested_type, | ||
const namespacet &ns); | ||
|
||
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ Author: Daniel Kroening, [email protected] | |
#include <util/type_eq.h> | ||
|
||
#include "class_hierarchy.h" | ||
#include "class_identifier.h" | ||
#include "remove_virtual_functions.h" | ||
|
||
/*******************************************************************\ | ||
|
@@ -61,8 +62,6 @@ class remove_virtual_functionst | |
exprt get_method( | ||
const irep_idt &class_id, | ||
const irep_idt &component_name) const; | ||
|
||
exprt build_class_identifier(const exprt &); | ||
}; | ||
|
||
/*******************************************************************\ | ||
|
@@ -88,48 +87,6 @@ remove_virtual_functionst::remove_virtual_functionst( | |
|
||
/*******************************************************************\ | ||
|
||
Function: remove_virtual_functionst::build_class_identifier | ||
|
||
Inputs: | ||
|
||
Outputs: | ||
|
||
Purpose: | ||
|
||
\*******************************************************************/ | ||
|
||
exprt remove_virtual_functionst::build_class_identifier( | ||
const exprt &src) | ||
{ | ||
// the class identifier is in the root class | ||
exprt e=src; | ||
|
||
while(1) | ||
{ | ||
const typet &type=ns.follow(e.type()); | ||
assert(type.id()==ID_struct); | ||
|
||
const struct_typet &struct_type=to_struct_type(type); | ||
const struct_typet::componentst &components=struct_type.components(); | ||
assert(!components.empty()); | ||
|
||
member_exprt member_expr( | ||
e, components.front().get_name(), components.front().type()); | ||
|
||
if(components.front().get_name()=="@class_identifier") | ||
{ | ||
// found it | ||
return member_expr; | ||
} | ||
else | ||
{ | ||
e=member_expr; | ||
} | ||
} | ||
} | ||
|
||
/*******************************************************************\ | ||
|
||
Function: remove_virtual_functionst::remove_virtual_function | ||
|
||
Inputs: | ||
|
@@ -181,22 +138,12 @@ void remove_virtual_functionst::remove_virtual_function( | |
goto_programt new_code_calls; | ||
goto_programt new_code_gotos; | ||
|
||
// Get a pointer from which we can extract a clsid. | ||
// If it's already a pointer to an object of some sort, just use it; | ||
// if it's void* then use the parent of all possible candidates, | ||
// which by the nature of get_functions happens to be the last candidate. | ||
|
||
exprt this_expr=code.arguments()[0]; | ||
assert(this_expr.type().id()==ID_pointer && | ||
"Non-pointer this-arg in remove-virtuals?"); | ||
const auto &points_to=this_expr.type().subtype(); | ||
if(points_to==empty_typet()) | ||
{ | ||
symbol_typet symbol_type(functions.back().class_id); | ||
this_expr=typecast_exprt(this_expr, pointer_typet(symbol_type)); | ||
} | ||
exprt deref=dereference_exprt(this_expr, this_expr.type().subtype()); | ||
exprt c_id2=build_class_identifier(deref); | ||
// If necessary, cast to the last candidate function to | ||
// get the object's clsid. By the structure of get_functions, | ||
// this is the parent of all other classes under consideration. | ||
symbol_typet suggested_type(functions.back().class_id); | ||
exprt c_id2=get_class_identifier_field(this_expr, suggested_type, ns); | ||
|
||
goto_programt::targett last_function; | ||
for(const auto &fun : functions) | ||
|
@@ -249,8 +196,10 @@ void remove_virtual_functionst::remove_virtual_function( | |
const irep_idt comment=it->source_location.get_comment(); | ||
it->source_location=target->source_location; | ||
it->function=target->function; | ||
if(!property_class.empty()) it->source_location.set_property_class(property_class); | ||
if(!comment.empty()) it->source_location.set_comment(comment); | ||
if(!property_class.empty()) | ||
it->source_location.set_property_class(property_class); | ||
if(!comment.empty()) | ||
it->source_location.set_comment(comment); | ||
} | ||
|
||
goto_programt::targett next_target=target; | ||
|
@@ -355,7 +304,8 @@ void remove_virtual_functionst::get_functions( | |
const class_hierarchyt::idst &parents= | ||
class_hierarchy.class_map[c].parents; | ||
|
||
if(parents.empty()) break; | ||
if(parents.empty()) | ||
break; | ||
c=parents.front(); | ||
} | ||
|
||
|
@@ -433,7 +383,6 @@ bool remove_virtual_functionst::remove_virtual_functions( | |
|
||
if(did_something) | ||
{ | ||
//remove_skip(goto_program); | ||
goto_program.update(); | ||
} | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
dereference_exprt deref(this_expr, this_expr.type().subtype());
(I guess the question on why that second argument is required still rests with @kroening).