32 const exprt &expr)
const 40 const typet &type)
const 49 if(type.
id()==ID_symbol)
51 else if(type.
id()==ID_c_enum_tag)
53 else if(type.
id()==ID_struct_tag)
55 else if(type.
id()==ID_union_tag)
64 const typet &type)
const 68 if(followed.
id()==ID_struct || followed.
id()==ID_union)
72 const std::string &tag=followed.
get_string(ID_tag);
80 for(struct_union_typet::componentst::const_iterator
81 it=components.begin();
85 const typet &subtype=it->type();
90 if(it->get_base_name()!=
"")
102 else if(followed.
id()==ID_pointer)
106 else if(followed.
id()==ID_incomplete_struct ||
107 followed.
id()==ID_incomplete_union)
121 exprt &conflict_path)
124 debug() <<
"<BEGIN DEPTH " << depth <<
">" <<
eom;
133 msg=
"type classes differ";
134 else if(t1.
id()==ID_pointer ||
150 else if(t1.
id()==ID_pointer)
151 msg=
"pointer types differ";
153 msg=
"array types differ";
155 else if(t1.
id()==ID_struct ||
164 exprt conflict_path_before=conflict_path;
166 if(components1.size()!=components2.size())
168 msg=
"number of members is different (";
169 msg+=std::to_string(components1.size())+
'/';
170 msg+=std::to_string(components2.size())+
')';
174 for(std::size_t i=0; i<components1.size(); ++i)
176 const typet &subtype1=components1[i].type();
177 const typet &subtype2=components2[i].type();
179 if(components1[i].get_name()!=components2[i].get_name())
181 msg=
"names of member "+std::to_string(i)+
" differ (";
182 msg+=
id2string(components1[i].get_name())+
'/';
183 msg+=
id2string(components2[i].get_name())+
')';
188 typedef std::unordered_set<typet, irep_hash> type_sett;
189 type_sett parent_types;
191 exprt e=conflict_path_before;
192 while(e.
id()==ID_dereference ||
196 parent_types.insert(e.
type());
200 conflict_path=conflict_path_before;
201 conflict_path.
type()=t1;
206 parent_types.find(t1)==parent_types.end())
216 msg=
"type of member "+
235 if(parent_types.find(t1)==parent_types.end())
241 else if(t1.
id()==ID_c_enum)
251 msg=
"enum value types are different (";
255 else if(members1.size()!=members2.size())
257 msg=
"number of enum members is different (";
258 msg+=std::to_string(members1.size())+
'/';
259 msg+=std::to_string(members2.size())+
')';
263 for(std::size_t i=0; i<members1.size(); ++i)
267 msg=
"names of member "+std::to_string(i)+
" differ (";
272 else if(members1[i].get_value()!=members2[i].get_value())
274 msg=
"values of member "+std::to_string(i)+
" differ (";
275 msg+=
id2string(members1[i].get_value())+
'/';
276 msg+=
id2string(members2[i].get_value())+
')';
282 msg+=
"\nenum declarations at\n";
286 else if(t1.
id()==ID_code)
297 if(parameters1.size()!=parameters2.size())
299 msg=
"parameter counts differ (";
300 msg+=std::to_string(parameters1.size())+
'/';
301 msg+=std::to_string(parameters2.size())+
')';
318 msg=
"return types differ";
322 for(std::size_t i=0; i<parameters1.size(); i++)
324 const typet &subtype1=parameters1[i].type();
325 const typet &subtype2=parameters2[i].type();
342 msg=
"parameter types differ";
350 msg=
"conflict on POD";
355 error() <<
"reason for conflict at " 357 <<
": " << msg <<
'\n';
365 debug() <<
"<END DEPTH " << depth <<
">" <<
eom;
372 const std::string &msg)
376 error() <<
"error: " << msg <<
" `" 379 error() <<
"old definition in module `" << old_symbol.
module 380 <<
"' " << old_symbol.
location <<
'\n' 382 error() <<
"new definition in module `" << new_symbol.
module 383 <<
"' " << new_symbol.
location <<
'\n' 392 const std::string &msg)
396 warning() <<
"warning: " << msg <<
" \"" 399 warning() <<
"old definition in module " << old_symbol.
module 400 <<
" " << old_symbol.
location <<
'\n' 402 warning() <<
"new definition in module " << new_symbol.
module 403 <<
" " << new_symbol.
location <<
'\n' 414 id2string(
id)+
"$link"+std::to_string(++cnt);
427 return new_identifier;
463 "implicit function declaration");
476 "ignoring conflicting implicit function declaration");
503 "function declaration conflicts with with weak definition");
517 "ignoring conflicting weak function declaration");
531 "ignoring conflicting function alias declaration");
542 "ignoring conflicting function declarations");
562 "conflicting parameter counts of function declarations");
568 std::string warn_msg;
570 typedef std::deque<std::pair<typet, typet> > conflictst;
571 conflictst conflicts;
577 code_typet::parameterst::const_iterator
587 std::make_pair(o_it->type(), n_it->type()));
595 "conflicting parameter counts of function declarations");
604 "conflicting parameter counts of function declarations");
608 while(!conflicts.empty())
615 if((t1.
id()==ID_empty || t2.id()==ID_empty) &&
619 warn_msg=
"void/non-void return type conflict on function";
625 else if((t1.
id()==ID_pointer || t2.id()==ID_pointer) &&
630 warn_msg=
"different pointer types in extern function";
635 else if((t1.
id()==ID_pointer || t2.id()==ID_pointer) &&
640 warn_msg=
"pointer parameter types differ between " 641 "declaration and definition";
647 else if((t1.
id()==ID_union &&
648 (t1.
get_bool(ID_C_transparent_union) ||
649 conflicts.front().first.get_bool(ID_C_transparent_union))) ||
650 (t2.id()==ID_union &&
651 (t2.get_bool(ID_C_transparent_union) ||
652 conflicts.front().second.get_bool(ID_C_transparent_union))))
656 (t1.
get_bool(ID_C_transparent_union) ||
657 conflicts.front().first.get_bool(ID_C_transparent_union)) &&
662 const typet &src_type=t1.
id()==ID_union?t2:t1;
665 for(union_typet::componentst::const_iterator
673 warn_msg=
"conflict on transparent union parameter in function";
683 conflicts.pop_front();
686 if(!conflicts.empty())
691 conflicts.front().first,
692 conflicts.front().second);
697 "conflicting function declarations");
735 warning() <<
"function `" << old_symbol.
name <<
"' in module `" 736 << new_symbol.
module <<
"' is shadowed by a definition in module `" 743 "duplicate definition of function");
755 if(t1.
id()==ID_symbol ||
756 t1.
id()==ID_struct_tag ||
757 t1.
id()==ID_union_tag ||
758 t1.
id()==ID_c_enum_tag)
762 if(info.
o_symbols.insert(identifier).second)
773 else if(t2.
id()==ID_symbol ||
774 t2.
id()==ID_struct_tag ||
775 t2.
id()==ID_union_tag ||
776 t2.
id()==ID_c_enum_tag)
780 if(info.
n_symbols.insert(identifier).second)
791 else if(t1.
id()==ID_pointer && t2.
id()==ID_array)
797 else if(t1.
id()==ID_array && t2.
id()==ID_pointer)
802 else if((t1.
id()==ID_incomplete_struct && t2.
id()==ID_struct) ||
803 (t1.
id()==ID_incomplete_union && t2.
id()==ID_union))
809 else if((t1.
id()==ID_struct && t2.
id()==ID_incomplete_struct) ||
810 (t1.
id()==ID_union && t2.
id()==ID_incomplete_union))
815 else if(t1.
id()!=t2.
id())
821 if(t1.
id()==ID_pointer)
830 "conflicting pointer types for variable");
837 "conflicting pointer types for variable");
842 else if(t1.
id()==ID_array &&
855 else if(new_size.
is_nil() ||
869 "conflicting array sizes for variable");
874 else if(t1.
id()==ID_struct || t1.
id()==ID_union)
882 struct_union_typet::componentst::const_iterator
883 it1=components1.begin(), it2=components2.begin();
885 it1!=components1.end() && it2!=components2.end();
888 if(it1->get_name()!=it2->get_name() ||
892 if(it1!=components1.end() || it2!=components2.end())
924 bool set_to_new=
false;
934 if(old_type.
id()==ID_struct ||
935 old_type.
id()==ID_union ||
936 old_type.
id()==ID_array ||
937 old_type.
id()==ID_c_enum)
947 "conflicting types for variable");
972 tmp_new=new_symbol.
value;
985 warning() <<
"warning: conflicting initializers for" 986 <<
" variable \"" << old_symbol.
name <<
"\"\n";
987 warning() <<
"using old value in module " 988 << old_symbol.
module <<
" " 992 warning() <<
"ignoring new value in module " 993 << new_symbol.
module <<
" " 1008 bool is_code_old_symbol=old_symbol.
type.
id()==ID_code;
1009 bool is_code_new_symbol=new_symbol.
type.
id()==ID_code;
1011 if(is_code_old_symbol!=is_code_new_symbol)
1015 "conflicting definition for symbol");
1017 if(is_code_old_symbol)
1041 "conflicting definition for symbol");
1043 if(old_symbol.
type==new_symbol.
type)
1046 if(old_symbol.
type.
id()==ID_incomplete_struct &&
1047 new_symbol.
type.
id()==ID_struct)
1054 if(old_symbol.
type.
id()==ID_struct &&
1055 new_symbol.
type.
id()==ID_incomplete_struct)
1061 if(old_symbol.
type.
id()==ID_incomplete_union &&
1062 new_symbol.
type.
id()==ID_union)
1069 if(old_symbol.
type.
id()==ID_union &&
1070 new_symbol.
type.
id()==ID_incomplete_union)
1076 if(old_symbol.
type.
id()==ID_array &&
1077 new_symbol.
type.
id()==ID_array &&
1105 "unexpected difference between type symbols");
1117 if(old_symbol.
type==new_symbol.
type)
1120 if(old_symbol.
type.
id()==ID_incomplete_struct &&
1121 new_symbol.
type.
id()==ID_struct)
1124 if(old_symbol.
type.
id()==ID_struct &&
1125 new_symbol.
type.
id()==ID_incomplete_struct)
1128 if(old_symbol.
type.
id()==ID_incomplete_union &&
1129 new_symbol.
type.
id()==ID_union)
1132 if(old_symbol.
type.
id()==ID_union &&
1133 new_symbol.
type.
id()==ID_incomplete_union)
1136 if(old_symbol.
type.
id()==ID_array &&
1137 new_symbol.
type.
id()==ID_array &&
1161 if(s_it->second.is_type)
1167 for(find_symbols_sett::const_iterator
1168 it=symbols_used.begin();
1169 it!=symbols_used.end();
1172 used_by[*it].insert(s_it->first);
1177 std::stack<irep_idt> queue;
1179 for(id_sett::const_iterator
1180 d_it=needs_to_be_renamed.begin();
1181 d_it!=needs_to_be_renamed.end();
1185 while(!queue.empty())
1192 for(id_sett::const_iterator
1196 if(needs_to_be_renamed.insert(*d_it).second)
1200 debug() <<
"LINKING: needs to be renamed (dependency): " 1211 for(id_sett::const_iterator
1212 it=needs_to_be_renamed.begin();
1213 it!=needs_to_be_renamed.end();
1223 new_identifier=
rename(*it);
1225 new_symbol.
name=new_identifier;
1228 debug() <<
"LINKING: renaming " << *it <<
" to " 1229 << new_identifier <<
eom;
1255 if(s_it->first!=s_it->second.name)
1262 symbol_tablet::symbolst::iterator
1271 collisions.insert(s_it->first);
1276 for(id_sett::const_iterator
1277 i_it=collisions.begin();
1278 i_it!=collisions.end();
1293 if(!s_it->second.is_type &&
1294 !s_it->second.is_macro &&
1295 s_it->second.value.is_not_nil())
1312 symbol_tablet::symbolst::const_iterator
1318 needs_to_be_renamed.insert(s_it->first);
1320 debug() <<
"LINKING: needs to be renamed: " 1321 << s_it->first <<
eom;
1342 dest_symbol_table, new_symbol_table, message_handler);
The type of an expression.
irep_idt name
The unique identifier.
const typet & follow(const typet &src) const
std::unordered_map< irep_idt, id_sett, irep_id_hash > used_byt
const std::string & id2string(const irep_idt &d)
#define forall_symbols(it, expr)
void link_error(const symbolt &old_symbol, const symbolt &new_symbol, const std::string &msg)
exprt simplify_expr(const exprt &src, const namespacet &ns)
void detailed_conflict_report(const symbolt &old_symbol, const symbolt &new_symbol, const typet &type1, const typet &type2)
bool base_type_eq(const typet &type1, const typet &type2, const namespacet &ns)
bool has_ellipsis() const
const union_typet & to_union_type(const typet &type)
Cast a generic typet to a union_typet.
void insert_type(const irep_idt &old_id, const irep_idt &new_id)
const irep_idt & get_function() const
std::string as_string() const
std::string from_expr(const namespacet &ns, const irep_idt &identifier, const exprt &expr)
std::vector< componentt > componentst
std::vector< parametert > parameterst
void do_type_dependencies(id_sett &)
exprt value
Initial value of symbol.
const componentst & components() const
bool linking(symbol_tablet &dest_symbol_table, symbol_tablet &new_symbol_table, message_handlert &message_handler)
const memberst & members() const
irep_idt module
Name of module the symbol belongs to.
symbol_tablet & main_symbol_table
mp_integer pointer_offset_bits(const typet &type, const namespacet &ns)
void link_warning(const symbolt &old_symbol, const symbolt &new_symbol, const std::string &msg)
Symbol table entry.This is a symbol in the symbol table, stored in an object of type symbol_tablet...
std::string expr_to_string(const namespacet &ns, const irep_idt &identifier, const exprt &expr) const
A constant literal expression.
static mstreamt & eom(mstreamt &m)
bool get_bool(const irep_namet &name) const
std::string get_base_name(const std::string &in, bool strip_suffix)
cleans a filename from path and extension
void detailed_conflict_report_rec(const symbolt &old_symbol, const symbolt &new_symbol, const typet &type1, const typet &type2, unsigned depth, exprt &conflict_path)
bool needs_renaming_non_type(const symbolt &old_symbol, const symbolt &new_symbol)
Extract member of struct or union.
std::unordered_set< irep_idt, irep_id_hash > find_symbols_sett
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a generic typet to a struct_union_typet.
#define Forall_symbols(it, expr)
const symbolt & new_symbol
const typet & follow_tag(const union_tag_typet &src) const
const irep_idt & id() const
bool needs_renaming(const symbolt &old_symbol, const symbolt &new_symbol)
const array_typet & to_array_type(const typet &type)
Cast a generic typet to an array_typet.
void rename_symbols(const id_sett &needs_to_be_renamed)
class symbol_exprt symbol_expr() const
produces a symbol_exprt for a symbol
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a generic typet to a c_enum_typet.
std::string type_to_name(const namespacet &ns, const irep_idt &identifier, const typet &type)
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a generic typet to a c_enum_tag_typet.
const source_locationt & find_source_location() const
virtual std::string id() const
source_locationt source_location
Operator to dereference a pointer.
API to expression classes.
const irep_idt & get(const irep_namet &name) const
const symbolt & old_symbol
const exprt & size() const
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
bool needs_renaming_type(const symbolt &old_symbol, const symbolt &new_symbol)
irep_idt rename(irep_idt)
std::string from_type(const namespacet &ns, const irep_idt &identifier, const typet &type)
std::string type_to_string(const namespacet &ns, const irep_idt &identifier, const typet &type) const
static const typet & follow_tags_symbols(const namespacet &ns, const typet &type)
replace_symbolt object_type_updates
void duplicate_code_symbol(symbolt &old_symbol, symbolt &new_symbol)
const source_locationt & source_location() const
const irep_idt & display_name() const
bool adjust_object_type_rec(const typet &type1, const typet &type2, adjust_type_infot &info)
Unbounded, signed integers.
typet type
Type of symbol.
source_locationt location
Source code location of definition of symbol.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a generic typet to a union_tag_typet.
void insert_expr(const irep_idt &old_id, const irep_idt &new_id)
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a generic typet to a union_tag_typet.
symbol_tablet & src_symbol_table
Base class for all expressions.
void duplicate_non_type_symbol(symbolt &old_symbol, symbolt &new_symbol)
const parameterst & parameters() const
rename_symbolt rename_symbol
void duplicate_object_symbol(symbolt &old_symbol, symbolt &new_symbol)
const std::string & get_string(const irep_namet &name) const
const code_typet & to_code_type(const typet &type)
Cast a generic typet to a code_typet.
const std::string & id_string() const
void insert(const irep_idt &identifier, const exprt &expr)
std::string type_to_string_verbose(const namespacet &ns, const symbolt &symbol, const typet &type) const
bool adjust_object_type(const symbolt &old_symbol, const symbolt &new_symbol, bool &set_to_new)
Expression to hold a symbol (variable)
void find_type_and_expr_symbols(const exprt &src, find_symbols_sett &dest)
void duplicate_type_symbol(symbolt &old_symbol, symbolt &new_symbol)
const typet & subtype() const
std::unordered_set< irep_idt, irep_id_hash > id_sett
message_handlert * message_handler
std::vector< c_enum_membert > memberst
virtual bool typecheck_main()
const typet & return_type() const
bool simplify(exprt &expr, const namespacet &ns)