34 if(type.
id()==ID_const)
36 else if(type.
id()==ID_merged_type)
50 if(type.
id()==ID_volatile)
52 else if(type.
id()==ID_merged_type)
66 if(type.
id() == ID_auto)
69 type.
id() == ID_merged_type || type.
id() == ID_frontend_pointer ||
70 type.
id() == ID_pointer)
85 bool tag_only_declaration)
101 if(has_body || tag_only_declaration)
111 for(
const auto &
id : id_set)
113 return static_cast<cpp_scopet &>(id->get_parent());
128 type.
remove(ID_C_constant);
129 type.
remove(ID_C_volatile);
130 type.
remove(ID_C_restricted);
137 bool tag_only_declaration=type.
get_bool(ID_C_tag_only_declaration);
138 bool is_union = type.
id() == ID_union;
146 type.
set(ID_C_is_anonymous,
true);
160 if(type.
get_bool(ID_C_is_anonymous))
163 dest_scope=&
tag_scope(base_name, has_body, tag_only_declaration);
171 &cpp_typecheck_resolve.
resolve_scope(cpp_name, base_name, t_args);
188 const symbolt &symbol=*maybe_symbol;
206 error() <<
"error: compound tag `" << base_name
207 <<
"' declared previously\n" 208 <<
"location of previous definition: " 219 symbol.
name=symbol_name;
241 error() <<
"cpp_typecheckt::typecheck_compound_type: " 242 <<
"symbol_table.move() failed" <<
eom;
254 id.class_identifier=new_symbol->
name;
271 qualifiers.
write(tag_type);
278 qualifiers.
write(tag_type);
293 bool is_cast_operator=
294 declaration.
type().
id()==
"cpp-cast-operator";
299 declarator.
name().
get_sub().front().id()==ID_operator);
333 error() <<
"declarator in compound needs to be simple name" 338 bool is_method=!is_typedef && final_type.
id()==ID_code;
345 final_type.
set(ID_C_member_name, symbol.
name);
349 if(is_virtual && !is_method)
352 error() <<
"only methods can be virtual" <<
eom;
356 if(is_inline && !is_method)
359 error() <<
"only methods can be inlined" <<
eom;
363 if(is_virtual && is_static)
366 error() <<
"static methods cannot be virtual" <<
eom;
370 if(is_cast_operator && is_static)
373 error() <<
"cast operators cannot be static`" <<
eom;
380 error() <<
"constructors cannot be virtual" <<
eom;
387 error() <<
"only constructors can be explicit" <<
eom;
394 error() <<
"member function must return a value or void" <<
eom;
402 error() <<
"destructor with wrong name" <<
eom;
414 is_method || is_static)
425 identifier=base_name;
437 component.type().set(ID_C_is_operator,
true);
441 component.set(ID_is_cast_operator,
true);
447 const typet &method_qualifier=
448 static_cast<const typet &
>(declarator.
add(ID_method_qualifier));
453 component.type().set(ID_C_is_static,
true);
468 value.
id() == ID_code &&
482 virtual_name+=
"$const";
485 virtual_name +=
"$volatile";
488 virtual_name=
"@dtor";
491 std::set<irep_idt> virtual_bases;
493 for(
const auto &comp : components)
495 if(comp.get_bool(ID_is_virtual))
497 if(comp.get(ID_virtual_name) == virtual_name)
513 method_qualifier, value);
515 if(!value.
is_nil() && !is_static)
518 error() <<
"no initialization allowed here" <<
eom;
524 component.type().set(ID_C_is_virtual,
true);
525 component.type().set(ID_C_virtual_name, virtual_name);
535 error() <<
"expected 0 to mark pure virtual method, got " << i <<
eom;
556 vt_symb_type.
name= vt_name;
559 vt_symb_type.
mode=ID_cpp;
575 compo.
set(ID_is_vtptr,
true);
576 compo.
set(ID_access, ID_public);
577 components.push_back(compo);
582 INVARIANT(vt.
id()==ID_struct,
"Virtual tables must be stored as struct");
585 component.set(ID_virtual_name, virtual_name);
586 component.set(ID_is_virtual, is_virtual);
590 id2string(vt_name) +
"::" + virtual_name,
594 vt_entry.
set(ID_access, ID_public);
596 virtual_table.components().push_back(vt_entry);
599 while(!virtual_bases.empty())
601 irep_idt virtual_base=*virtual_bases.begin();
609 func_symb.
mode=ID_cpp;
622 for(
auto &arg : args)
624 irep_idt param_base_name = arg.get_base_name();
626 if(param_base_name.
empty())
634 arg_symb.
mode=ID_cpp;
636 arg_symb.
type=arg.type();
638 arg.
set(ID_C_identifier, arg_symb.
name);
647 lookup(args[0].
get(ID_C_identifier)).symbol_expr(),
653 expr_call.arguments().reserve(args.size());
654 expr_call.arguments().push_back(late_cast);
656 for(
const auto &arg : args)
658 expr_call.arguments().push_back(
659 lookup(arg.get(ID_C_identifier)).symbol_expr());
684 components.push_back(new_compo);
695 virtual_bases.erase(virtual_bases.begin());
700 if(is_static && !is_method)
705 static_symbol.
name=identifier;
720 error() <<
"redeclaration of static member `" 746 ops.push_back(value);
766 if(type.
id()==ID_array)
785 if(base_name.
empty())
788 if(compound.
type().
id()==ID_code)
800 id.is_static_member=compound.
get_bool(ID_is_static);
823 for(
const auto &id_it : id_set)
829 if(!
id.is_class() && !
id.is_enum())
832 error() <<
"`" << base_name
833 <<
"' already in compound scope" <<
eom;
847 id.is_static_member=compound.
get_bool(ID_is_static);
864 error() <<
"friend template not supported" <<
eom;
875 if(ftype.
id()!=ID_struct && ftype.
id()!=ID_union)
878 error() <<
"unexpected friend" <<
eom;
885 error() <<
"friend declaration must not have compound body" <<
eom;
904 bool has_value = sub_it.value().is_not_nil();
945 assert(symbol.
type.
id()==ID_struct ||
946 symbol.
type.
id()==ID_union);
952 if(!type.find(ID_bases).get_sub().empty())
954 if(type.id()==ID_union)
957 error() <<
"union types must not have bases" <<
eom;
964 exprt &body=
static_cast<exprt &
>(type.add(ID_body));
970 irep_idt access = type.default_access();
972 bool found_ctor=
false;
973 bool found_dtor=
false;
979 if(it->id()==ID_cpp_declaration)
993 declaration.
set(ID_C_access, access);
1004 if(declaration.
type().
id()==ID_struct ||
1005 declaration.
type().
id()==ID_union ||
1006 declaration.
type().
id()==ID_c_enum)
1008 declaration.
type().
set(ID_C_tag_only_declaration,
true);
1021 error() <<
"invalid storage class specified for field" <<
eom;
1029 final_type.
get_bool(ID_C_is_anonymous))
1032 if(final_type.
id()!=ID_union &&
1033 final_type.
id()!=ID_struct)
1036 error() <<
"member declaration does not declare anything" 1042 declaration, access, components);
1063 declaration, declarator, components,
1064 access, is_static, is_typedef, is_mutable);
1067 else if(it->id()==
"cpp-public")
1069 else if(it->id()==
"cpp-private")
1071 else if(it->id()==
"cpp-protected")
1072 access=ID_protected;
1090 dtor,
dtor.declarators()[0], components,
1091 ID_public,
false,
false,
false);
1095 if(symbol.
type.
id()==ID_struct)
1101 exprt cpp_public(
"cpp-public");
1111 access = type.default_access();
1117 if(it->id()==ID_cpp_declaration)
1129 declarator.name().get_base_name();
1132 if(declarator.value().is_not_nil())
1134 if(declarator.find(ID_member_initializers).is_nil())
1135 declarator.set(ID_member_initializers, ID_member_initializers);
1137 if(type.id() == ID_union)
1140 {}, type.components(), declarator.member_initializers());
1147 declarator.member_initializers());
1152 declarator.member_initializers());
1164 declaration, declarator, components,
1165 access, is_static, is_typedef, is_mutable);
1168 else if(it->id()==
"cpp-public")
1170 else if(it->id()==
"cpp-private")
1172 else if(it->id()==
"cpp-protected")
1173 access=ID_protected;
1191 exprt value(ID_cpp_not_typechecked);
1192 value.copy_to_operands(cpctor.
declarators()[0].value());
1198 ID_public,
false,
false,
false);
1218 ID_public,
false,
false,
false);
1227 irept &initializers,
1232 if(!initializers.
get_sub().empty())
1236 initializers.
find(ID_C_source_location));
1241 error() <<
"only constructors are allowed to " 1242 <<
"have member initializers" <<
eom;
1249 error() <<
"only constructors with body are allowed to " 1250 <<
"have member initializers" <<
eom;
1256 exprt::operandst::iterator o_it=value.
operands().begin();
1259 o_it=value.
operands().insert(o_it, static_cast<const exprt &>(*it));
1266 const symbolt &compound_symbol,
1268 irept &initializers,
1269 const typet &method_qualifier,
1278 if(!method_qualifier.
id().
empty())
1281 error() <<
"method is static -- no qualifiers allowed" <<
eom;
1307 type.
set(ID_C_inlined,
true);
1309 symbol.
name=identifier;
1325 error() <<
"failed to insert new method symbol: " 1326 << symbol.
name <<
"\n" 1327 <<
"name of previous symbol: " 1328 << new_symbol->
name <<
"\n" 1329 <<
"location of previous symbol: " 1345 const symbolt &compound_symbol,
1347 const typet &method_qualifier)
1362 if(compound_symbol.
type.
id() == ID_union)
1368 subtype.
set(ID_C_constant,
true);
1371 subtype.
set(ID_C_volatile,
true);
1377 const symbolt &struct_union_symbol)
1389 for(
const auto &comp : struct_union_components)
1391 if(comp.type().id()==ID_code)
1394 error() <<
"anonymous struct/union member `" 1396 <<
"' shall not have function members" <<
eom;
1400 if(comp.get_anonymous())
1402 const symbolt &symbol=
lookup(comp.type().get(ID_identifier));
1408 const irep_idt &base_name=comp.get_base_name();
1413 error() <<
"`" << base_name <<
"' already in scope" <<
eom;
1419 id.identifier=comp.get_name();
1420 id.class_identifier=struct_union_symbol.
name;
1438 error() <<
"storage class is not allowed here" <<
eom;
1445 error() <<
"anonymous struct/union member is not POD" <<
eom;
1456 typet compound_type;
1458 if(struct_union_symbol.
type.
id() == ID_union)
1476 struct_union_symbol.
type.
set(ID_C_unnamed_object, base_name);
1481 const exprt &
object,
1487 assert(followed_type.
id()==ID_struct ||
1488 followed_type.
id()==ID_union);
1494 final_type.components();
1501 if(
component.get_name()==component_name)
1510 member.
set(ID_C_not_accessible,
true);
1516 error() <<
"error: member `" << component_name
1517 <<
"' is not accessible (" <<
component.get(ID_access) <<
")" 1523 if(
object.get_bool(ID_C_lvalue))
1524 member.
set(ID_C_lvalue,
true);
1527 object.type().get_bool(ID_C_constant) &&
1530 member.
type().
set(ID_C_constant,
true);
1543 if(component_type.
id()==ID_union ||
1544 component_type.
id()==ID_struct)
1547 if(
get_component(source_location, tmp, component_name, member))
1552 error() <<
"error: member `" << component_name
1553 <<
"' is not accessible" <<
eom;
1557 if(
object.get_bool(ID_C_lvalue))
1558 member.
set(ID_C_lvalue,
true);
1561 object.get_bool(ID_C_constant) &&
1564 member.
type().
set(ID_C_constant,
true);
1583 if(access == ID_noaccess)
1586 if(access==ID_public)
1589 assert(access==ID_private ||
1590 access==ID_protected);
1593 struct_union_type.
get(ID_name);
1596 !(pscope->is_root_scope());
1597 pscope = &(pscope->get_parent()))
1599 if(pscope->is_class())
1601 if(pscope->identifier==struct_identifier)
1620 const irept &friend_symb=*f_it;
1626 !(pscope->is_root_scope());
1627 pscope = &(pscope->get_parent()))
1629 if(friend_scope.
identifier==pscope->identifier)
1632 if(pscope->is_class())
1642 std::set<irep_idt> &set_bases)
const 1644 for(
const auto &b : type.
bases())
1646 DATA_INVARIANT(b.id() == ID_base,
"base class expression expected");
1650 set_bases.insert(base.get(ID_name));
1657 std::list<irep_idt> &vbases)
const 1659 if(std::find(vbases.begin(), vbases.end(), type.
get(ID_name))!=vbases.end())
1662 for(
const auto &b : type.
bases())
1664 DATA_INVARIANT(b.id() == ID_base,
"base class expression expected");
1668 if(b.get_bool(ID_virtual))
1669 vbases.push_back(base.get(ID_name));
1679 if(from.
get(ID_name)==to.
get(ID_name))
1682 std::set<irep_idt> bases;
1686 return bases.find(to.
get(ID_name))!=bases.end();
1691 const typet &dest_type)
1695 assert(src_type.
id()== ID_pointer);
1696 assert(dest_type.
id()== ID_pointer);
C++ Language Type Checking.
const irep_idt & get_statement() const
const irep_idt & get_name() const
The type of an expression, extends irept.
irep_idt name
The unique identifier.
void add_anonymous_members_to_scope(const symbolt &struct_union_symbol)
#define forall_subtypes(it, type)
bool find_cpctor(const symbolt &symbol) const
void check_fixed_size_array(typet &type)
check that an array has fixed size
Semantic type conversion.
static bool is_constructor(const irep_idt &method_name)
codet dtor(const symbolt &symb)
produces destructor code for a class object
const std::string & id2string(const irep_idt &d)
pointer_typet pointer_type(const typet &subtype)
const cpp_storage_spect & storage_spec() const
static bool has_const(const typet &type)
static bool has_auto(const typet &type)
bool is_destructor() const
optionalt< codet > cpp_constructor(const source_locationt &source_location, const exprt &object, const exprt::operandst &operands)
std::vector< irept > subt
irep_idt mode
Language mode.
void move_to_sub(irept &irep)
void name_anon_struct_union()
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
void get_bases(const struct_typet &type, std::set< irep_idt > &set_bases) const
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
void set_base_name(const irep_idt &base_name)
void set_name(const irep_idt &name)
void full_member_initialization(const struct_union_typet &struct_union_type, irept &initializers)
Build the full initialization list of the constructor.
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
id_sett lookup(const irep_idt &base_name_to_lookup, lookup_kindt kind)
bool check_component_access(const struct_union_typet::componentt &component, const struct_union_typet &struct_union_type)
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
cpp_namet & to_cpp_name(irept &cpp_name)
std::vector< componentt > componentst
void move_to_operands(exprt &expr)
Move the given argument to the end of exprt's operands.
cpp_scopet & get_parent() const
std::vector< parametert > parameterst
void already_typechecked(irept &irep)
exprt value
Initial value of symbol.
A union tag type, i.e., union_typet with an identifier.
const componentst & components() const
cpp_idt & put_into_scope(const symbolt &symbol, cpp_scopet &scope, bool is_friend=false)
A struct tag type, i.e., struct_typet with an identifier.
irep_idt module
Name of module the symbol belongs to.
irep_idt pretty_name
Language-specific display name.
void default_dtor(const symbolt &symb, cpp_declarationt &dtor)
Note:
typet & type()
Return the type of the expression.
cpp_scopet & get_global_scope()
bool is_simple_name() const
typet merge_type(const typet &declaration_type) const
#define CHECK_RETURN(CONDITION)
Structure type, corresponds to C style structs.
bool get_bool(const irep_namet &name) const
codet representation of an expression statement.
const cpp_member_spect & member_spec() const
void set_inline(bool value)
void set_base_name(const irep_idt &name)
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)
Extract member of struct or union.
symbol_tablet & symbol_table
virtual symbolt * get_writeable(const irep_idt &name) override
Find a symbol in the symbol table for read-write access.
const irep_idt & get_base_name() const
void add_method_body(symbolt *_method_symbol)
const irep_idt & id() const
const source_locationt & source_location() const
bool contains(const irep_idt &base_name_to_lookup)
void elaborate_class_template(const typet &type)
elaborate class template instances
class code_blockt & make_block()
If this codet is a code_blockt (i.e. it represents a block of statements), return the unmodified inpu...
const declaratorst & declarators() const
void add_this_to_method_type(const symbolt &compound_symbol, code_typet &method_type, const typet &method_qualifier)
source_locationt & location()
const basest & bases() const
Get the collection of base classes/structs.
virtual bool move(symbolt &symbol, symbolt *&new_symbol) override
Move a symbol into the symbol table.
void check_member_initializers(const struct_typet::basest &bases, const struct_typet::componentst &components, const irept &initializers)
Check a constructor initialization-list.
source_locationt source_location
bool cpp_is_pod(const typet &type) const
void typecheck_type(typet &) override
void typecheck_friend_declaration(symbolt &symbol, cpp_declarationt &cpp_declaration)
const irep_idt & get(const irep_namet &name) const
void go_to_global_scope()
void do_virtual_table(const symbolt &symbol)
std::string cpp_type2name(const typet &type)
const exprt & size() const
Base class for tree-like data structures with sharing.
void convert_template_declaration(cpp_declarationt &declaration)
C++ Language Type Checking.
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
symbol_exprt cpp_symbol_expr(const symbolt &symbol)
dstringt has one field, an unsigned integer no which is an index into a static table of strings...
bool is_constructor() const
void default_assignop(const symbolt &symbol, cpp_declarationt &cpctor)
Generate declaration of the implicit default assignment operator.
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
bool has_operands() const
Return true if there is at least one operand.
void default_cpctor(const symbolt &, cpp_declarationt &cpctor) const
Generate code for implicit default copy constructor.
void make_ptr_typecast(exprt &expr, const typet &dest_type)
std::vector< exprt > operandst
const source_locationt & source_location() const
irep_idt get_base_name() const
cpp_scopet & set_scope(const irep_idt &identifier)
A side_effect_exprt representation of a function call side effect.
bool get_component(const source_locationt &source_location, const exprt &object, const irep_idt &component_name, exprt &member)
irep_idt function_identifier(const typet &type)
for function overloading
typet type
Type of symbol.
source_locationt location
Source code location of definition of symbol.
cpp_declarationt & to_cpp_declaration(irept &irep)
void set_identifier(const irep_idt &identifier)
bool subtype_typecast(const struct_typet &from, const struct_typet &to) const
void typecheck_compound_type(struct_union_typet &) override
void typecheck_compound_bases(struct_typet &type)
Base type for structs and unions.
void default_ctor(const source_locationt &source_location, const irep_idt &base_name, cpp_declarationt &ctor) const
Generate code for implicit default constructors.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
bool find_assignop(const symbolt &symbol) const
Base class for all expressions.
void get_virtual_bases(const struct_typet &type, std::list< irep_idt > &vbases) const
const parameterst & parameters() const
irep_idt base_name
Base (non-scoped) name.
cpp_scopet & current_scope()
irept & member_initializers()
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
void set_pretty_name(const irep_idt &name)
symbolt & convert(const typet &type, const cpp_storage_spect &storage_spec, const cpp_member_spect &member_spec, cpp_declaratort &declarator)
const source_locationt & source_location() const
virtual void make_constant_index(exprt &expr)
irept & add(const irep_namet &name)
const std::string & get_string(const irep_namet &name) const
void set_identifier(const irep_idt &identifier)
dynamic_initializationst dynamic_initializations
const std::string & id_string() const
bool disable_access_control
virtual void write(typet &src) const override
#define Forall_operands(it, expr)
source_locationt & add_source_location()
const codet & to_code(const exprt &expr)
void typecheck_compound_body(symbolt &symbol)
void move_member_initializers(irept &initializers, const code_typet &type, exprt &value)
Expression to hold a symbol (variable)
cpp_scopet & get_scope(const irep_idt &identifier)
const char * c_str() const
virtual void do_initializer(exprt &initializer, const typet &type, bool force_constant)
void put_compound_into_scope(const struct_union_typet::componentt &component)
codet representation of a "return from a function" statement.
void typecheck_member_function(const symbolt &compound_symbol, struct_typet::componentt &component, irept &initializers, const typet &method_qualifier, exprt &value)
void remove(const irep_namet &name)
const typet & subtype() const
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions, goto_programs, exprts, etc.
const symbolt * lookup(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
static bool has_volatile(const typet &type)
void convert_anon_struct_union_member(const cpp_declarationt &declaration, const irep_idt &access, struct_typet::componentst &components)
cpp_idt & insert(const irep_idt &_base_name)
void make_typecast(const typet &_type)
Create a typecast_exprt to the given type.
const irept & find(const irep_namet &name) const
cpp_scopet & tag_scope(const irep_idt &_base_name, bool has_body, bool tag_only_declaration)
const typet & return_type() const
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
bool is_template_scope() const
void set(const irep_namet &name, const irep_idt &value)
virtual std::pair< symbolt &, bool > insert(symbolt symbol) override
Author: Diffblue Ltd.
bool simplify(exprt &expr, const namespacet &ns)
cpp_scopet & resolve_scope(const cpp_namet &cpp_name, irep_idt &base_name, cpp_template_args_non_tct &template_args)
#define forall_irep(it, irep)