116 for(
const auto &
id :
id_set)
118 return static_cast<cpp_scopet &
>(id->get_parent());
150 base_name=std::string(
"#anon_")+std::to_string(++
anon_counter);
213 error() <<
"error: compound tag '" << base_name
214 <<
"' declared previously\n"
215 <<
"location of previous definition: " << symbol.
location
220 else if(symbol.
type.
id() != type.
id())
224 <<
" as different kind of tag" <<
eom;
238 symbol.module=
module;
255 error() <<
"cpp_typecheckt::typecheck_compound_type: "
256 <<
"symbol_table.move() failed" <<
eom;
268 id.class_identifier=new_symbol->
name;
335 error() <<
"void-typed member not permitted" <<
eom;
356 error() <<
"declarator in compound needs to be simple name"
361 bool is_method=!is_typedef && final_type.
id()==
ID_code;
364 bool is_virtual=
declaration.member_spec().is_virtual();
365 bool is_explicit=
declaration.member_spec().is_explicit();
366 bool is_inline=
declaration.member_spec().is_inline();
372 if(is_virtual && !is_method)
375 error() <<
"only methods can be virtual" <<
eom;
379 if(is_inline && !is_method)
382 error() <<
"only methods can be inlined" <<
eom;
386 if(is_virtual && is_static)
389 error() <<
"static methods cannot be virtual" <<
eom;
396 error() <<
"cast operators cannot be static" <<
eom;
403 error() <<
"constructors cannot be virtual" <<
eom;
410 error() <<
"only constructors can be explicit" <<
eom;
417 error() <<
"member function must return a value or void" <<
eom;
425 error() <<
"destructor with wrong name" <<
eom;
437 is_method || is_static)
448 identifier=base_name;
470 const typet &method_qualifier=
516 for(
const auto &
comp : components)
537 method_qualifier, value);
539 if(!value.
is_nil() && !is_static)
542 error() <<
"no initialization allowed here" <<
eom;
559 error() <<
"expected 0 to mark pure virtual method, got " <<
i <<
eom;
597 compo.set_base_name(
"@vtable_pointer");
601 components.push_back(
compo);
646 for(
auto &arg : args)
679 expr_call.arguments().reserve(args.size());
681 for(
const auto &arg : args)
684 lookup(arg.get_identifier()).symbol_expr());
722 if(is_static && !is_method)
759 ops.push_back(value);
809 if(base_name.
empty())
853 if(!
id.is_class() && !
id.is_enum())
856 error() <<
"'" << base_name <<
"' already in compound scope" <<
eom;
884 error() <<
"friend template not supported" <<
eom;
897 error() <<
"unexpected friend" <<
eom;
904 error() <<
"friend declaration must not have compound body" <<
eom;
920 std::cout <<
"friend declaration: " <<
declaration.pretty() <<
'\n';
926 std::cout <<
"decl: " <<
sub_it.pretty() <<
"\n with value "
927 <<
sub_it.value().pretty() <<
'\n';
931 if(
sub_it.value().is_not_nil())
965 error() <<
"union types must not have bases" <<
eom;
1021 bool is_static=
declaration.storage_spec().is_static();
1022 bool is_mutable=
declaration.storage_spec().is_mutable();
1029 error() <<
"invalid storage class specified for field" <<
eom;
1044 error() <<
"member declaration does not declare anything"
1072 access, is_static, is_typedef, is_mutable);
1075 else if(it->id()==
"cpp-public")
1077 else if(it->id()==
"cpp-private")
1079 else if(it->id()==
"cpp-protected")
1098 dtor,
dtor.declarators()[0], components,
1137 declarator.name().get_base_name();
1140 if(declarator.value().is_not_nil())
1148 {}, type.
components(), declarator.member_initializers());
1155 declarator.member_initializers());
1160 declarator.member_initializers());
1166 bool is_static=
declaration.storage_spec().is_static();
1167 bool is_mutable=
declaration.storage_spec().is_mutable();
1173 access, is_static, is_typedef, is_mutable);
1176 else if(it->id()==
"cpp-public")
1178 else if(it->id()==
"cpp-private")
1180 else if(it->id()==
"cpp-protected")
1201 cpctor.declarators()[0].value()=value;
1220 assignop.declarators().push_back(declarator);
1249 error() <<
"only constructors are allowed to "
1250 <<
"have member initializers" <<
eom;
1257 error() <<
"only constructors with body are allowed to "
1258 <<
"have member initializers" <<
eom;
1265 exprt::operandst::iterator
o_it=value.
operands().begin();
1279 const typet &method_qualifier,
1288 if(!method_qualifier.
id().
empty())
1291 error() <<
"method is static -- no qualifiers allowed" <<
eom;
1322 symbol.
name=identifier;
1326 symbol.module=
module;
1339 *new_symbol = std::move(symbol);
1344 error() <<
"failed to insert new method symbol: " << symbol.
name <<
'\n'
1345 <<
"name of previous symbol: " << new_symbol->
name <<
'\n'
1346 <<
"location of previous symbol: " << new_symbol->
location <<
eom;
1362 const typet &method_qualifier)
1385 parameters.insert(parameters.begin(),
parameter);
1406 error() <<
"anonymous struct/union member '"
1408 <<
"' shall not have function members" <<
eom;
1412 if(
comp.get_anonymous())
1425 error() <<
"'" << base_name <<
"' already in scope" <<
eom;
1431 id.identifier=
comp.get_name();
1450 error() <<
"storage class is not allowed here" <<
eom;
1457 error() <<
"anonymous struct/union member is not POD" <<
eom;
1462 irep_idt base_name=
"#anon_member"+std::to_string(components.size());
1468 typet compound_type;
1493 const exprt &
object,
1511 tmp.add_source_location()=source_location;
1513 if(
component.get_name()==component_name)
1528 error() <<
"error: member '" << component_name
1564 error() <<
"error: member '" << component_name
1565 <<
"' is not accessible" <<
eom;
1608 !(
pscope->is_root_scope());
1636 !(
pscope->is_root_scope());
1654 for(
const auto &
b : type.
bases())
1667 std::list<irep_idt> &
vbases)
const
1672 for(
const auto &
b : type.
bases())
1692 std::set<irep_idt> bases;
1696 return bases.find(to.
get(
ID_name))!=bases.end();
void base_type(typet &type, const namespacet &ns)
pointer_typet pointer_type(const typet &subtype)
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
virtual void do_initializer(exprt &initializer, const typet &type, bool force_constant)
symbol_tablet & symbol_table
virtual void make_constant_index(exprt &expr)
A codet representing sequential composition of program statements.
codet representation of an expression statement.
codet representation of a "return from a function" statement.
std::vector< parametert > parameterst
void set_inlined(bool value)
const parameterst & parameters() const
const typet & return_type() const
const irep_idt & get_statement() const
irept & member_initializers()
typet merge_type(const typet &declaration_type) const
bool is_template_scope() const
const source_locationt & source_location() const
cpp_idt & put_into_scope(const symbolt &symbol, cpp_scopet &scope, bool is_friend=false)
cpp_scopet & get_global_scope()
cpp_scopet & get_scope(const irep_idt &identifier)
cpp_scopet & set_scope(const irep_idt &identifier)
void go_to_global_scope()
cpp_scopet & current_scope()
cpp_scopet & get_parent() const
cpp_idt & insert(const irep_idt &_base_name)
id_sett lookup(const irep_idt &base_name_to_lookup, lookup_kindt kind)
bool contains(const irep_idt &base_name_to_lookup)
void default_assignop(const symbolt &symbol, cpp_declarationt &cpctor)
Generate declaration of the implicit default assignment operator.
void typecheck_compound_body(symbolt &symbol)
void do_virtual_table(const symbolt &symbol)
void put_compound_into_scope(const struct_union_typet::componentt &component)
void typecheck_type(typet &) override
void convert_anon_struct_union_member(const cpp_declarationt &declaration, const irep_idt &access, struct_typet::componentst &components)
void full_member_initialization(const struct_union_typet &struct_union_type, irept &initializers)
Build the full initialization list of the constructor.
static bool has_const(const typet &type)
dynamic_initializationst dynamic_initializations
void convert_template_declaration(cpp_declarationt &declaration)
void typecheck_compound_declarator(const symbolt &symbol, const cpp_declarationt &declaration, cpp_declaratort &declarator, struct_typet::componentst &components, const irep_idt &access, bool is_static, bool is_typedef, bool is_mutable)
void default_dtor(const symbolt &symb, cpp_declarationt &dtor)
Note:
bool check_component_access(const struct_union_typet::componentt &component, const struct_union_typet &struct_union_type)
void typecheck_member_function(const symbolt &compound_symbol, struct_typet::componentt &component, irept &initializers, const typet &method_qualifier, exprt &value)
bool cpp_is_pod(const typet &type) const
void check_fixed_size_array(typet &type)
check that an array has fixed size
void default_cpctor(const symbolt &, cpp_declarationt &cpctor) const
Generate code for implicit default copy constructor.
bool find_assignop(const symbolt &symbol) const
bool get_component(const source_locationt &source_location, const exprt &object, const irep_idt &component_name, exprt &member)
void typecheck_compound_type(struct_union_typet &) override
void add_anonymous_members_to_scope(const symbolt &struct_union_symbol)
codet dtor(const symbolt &symb, const symbol_exprt &this_expr)
produces destructor code for a class object
void get_virtual_bases(const struct_typet &type, std::list< irep_idt > &vbases) const
std::unordered_set< irep_idt > deferred_typechecking
void add_method_body(symbolt *_method_symbol)
void check_member_initializers(const struct_typet::basest &bases, const struct_typet::componentst &components, const irept &initializers)
Check a constructor initialization-list.
cpp_scopet & tag_scope(const irep_idt &_base_name, bool has_body, bool tag_only_declaration)
void typecheck_compound_bases(struct_typet &type)
optionalt< codet > cpp_constructor(const source_locationt &source_location, const exprt &object, const exprt::operandst &operands)
void elaborate_class_template(const typet &type)
elaborate class template instances
static bool has_auto(const typet &type)
static bool has_volatile(const typet &type)
irep_idt function_identifier(const typet &type)
for function overloading
void typecheck_friend_declaration(symbolt &symbol, cpp_declarationt &cpp_declaration)
void add_this_to_method_type(const symbolt &compound_symbol, code_typet &method_type, const typet &method_qualifier)
bool subtype_typecast(const struct_typet &from, const struct_typet &to) const
void convert_parameter(const irep_idt ¤t_mode, code_typet::parametert ¶meter)
bool find_cpctor(const symbolt &symbol) const
void move_member_initializers(irept &initializers, const code_typet &type, exprt &value)
bool disable_access_control
void make_ptr_typecast(exprt &expr, const typet &dest_type)
void default_ctor(const source_locationt &source_location, const irep_idt &base_name, cpp_declarationt &ctor) const
Generate code for implicit default constructors.
void get_bases(const struct_typet &type, std::set< irep_idt > &set_bases) const
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
const char * c_str() const
Base class for all expressions.
std::vector< exprt > operandst
bool has_operands() const
Return true if there is at least one operand.
void copy_to_operands(const exprt &expr)
Copy the given argument to the end of exprt's operands.
typet & type()
Return the type of the expression.
const source_locationt & source_location() const
source_locationt & add_source_location()
void add_to_operands(const exprt &expr)
Add the given argument to the end of exprt's operands.
There are a large number of kinds of tree structured or tree-like data in CPROVER.
bool get_bool(const irep_idt &name) const
const irept & find(const irep_idt &name) const
const irep_idt & get(const irep_idt &name) const
void remove(const irep_idt &name)
void set(const irep_idt &name, const irep_idt &value)
void move_to_sub(irept &irep)
const irep_idt & id() const
irept & add(const irep_idt &name)
const std::string & get_string(const irep_idt &name) const
Extract member of struct or union.
source_locationt source_location
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
A side_effect_exprt representation of a function call side effect.
A struct tag type, i.e., struct_typet with an identifier.
Structure type, corresponds to C style structs.
const basest & bases() const
Get the collection of base classes/structs.
const irep_idt & get_base_name() const
const irep_idt & get_name() const
Base type for structs and unions.
irep_idt default_access() const
Return the access specification for members where access has not been modified.
const componentst & components() const
bool is_incomplete() const
A struct/union may be incomplete.
std::vector< componentt > componentst
Expression to hold a symbol (variable)
static symbol_exprt typeless(const irep_idt &id)
Generate a symbol_exprt without a proper type.
const irep_idt & get_identifier() const
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
const symbolt * lookup(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
virtual bool move(symbolt &symbol, symbolt *&new_symbol) override
Move a symbol into the symbol table.
virtual std::pair< symbolt &, bool > insert(symbolt symbol) override
Author: Diffblue Ltd.
source_locationt location
Source code location of definition of symbol.
typet type
Type of symbol.
irep_idt name
The unique identifier.
irep_idt pretty_name
Language-specific display name.
irep_idt irep_idt base_name
Name of module the symbol belongs to.
exprt value
Initial value of symbol.
irep_idt mode
Language mode.
Semantic type conversion.
The type of an expression, extends irept.
const typet & subtype() const
const source_locationt & source_location() const
A union tag type, i.e., union_typet with an identifier.
cpp_declarationt & to_cpp_declaration(irept &irep)
C++ Language Type Checking.
cpp_namet & to_cpp_name(irept &cpp_name)
std::string cpp_type2name(const typet &type)
C++ Language Type Checking.
symbol_exprt cpp_symbol_expr(const symbolt &symbol)
#define Forall_operands(it, expr)
const std::string & id2string(const irep_idt &d)
static bool is_constructor(const irep_idt &method_name)
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
static optionalt< smt_termt > get_identifier(const exprt &expr, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_handle_identifiers, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_identifiers)
#define CHECK_RETURN(CONDITION)
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
#define PRECONDITION(CONDITION)
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
const codet & to_code(const exprt &expr)
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
static bool failed(bool error_indicator)
const type_with_subtypest & to_type_with_subtypes(const typet &type)