25 return expr2c(expr, *
this);
30 return type2c(type, *
this);
41 error() <<
"failed to move symbol `" << symbol.
name 42 <<
"' into symbol table" <<
eom;
49 bool is_function=symbol.
type.
id()==ID_code;
77 warning() <<
"`extern' symbol should not have an initializer" <<
eom;
80 else if(!is_function && symbol.
value.
id()==ID_code)
83 error() <<
"only functions can have a function body" <<
eom;
89 (final_type.
id()==ID_struct ||
90 final_type.
id()==ID_incomplete_struct))
95 (final_type.
id()==ID_union ||
96 final_type.
id()==ID_incomplete_union))
101 (final_type.
id()==ID_c_enum ||
102 final_type.
id()==ID_incomplete_c_enum))
112 symbol_tablet::symbolst::const_iterator old_it=
125 if(old_it->second.is_type!=symbol.
is_type)
129 <<
"' as a different kind of symbol" <<
eom;
148 if(symbol.
type.
id()==ID_code)
157 for(code_typet::parameterst::iterator
179 if(final_old.
id()==ID_incomplete_struct ||
180 final_old.
id()==ID_incomplete_union ||
181 final_old.
id()==ID_incomplete_c_enum)
197 error() <<
"conflicting definition of type symbol `" 206 if(final_new.
id()==ID_incomplete_struct ||
207 final_new.
id()==ID_incomplete_union ||
208 final_new.
id()==ID_incomplete_c_enum)
218 error() <<
"conflicting definition of tag symbol `" 225 final_new.
id()==ID_c_enum && final_old.
id()==ID_c_enum)
231 final_new.
id()==ID_pointer && final_old.
id()==ID_pointer &&
244 error() <<
"type symbol `" 261 if(final_old.
id()==ID_array &&
263 initial_new.
id()==ID_array &&
270 else if(final_old.
id()==ID_array &&
272 initial_new.
id()==ID_array &&
289 if(old_symbol.
type.
id()==ID_KnR)
292 if(final_new.
id()==ID_code)
295 error() <<
"function type not allowed for K&R function parameter" 305 if(final_new.
id()==ID_code)
311 if(final_old.
id()!=ID_code)
314 error() <<
"error: function symbol `" 316 <<
"' redefined with a different type:\n" 332 old_symbol.
type.
set(ID_C_inlined,
true);
333 new_symbol.
type.
set(ID_C_inlined,
true);
358 for(code_typet::parameterst::const_iterator
363 const irep_idt &identifier=p_it->get_identifier();
365 symbol_tablet::symbolst::const_iterator p_s_it=
375 <<
"' defined twice" <<
eom;
409 if(final_old!=final_new)
411 if(final_old.
id()==ID_array &&
413 final_new.
id()==ID_array &&
421 else if((final_old.
id()==ID_incomplete_c_enum ||
422 final_old.
id()==ID_c_enum) &&
423 (final_new.
id()==ID_incomplete_c_enum ||
424 final_new.
id()==ID_c_enum))
428 else if(final_old.
id()==ID_pointer &&
431 final_new.
id()==ID_pointer &&
439 else if(final_old.
id()==ID_pointer &&
441 final_new.
id()==ID_pointer &&
453 <<
"' redefined with a different type:\n" 481 (final_new.
id()==ID_incomplete_c_enum ||
482 final_new.
id()==ID_c_enum) &&
493 <<
"' already has an initial value" <<
eom;
532 unsigned anon_counter=0;
536 for(code_typet::parameterst::iterator
537 p_it=parameters.begin();
538 p_it!=parameters.end();
542 if(p_it->get_base_name().empty())
545 p_it->set_base_name(base_name);
549 irep_idt base_name=p_it->get_base_name();
552 p_it->set_identifier(identifier);
556 p_symbol.
type=p_it->type();
557 p_symbol.
name=identifier;
559 p_symbol.
location=p_it->source_location();
569 if(symbol.
name==ID_main)
573 for(std::map<irep_idt, source_locationt>::const_iterator
579 error() <<
"branching label `" << it->first
580 <<
"' is not defined in function" <<
eom;
595 if(!asm_label.
empty() &&
599 symbol.
name=asm_label;
603 if(symbol.
name!=orig_name)
606 std::make_pair(orig_name, asm_label)).second)
611 error() <<
"error: replacing asm renaming " 618 else if(asm_label.
empty())
620 asm_label_mapt::const_iterator entry=
624 symbol.
name=entry->second;
629 if(symbol.
name!=orig_name &&
630 symbol.
type.
id()==ID_code &&
635 for(code_typet::parameterst::const_iterator
640 const irep_idt &p_bn=p_it->get_base_name();
648 std::make_pair(p_id, p_new_id)).second)
659 assert(declaration.
operands().size()==2);
678 static_cast<const exprt&>(declaration.
find(ID_C_spec_requires));
679 contract.
add(ID_C_spec_requires).
swap(spec_requires);
682 static_cast<const exprt&>(declaration.
find(ID_C_spec_ensures));
683 contract.
add(ID_C_spec_ensures).
swap(spec_ensures);
687 for(ansi_c_declarationt::declaratorst::iterator
693 full_spec|=c_storage_spec;
711 if(!full_spec.alias.empty())
716 error() <<
"alias attribute cannot be used with a body" 724 const auto &renaming_entry =
asm_label_map.find(full_spec.alias);
732 if(full_spec.section.empty())
737 std::string asm_name =
id2string(full_spec.section);
739 if(asm_name[0] ==
'.')
743 if(primary_section != std::string::npos)
744 asm_name.resize(primary_section);
749 if(!full_spec.asm_label.empty())
750 asm_name+=
id2string(full_spec.asm_label);
758 d_it->set_name(identifier);
770 if(new_symbol.
type.
id()==ID_code)
773 if(ret_type.
id()!=ID_empty)
778 if(contract.find(ID_C_spec_requires).is_not_nil())
779 new_symbol.
type.
add(ID_C_spec_requires)=
780 contract.
find(ID_C_spec_requires);
781 if(contract.find(ID_C_spec_ensures).is_not_nil())
782 new_symbol.
type.
add(ID_C_spec_ensures)=
783 contract.
find(ID_C_spec_ensures);
void typecheck_redefinition_type(symbolt &old_symbol, symbolt &new_symbol)
bool get_is_static_assert() const
The type of an expression, extends irept.
irep_idt name
The unique identifier.
std::map< irep_idt, source_locationt > labels_used
struct configt::ansi_ct ansi_c
virtual void typecheck_spec_expr(codet &code, const irep_idt &spec)
void typecheck_declaration(ansi_c_declarationt &)
const std::string & id2string(const irep_idt &d)
asm_label_mapt asm_label_map
Symbol table entry of function parameterThis is a symbol generated as part of type checking.
void set_is_used(bool is_used)
std::string type2c(const typet &type, const namespacet &ns, const expr2c_configurationt &configuration)
irep_idt mode
Language mode.
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
void move_symbol(symbolt &symbol, symbolt *&new_symbol)
bool has_ellipsis() const
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
std::vector< parametert > parameterst
exprt value
Initial value of symbol.
id_type_mapt parameter_map
void to_symbol(const ansi_c_declaratort &, symbolt &symbol) const
irep_idt module
Name of module the symbol belongs to.
irep_idt pretty_name
Language-specific display name.
typet & type()
Return the type of the expression.
unsignedbv_typet size_type()
bool get_bool(const irep_namet &name) const
virtual std::string to_string(const exprt &expr)
typet full_type(const ansi_c_declaratort &) const
symbol_tablet & symbol_table
mstreamt & warning() const
void set_is_weak(bool is_weak)
virtual symbolt * get_writeable(const irep_idt &name) override
Find a symbol in the symbol table for read-write access.
const irep_idt & id() const
void set_is_thread_local(bool is_thread_local)
const declaratorst & declarators() const
void typecheck_new_symbol(symbolt &symbol)
void apply_asm_label(const irep_idt &asm_label, symbolt &symbol)
ANSI-C Language Type Checking.
virtual bool move(symbolt &symbol, symbolt *&new_symbol) override
Move a symbol into the symbol table.
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
void make_already_typechecked(typet &dest)
source_locationt source_location
const irep_idt & get(const irep_namet &name) const
#define PRECONDITION(CONDITION)
const exprt & size() const
virtual void typecheck_expr(exprt &expr)
void set_is_register(bool is_register)
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
virtual void erase(const symbolst::const_iterator &entry) override
Remove a symbol from the symbol table.
void typecheck_redefinition_non_type(symbolt &old_symbol, symbolt &new_symbol)
bool is_constant() const
Return whether the expression is a constant.
virtual void adjust_function_parameter(typet &type) const
const irep_idt & display_name() const
Return language specific display name if present.
void set_is_static(bool is_static)
typet type
Type of symbol.
source_locationt location
Source code location of definition of symbol.
void set_is_extern(bool is_extern)
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Base class for all expressions.
void add_argc_argv(const symbolt &main_symbol)
const parameterst & parameters() const
irep_idt base_name
Base (non-scoped) name.
std::string expr2c(const exprt &expr, const namespacet &ns, const expr2c_configurationt &configuration)
irept & add(const irep_namet &name)
std::map< irep_idt, source_locationt > labels_defined
void typecheck_symbol(symbolt &symbol)
const std::string & id_string() const
const codet & to_code(const exprt &expr)
void set_is_typedef(bool is_typedef)
void typecheck_function_body(symbolt &symbol)
Expression to hold a symbol (variable)
virtual void typecheck_type(typet &type)
virtual void do_initializer(exprt &initializer, const typet &type, bool force_constant)
Data structure for representing an arbitrary statement in a program.
void set_is_inline(bool is_inline)
const typet & subtype() const
const irept & find(const irep_namet &name) const
const typet & return_type() const
void set(const irep_namet &name, const irep_idt &value)
virtual void typecheck_code(codet &code)