Go to the documentation of this file.
14 #include <unordered_set>
41 ansi_c_convert_type.
read(type);
42 ansi_c_convert_type.
write(type);
45 if(type.
id()==ID_already_typechecked)
53 bool packed=type.
get_bool(ID_C_packed);
57 type = already_typechecked.
get_type();
59 c_qualifiers.
write(type);
61 type.
set(ID_C_packed,
true);
65 type.
add(ID_C_typedef, _typedef);
81 if(type.
id()==ID_code)
83 else if(type.
id()==ID_array)
85 else if(type.
id()==ID_pointer)
91 else if(type.
id()==ID_struct ||
94 else if(type.
id()==ID_c_enum)
96 else if(type.
id()==ID_c_enum_tag)
98 else if(type.
id()==ID_c_bit_field)
100 else if(type.
id()==ID_typeof)
102 else if(type.
id() == ID_typedef_type)
104 else if(type.
id() == ID_struct_tag ||
105 type.
id() == ID_union_tag)
109 else if(type.
id()==ID_vector)
113 else if(type.
id() == ID_frontend_vector)
117 else if(type.
id()==ID_custom_unsignedbv ||
118 type.
id()==ID_custom_signedbv ||
119 type.
id()==ID_custom_floatbv ||
120 type.
id()==ID_custom_fixedbv)
122 else if(type.
id()==ID_gcc_attribute_mode)
135 if(underlying_type.
id()==ID_c_enum_tag)
140 assert(underlying_type.
id()==ID_signedbv ||
141 underlying_type.
id()==ID_unsignedbv);
144 if(underlying_type.
id()==ID_signedbv ||
145 underlying_type.
id()==ID_unsignedbv)
151 if(gcc_attr_mode ==
"__QI__")
158 else if(gcc_attr_mode ==
"__byte__")
165 else if(gcc_attr_mode ==
"__HI__")
172 else if(gcc_attr_mode ==
"__SI__")
179 else if(gcc_attr_mode ==
"__word__")
186 else if(gcc_attr_mode ==
"__pointer__")
193 else if(gcc_attr_mode ==
"__DI__")
212 else if(gcc_attr_mode ==
"__TI__")
219 else if(gcc_attr_mode ==
"__V2SI__")
232 else if(gcc_attr_mode ==
"__V4SI__")
262 else if(underlying_type.
id()==ID_floatbv)
266 if(gcc_attr_mode ==
"__SF__")
268 else if(gcc_attr_mode ==
"__DF__")
270 else if(gcc_attr_mode ==
"__TF__")
272 else if(gcc_attr_mode ==
"__V2SF__")
275 else if(gcc_attr_mode ==
"__V2DF__")
278 else if(gcc_attr_mode ==
"__V4SF__")
281 else if(gcc_attr_mode ==
"__V4DF__")
292 else if(underlying_type.
id()==ID_complex)
297 if(gcc_attr_mode ==
"__SC__")
299 else if(gcc_attr_mode ==
"__DC__")
301 else if(gcc_attr_mode ==
"__TC__")
314 error() <<
"attribute mode '" << gcc_attr_mode
315 <<
"' applied to inappropriate type '" <<
to_string(type) <<
"'"
323 if(type.
get_bool(ID_C_restricted) &&
324 type.
id()!=ID_pointer &&
328 error() <<
"only a pointer can be 'restrict'" <<
eom;
337 static_cast<const exprt &
>(type.
find(ID_size));
347 error() <<
"failed to convert bit vector width to constant" <<
eom;
354 error() <<
"bit vector width invalid" <<
eom;
363 if(type.
id()==ID_custom_unsignedbv)
364 type.
id(ID_unsignedbv);
365 else if(type.
id()==ID_custom_signedbv)
366 type.
id(ID_signedbv);
367 else if(type.
id()==ID_custom_fixedbv)
372 static_cast<const exprt &
>(type.
find(ID_f));
385 error() <<
"failed to convert number of fraction bits to constant" <<
eom;
389 if(f_int<0 || f_int>size_int)
392 error() <<
"fixedbv fraction width invalid" <<
eom;
399 else if(type.
id()==ID_custom_floatbv)
404 static_cast<const exprt &
>(type.
find(ID_f));
417 error() <<
"failed to convert number of fraction bits to constant" <<
eom;
421 if(f_int<1 || f_int+1>=size_int)
424 error() <<
"floatbv fraction width invalid" <<
eom;
444 if(parameters.empty())
451 if(type.
parameters().back().id()==ID_ellipsis)
462 if(param.id()==ID_declaration)
472 std::list<codet> tmp_clean_code;
482 if(identifier.
empty())
497 param.
swap(parameter);
503 if(parameters.size() == 1 && parameters[0].type().id() == ID_empty)
518 if(decl_return_type.
id() == ID_array)
521 error() <<
"function must not return array" <<
eom;
525 if(decl_return_type.
id() == ID_code)
528 error() <<
"function must not return function type" <<
eom;
550 (followed_subtype.
id() == ID_struct || followed_subtype.
id() == ID_union) &&
555 error() <<
"array has incomplete element type" <<
eom;
564 error() <<
"array of function element type" <<
eom;
592 error() <<
"failed to convert constant: "
600 error() <<
"array size must not be negative, "
601 "but got " << s <<
eom;
607 else if(tmp_size.
id()==ID_infinity)
611 else if(tmp_size.
id()==ID_symbol &&
632 <<
"' is not constant" <<
eom;
640 size_source_location,
643 new_symbol.
type.
set(ID_C_constant,
true);
653 assignment.
lhs()=symbol_expr;
654 assignment.
rhs() = new_symbol.
value;
683 if(subtype.
id()!=ID_signedbv &&
684 subtype.
id()!=ID_unsignedbv &&
685 subtype.
id()!=ID_floatbv &&
686 subtype.
id()!=ID_fixedbv)
689 error() <<
"cannot make a vector of subtype "
700 error() <<
"failed to convert constant: "
708 error() <<
"vector size must be positive, "
709 "but got " << s <<
eom;
716 if(!sub_size_expr_opt.has_value())
719 error() <<
"failed to determine size of vector base type '"
724 simplify(sub_size_expr_opt.value(), *
this);
726 const auto sub_size = numeric_cast<mp_integer>(sub_size_expr_opt.value());
728 if(!sub_size.has_value())
731 error() <<
"failed to determine size of vector base type '"
744 if(s % *sub_size != 0)
747 error() <<
"vector size (" << s
748 <<
") expected to be multiple of base type size (" << *sub_size
778 remove_qualifiers.
write(type);
780 bool is_packed = type.
get_bool(ID_C_packed);
791 compound_symbol.
type=type;
796 std::string typestr =
type2name(compound_symbol.
type, *
this);
797 compound_symbol.
base_name =
"#anon#" + typestr;
798 compound_symbol.
name=
"tag-#anon#"+typestr;
799 identifier=compound_symbol.
name;
812 identifier=type.
find(ID_tag).
get(ID_identifier);
815 symbol_tablet::symbolst::const_iterator s_it=
823 type.
set(ID_tag, base_name);
827 compound_symbol.
name=identifier;
829 compound_symbol.
type=type;
852 s_it->second.type.id() == type.
id() &&
860 type.
set(ID_tag, base_name);
866 else if(s_it->second.type.id() != type.
id())
869 error() <<
"redefinition of '" << s_it->second.pretty_name <<
"'"
870 <<
" as different kind of tag" <<
eom;
876 error() <<
"redefinition of body of '" << s_it->second.pretty_name
885 if(type.
id() == ID_union)
887 else if(type.
id() == ID_struct)
895 original_qualifiers.
write(type);
898 type.
set(ID_C_packed,
true);
909 old_components.swap(components);
912 for(
auto &decl : old_components)
915 assert(decl.id()==ID_declaration);
923 new_component.
id(ID_static_assert);
926 assert(new_component.
operands().size()==2);
927 components.push_back(new_component);
935 for(
const auto &declarator : declaration.
declarators())
938 declarator.get_base_name(), declaration.
full_type(declarator));
944 : declarator.source_location();
952 (new_component.
type().
id()!=ID_array ||
956 error() <<
"incomplete type not permitted here" <<
eom;
960 if(new_component.
type().
id() == ID_empty)
963 error() <<
"void-typed member not permitted" <<
eom;
967 components.push_back(new_component);
972 unsigned anon_member_counter=0;
975 for(
auto &member : components)
977 if(!member.get_name().empty())
981 member.set_anonymous(
true);
987 std::unordered_set<irep_idt> members;
989 for(
const auto &c : components)
991 if(!members.insert(c.get_name()).second)
994 error() <<
"duplicate member '" << c.get_name() <<
'\'' <<
eom;
1003 if(type.
id()==ID_struct ||
1004 type.
id()==ID_union)
1006 for(struct_union_typet::componentst::iterator
1007 it=components.begin();
1008 it!=components.end();
1011 typet &c_type=it->type();
1013 if(c_type.
id()==ID_array &&
1017 if(type.
id()==ID_struct && it!=--components.
end())
1020 error() <<
"flexible struct member must be last member" <<
eom;
1026 c_type.
set(ID_C_flexible_array_member,
true);
1035 if(type.
id()==ID_struct)
1037 else if(type.
id()==ID_union)
1042 for(struct_typet::componentst::iterator
1043 it=components.begin();
1044 it!=components.end();
1047 if(it->type().id()==ID_c_bit_field &&
1049 it=components.erase(it);
1055 for(struct_union_typet::componentst::iterator
1056 it=components.begin();
1057 it!=components.end();
1060 if(it->id()==ID_static_assert)
1065 error() <<
"static_assert not supported in compound body" <<
eom;
1078 error() <<
"failed _Static_assert" <<
eom;
1086 it=components.erase(it);
1128 bool is_packed)
const
1200 const bool have_underlying_type =
1203 if(have_underlying_type)
1207 const typet &underlying_type =
1208 static_cast<const typet &
>(type.
find(ID_enum_underlying_type));
1212 std::ostringstream msg;
1213 msg <<
"non-integral type '" << underlying_type.
get(ID_C_c_type)
1214 <<
"' is an invalid underlying type";
1221 mp_integer value=0, min_value=0, max_value=0;
1223 std::list<c_enum_typet::c_enum_membert> enum_members;
1247 tmp_v.
id() == ID_constant &&
1254 error() <<
"enum is not a constant" <<
eom;
1264 typet constant_type;
1266 if(have_underlying_type)
1268 constant_type = type.
find_type(ID_enum_underlying_type);
1271 if(value < tmp.smallest() || value > tmp.largest())
1273 std::ostringstream msg;
1274 msg <<
"enumerator value is not representable in the underlying type '"
1275 << constant_type.
get(ID_C_c_type) <<
"'";
1286 declaration.
type()=constant_type;
1302 enum_members.push_back(member);
1312 bool is_packed=type.
get_bool(ID_C_packed);
1317 if(have_underlying_type)
1328 std::size_t width = underlying_type.
get_width();
1329 for(
auto &member : enum_members)
1341 std::string anon_identifier=
"#anon_enum";
1343 for(
const auto &member : enum_members)
1345 anon_identifier+=
'$';
1346 anon_identifier+=
id2string(member.get_base_name());
1347 anon_identifier+=
'=';
1348 anon_identifier+=
id2string(member.get_value());
1352 anon_identifier+=
"#packed";
1354 type.
add(ID_tag).
set(ID_identifier, anon_identifier);
1365 enum_tag_symbol.
type=type;
1366 enum_tag_symbol.
location=source_location;
1369 enum_tag_symbol.
name=identifier;
1374 for(
const auto &member : enum_members)
1375 body.push_back(member);
1380 symbol_tablet::symbolst::const_iterator s_it=
1386 const symbolt &symbol=s_it->second;
1388 if(symbol.
type.
id() != ID_c_enum)
1391 error() <<
"use of tag that does not match previous declaration" <<
eom;
1406 if(!base_name.
empty())
1409 error() <<
"redeclaration of enum tag" <<
eom;
1421 type.
id(ID_c_enum_tag);
1423 type.
set(ID_identifier, identifier);
1433 error() <<
"anonymous enum tag without members" <<
eom;
1440 warning() <<
"ignoring specification of underlying type for enum" <<
eom;
1450 symbol_tablet::symbolst::const_iterator s_it=
1456 const symbolt &symbol=s_it->second;
1458 if(symbol.
type.
id() != ID_c_enum)
1461 error() <<
"use of tag that does not match previous declaration" <<
eom;
1469 new_type.
add(ID_tag)=tag;
1475 enum_tag_symbol.
type=new_type;
1476 enum_tag_symbol.
location=source_location;
1479 enum_tag_symbol.
name=identifier;
1505 error() <<
"failed to convert bit field width" <<
eom;
1512 error() <<
"bit field width is negative" <<
eom;
1516 type.
set_width(numeric_cast_v<std::size_t>(i));
1522 std::size_t sub_width=0;
1524 if(underlying_type.
id() == ID_bool)
1530 underlying_type.
id() == ID_signedbv ||
1531 underlying_type.
id() == ID_unsignedbv || underlying_type.
id() == ID_c_bool)
1535 else if(underlying_type.
id() == ID_c_enum_tag)
1540 const auto &c_enum_type =
1543 if(c_enum_type.is_incomplete())
1546 error() <<
"bit field has incomplete enum type" <<
eom;
1555 error() <<
"bit field with non-integer type: " <<
to_string(underlying_type)
1563 error() <<
"bit field (" << i
1564 <<
" bits) larger than type (" << sub_width <<
" bits)"
1577 c_qualifiers.
read(type);
1579 const auto &as_expr = (
const exprt &)type;
1581 if(!as_expr.has_operands())
1593 if(expr.
id()==ID_address_of &&
1603 c_qualifiers.
write(type);
1610 symbol_tablet::symbolst::const_iterator s_it =
1616 error() <<
"typedef symbol '" << identifier <<
"' not found" <<
eom;
1620 const symbolt &symbol = s_it->second;
1625 error() <<
"expected type symbol for typedef" <<
eom;
1632 bool is_packed = type.
get_bool(ID_C_packed);
1637 c_qualifiers.
write(type);
1640 type.
set(ID_C_packed,
true);
1657 if(type.
id()==ID_array)
1663 else if(type.
id()==ID_code)
1671 else if(type.
id()==ID_KnR)
virtual void read(const typet &src) override
const irep_idt & get_identifier() const
#define UNREACHABLE
This should be used to mark dead code.
const componentst & components() const
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
static exprt conditional_cast(const exprt &expr, const typet &type)
const unary_exprt & to_unary_expr(const exprt &expr)
Cast an exprt to a unary_exprt.
void set_identifier(const irep_idt &identifier)
virtual void typecheck_vector_type(typet &type)
bool is_incomplete() const
const declaratorst & declarators() const
void set_value(const irep_idt &value)
bool is_incomplete() const
enum types may be incomplete
virtual void typecheck_array_type(array_typet &type)
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
signedbv_typet signed_long_long_int_type()
signedbv_typet signed_char_type()
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
Unbounded, signed rational numbers.
The type of an expression, extends irept.
std::vector< parametert > parameterst
typet enum_constant_type(const mp_integer &min, const mp_integer &max) const
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
void typecheck_declaration(ansi_c_declarationt &)
virtual std::string to_string(const exprt &expr)
const irept & find(const irep_idt &name) const
Base type for structs and unions.
typet type
Type of symbol.
const constant_exprt & size() const
const integer_bitvector_typet & to_integer_bitvector_type(const typet &type)
Cast a typet to an integer_bitvector_typet.
virtual void write(typet &type)
static void add_rounding_mode(exprt &)
bool is_signed(const typet &t)
Convenience function – is the type signed?
const mp_integer string2integer(const std::string &n, unsigned base)
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a typet to a c_enum_typet.
Unbounded, signed integers (mathematical integers, not bitvectors)
const type_with_subtypet & to_type_with_subtype(const typet &type)
A codet representing the declaration of a local variable.
bitvector_typet enum_underlying_type(const mp_integer &min, const mp_integer &max, bool is_packed) const
Base class for all expressions.
std::vector< componentt > componentst
irep_idt base_name
Base (non-scoped) name.
A struct tag type, i.e., struct_typet with an identifier.
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
Complex numbers made of pair of given subtype.
Thrown when we can't handle something in an input source file.
void make_incomplete()
enum types may be incomplete
void move_symbol(symbolt &symbol, symbolt *&new_symbol)
virtual void typecheck_type(typet &type)
void make_incomplete()
A struct/union may be incomplete.
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
unsignedbv_typet unsigned_char_type()
bool is_true() const
Return whether the expression is a constant representing true.
const irep_idt & get_identifier() const
virtual void typecheck_c_bit_field_type(c_bit_field_typet &type)
struct configt::ansi_ct ansi_c
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
Expression to hold a symbol (variable)
const ansi_c_declaratort & declarator() const
floatbv_typet gcc_float128_type()
bool get_is_static_assert() const
A union tag type, i.e., union_typet with an identifier.
unsignedbv_typet unsigned_short_int_type()
bool is_false() const
Return whether the expression is a constant representing false.
std::list< codet > clean_code
already_typechecked_typet & to_already_typechecked_type(typet &type)
irep_idt get_name() const
const irep_idt & get(const irep_idt &name) const
irep_idt pretty_name
Language-specific display name.
virtual void make_constant(exprt &expr)
const binary_exprt & to_binary_expr(const exprt &expr)
Cast an exprt to a binary_exprt.
unsignedbv_typet unsigned_long_long_int_type()
unsignedbv_typet unsigned_long_int_type()
const exprt & size() const
typet & type()
Return the type of the expression.
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
mstreamt & result() const
signedbv_typet signed_int_type()
void add_padding(struct_typet &type, const namespacet &ns)
irep_idt get_base_name() const
Type for C bit fields These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (...
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
const std::string & id2string(const irep_idt &d)
source_locationt source_location
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
signedbv_typet gcc_signed_int128_type()
static std::string type2name(const typet &type, const namespacet &ns, symbol_numbert &symbol_number)
void set(const irep_idt &name, const irep_idt &value)
#define PRECONDITION(CONDITION)
const source_locationt & source_location() const
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
virtual bool is_complete_type(const typet &type) const
void set_pretty_name(const irep_idt &name)
signedbv_typet signed_short_int_type()
virtual void write(typet &src) const override
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
floatbv_typet float_type()
virtual void typecheck_c_enum_tag_type(c_enum_tag_typet &type)
signedbv_typet signed_size_type()
bool simplify(exprt &expr, const namespacet &ns)
std::size_t long_long_int_width
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
bool is_signed_or_unsigned_bitvector(const typet &type)
This method tests, if the given typet is a signed or unsigned bitvector.
void set_identifier(const irep_idt &identifier)
symbol_tablet & symbol_table
mp_integer alignment(const typet &type, const namespacet &ns)
pointer_typet pointer_type(const typet &subtype)
A codet representing an assignment in the program.
unsignedbv_typet unsigned_int_type()
virtual void make_constant_index(exprt &expr)
const irep_idt & id() const
virtual void typecheck_typedef_type(typet &type)
typet & add_type(const irep_idt &name)
virtual void typecheck_typeof_type(typet &type)
ansi_c_declarationt & to_ansi_c_declaration(exprt &expr)
const parameterst & parameters() const
source_locationt & add_source_location()
void set_width(std::size_t width)
const typedef_typet & to_typedef_type(const typet &type)
Cast a generic typet to a typedef_typet.
id_type_mapt parameter_map
void set_base_name(const irep_idt &name)
floatbv_typet double_type()
virtual void typecheck_expr(exprt &expr)
const typet & underlying_type() const
std::size_t get_width() const
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
exprt value
Initial value of symbol.
message_handlert & get_message_handler()
irept & add(const irep_idt &name)
C enum tag type, i.e., c_enum_typet with an identifier.
std::string::const_iterator end() const
void set_base_name(const irep_idt &base_name)
Base class of fixed-width bit-vector types.
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
source_locationt location
Source code location of definition of symbol.
typet & index_type_nonconst()
The type of the index expressions into any instance of this type.
const symbolst & symbols
Read-only field, used to look up symbols given their names.
bool is_constant() const
Return whether the expression is a constant.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
typet full_type(const ansi_c_declaratort &) const
unsignedbv_typet gcc_unsigned_int128_type()
virtual void typecheck_custom_type(typet &type)
const typet & find_type(const irep_idt &name) const
std::size_t short_int_width
const typet & subtype() const
signedbv_typet signed_long_int_type()
static void make_already_typechecked(typet &type)
const typet & return_type() const
optionalt< exprt > size_of_expr(const typet &type, const namespacet &ns)
virtual void read(const typet &type)
There are a large number of kinds of tree structured or tree-like data in CPROVER.
virtual void typecheck_c_enum_type(typet &type)
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
virtual void typecheck_compound_type(struct_union_typet &type)
void remove(const irep_idt &name)
source_locationt & add_source_location()
Semantic type conversion.
unsignedbv_typet size_type()
virtual void typecheck_code_type(code_typet &type)
mstreamt & warning() const
bitvector_typet c_index_type()
const source_locationt & source_location() const
bool is_incomplete() const
A struct/union may be incomplete.
symbolt & get_fresh_aux_symbol(const typet &type, const std::string &name_prefix, const std::string &basename_prefix, const source_locationt &source_location, const irep_idt &symbol_mode, const namespacet &ns, symbol_table_baset &symbol_table)
Installs a fresh-named symbol with respect to the given namespace ns with the requested name pattern ...
irep_idt name
The unique identifier.
bool get_bool(const irep_idt &name) const
bool is_transparent_union
virtual void typecheck_compound_body(struct_union_typet &type)
std::size_t long_int_width
virtual void make_index_type(exprt &expr)
const typet & element_type() const
The type of the elements of the array.
virtual void adjust_function_parameter(typet &type) const
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
const std::string integer2string(const mp_integer &n, unsigned base)