Skip to content

Extracted functions from the convert/convert_type methods in expr2c #354

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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
264 changes: 214 additions & 50 deletions src/ansi-c/expr2c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,29 +359,7 @@ std::string expr2ct::convert_rec(
}
else if(src.id()==ID_struct)
{
const struct_typet &struct_type=to_struct_type(src);

std::string dest=q+"struct";

const irep_idt &tag=struct_type.get_tag();
if(tag!="") dest+=" "+id2string(tag);
dest+=" {";

for(struct_typet::componentst::const_iterator
it=struct_type.components().begin();
it!=struct_type.components().end();
it++)
{
dest+=' ';
dest+=convert_rec(it->type(), c_qualifierst(), id2string(it->get_name()));
dest+=';';
}

dest+=" }";

dest+=d;

return dest;
return convert_struct_type(src, q, d);
}
else if(src.id()==ID_incomplete_struct)
{
Expand Down Expand Up @@ -517,18 +495,7 @@ std::string expr2ct::convert_rec(
}
else if(src.id()==ID_array)
{
// The [...] gets attached to the declarator.
std::string array_suffix;

if(to_array_type(src).size().is_nil())
array_suffix="[]";
else
array_suffix="["+convert(to_array_type(src).size())+"]";

// This won't really parse without declarator.
// Note that qualifiers are passed down.
return convert_rec(
src.subtype(), qualifiers, declarator+array_suffix);
return convert_array_type(src, qualifiers, declarator);
}
else if(src.id()==ID_incomplete_array)
{
Expand Down Expand Up @@ -708,6 +675,160 @@ std::string expr2ct::convert_rec(

/*******************************************************************\

Function: expr2ct::convert_struct_type

Inputs:
src - the struct type being converted
qualifiers - any qualifiers on the type
declarator - the declarator on the type

Outputs: Returns a type declaration for a struct, containing the
body of the struct and in that body the padding parameters.

Purpose: To generate C-like string for defining the given struct

\*******************************************************************/
std::string expr2ct::convert_struct_type(
const typet &src,
const std::string &qualifiers_str,
const std::string &declarator_str)
{
return convert_struct_type(src, qualifiers_str, declarator_str, true, true);
}

/*******************************************************************\

Function: expr2ct::convert_struct_type

Inputs:
src - the struct type being converted
qualifiers - any qualifiers on the type
declarator - the declarator on the type
inc_struct_body - when generating the code, should we include
a complete definition of the struct
inc_padding_components - should the padding parameters be included
Note this only makes sense if inc_struct_body

Outputs: Returns a type declaration for a struct, optionally containing the
body of the struct (and in that body, optionally the padding
parameters).

Purpose: To generate C-like string for declaring (or defining) the given struct

\*******************************************************************/
std::string expr2ct::convert_struct_type(
const typet &src,
const std::string &qualifiers,
const std::string &declarator,
bool inc_struct_body,
bool inc_padding_components)
{
// Either we are including the body (in which case it makes sense to include
// or exclude the parameters) or there is no body so therefore we definitely
// shouldn't be including the parameters
assert(inc_struct_body || !inc_padding_components);

const struct_typet &struct_type=to_struct_type(src);

std::string dest=qualifiers+"struct";

const irep_idt &tag=struct_type.get_tag();
if(tag!="")
dest+=" "+id2string(tag);

if(inc_struct_body)
{
dest+=" {";

for(const struct_union_typet::componentt &component :
struct_type.components())
{
// Skip padding parameters unless we including them
if(component.get_is_padding() && !inc_padding_components)
{
continue;
}

dest+=' ';
dest+=convert_rec(
component.type(),
c_qualifierst(),
id2string(component.get_name()));
dest+=';';
}

dest+=" }";
}

dest+=declarator;

return dest;
}

/*******************************************************************\

Function: expr2ct::convert_array_type

Inputs:
src - The array type to convert
qualifier
declarator_str

Outputs: A C-like type declaration of an array

Purpose: To generate a C-like type declaration of an array. Includes
the size of the array in the []

\*******************************************************************/

std::string expr2ct::convert_array_type(
const typet &src,
const c_qualifierst &qualifiers,
const std::string &declarator_str)
{
return convert_array_type(src, qualifiers, declarator_str, true);
}

/*******************************************************************\

Function: expr2ct::convert_array_type

Inputs:
src - The array type to convert
qualifier
declarator_str
inc_size_if_possible - Should the generated string include
the size of the array (if it is known).

Outputs: A C-like type declaration of an array

Purpose: To generate a C-like type declaration of an array. Optionally
can include or exclude the size of the array in the []

\*******************************************************************/

std::string expr2ct::convert_array_type(
const typet &src,
const c_qualifierst &qualifiers,
const std::string &declarator_str,
bool inc_size_if_possible)
{
// The [...] gets attached to the declarator.
std::string array_suffix;

if(to_array_type(src).size().is_nil() || !inc_size_if_possible)
array_suffix="[]";
else
array_suffix="["+convert(to_array_type(src).size())+"]";

// This won't really parse without declarator.
// Note that qualifiers are passed down.
return convert_rec(
src.subtype(), qualifiers, declarator_str+array_suffix);
}

/*******************************************************************\

Function: expr2ct::convert_typecast

Inputs:
Expand Down Expand Up @@ -2147,11 +2268,7 @@ std::string expr2ct::convert_constant(
}
else if(type.id()==ID_bool)
{
// C doesn't really have these
if(src.is_true())
dest="TRUE";
else
dest="FALSE";
dest=convert_constant_bool(src.is_true());
}
else if(type.id()==ID_unsignedbv ||
type.id()==ID_signedbv ||
Expand All @@ -2167,11 +2284,7 @@ std::string expr2ct::convert_constant(

if(type.id()==ID_c_bool)
{
// C doesn't really have these
if(int_value!=0)
dest="TRUE";
else
dest="FALSE";
dest=convert_constant_bool(int_value!=0);
}
else if(type==char_type() && type!=signed_int_type() && type!=unsigned_int_type())
{
Expand Down Expand Up @@ -2324,6 +2437,28 @@ std::string expr2ct::convert_constant(

/*******************************************************************\

Function: expr2ct::convert_constant_bool

Inputs:
boolean_value - The value of the constant bool expression

Outputs: Returns a C-like representation of the boolean value,
e.g. TRUE or FALSE.

Purpose: To get the C-like representation of a given boolean value.

\*******************************************************************/
std::string expr2ct::convert_constant_bool(bool boolean_value)
{
// C doesn't really have these
if(boolean_value)
return "TRUE";
else
return "FALSE";
}

/*******************************************************************\

Function: expr2ct::convert_struct

Inputs:
Expand All @@ -2337,6 +2472,31 @@ Function: expr2ct::convert_struct
std::string expr2ct::convert_struct(
const exprt &src,
unsigned &precedence)
{
return convert_struct(src, precedence, true);
}

/*******************************************************************\

Function: expr2ct::convert_struct

Inputs:
src - The struct declaration expression
precedence
include_padding_components - Should the generated C code
include the padding members added
to structs for GOTOs benifit

Outputs: A string representation of the struct expression

Purpose: To generate a C-like string representing a struct. Can optionally
include the padding parameters.

\*******************************************************************/
std::string expr2ct::convert_struct(
const exprt &src,
unsigned &precedence,
bool include_padding_components)
{
const typet full_type=ns.follow(src.type());

Expand All @@ -2360,14 +2520,18 @@ std::string expr2ct::convert_struct(
bool newline=false;
size_t last_size=0;

for(struct_typet::componentst::const_iterator
c_it=components.begin();
c_it!=components.end();
c_it++)
for(const struct_union_typet::componentt &component :
struct_type.components())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above for const auto ...

{
if(o_it->type().id()==ID_code)
continue;

if(component.get_is_padding() && !include_padding_components)
{
++o_it;
continue;
}

if(first)
first=false;
else
Expand All @@ -2391,7 +2555,7 @@ std::string expr2ct::convert_struct(
newline=false;

dest+='.';
dest+=c_it->get_string(ID_name);
dest+=component.get_string(ID_name);
dest+='=';
dest+=tmp;

Expand Down
29 changes: 29 additions & 0 deletions src/ansi-c/expr2c_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,29 @@ class expr2ct
const c_qualifierst &qualifiers,
const std::string &declarator);

virtual std::string convert_struct_type(
const typet &src,
const std::string &qualifiers_str,
const std::string &declarator_str);

std::string convert_struct_type(
const typet &src,
const std::string &qualifer_str,
const std::string &declarator_str,
bool inc_struct_body,
bool inc_padding_components);

virtual std::string convert_array_type(
const typet &src,
const c_qualifierst &qualifiers,
const std::string &declarator_str);

std::string convert_array_type(
const typet &src,
const c_qualifierst &qualifiers,
const std::string &declarator_str,
bool inc_size_if_possible);

static std::string indent_str(unsigned indent);

std::unordered_map<irep_idt,
Expand Down Expand Up @@ -197,6 +220,7 @@ class expr2ct
std::string convert_object_descriptor(const exprt &src, unsigned &precedence);
std::string convert_literal(const exprt &src, unsigned &precedence);
virtual std::string convert_constant(const constant_exprt &src, unsigned &precedence);
virtual std::string convert_constant_bool(bool boolean_value);

std::string convert_norep(const exprt &src, unsigned &precedence);

Expand All @@ -209,6 +233,11 @@ class expr2ct
std::string convert_designated_initializer(const exprt &src, unsigned &precedence);
std::string convert_concatenation(const exprt &src, unsigned &precedence);
std::string convert_sizeof(const exprt &src, unsigned &precedence);

std::string convert_struct(
const exprt &src,
unsigned &precedence,
bool include_padding_components);
};

#endif // CPROVER_ANSI_C_EXPR2C_CLASS_H