34 if(type.
id()==ID_const)
36 else if(type.
id()==ID_merged_type)
52 if(type.
id()==ID_volatile)
54 else if(type.
id()==ID_merged_type)
70 if(type.
id() == ID_auto)
73 type.
id() == ID_merged_type || type.
id() == ID_frontend_pointer ||
74 type.
id() == ID_pointer)
91 bool tag_only_declaration)
107 if(has_body || tag_only_declaration)
117 for(
const auto &
id : id_set)
119 return static_cast<cpp_scopet &
>(
id->get_parent());
134 type.
remove(ID_C_constant);
135 type.
remove(ID_C_volatile);
136 type.
remove(ID_C_restricted);
143 bool tag_only_declaration=type.
get_bool(ID_C_tag_only_declaration);
144 bool is_union = type.
id() == ID_union;
152 type.
set(ID_C_is_anonymous,
true);
166 if(type.
get_bool(ID_C_is_anonymous))
169 dest_scope=&
tag_scope(base_name, has_body, tag_only_declaration);
177 &cpp_typecheck_resolve.
resolve_scope(cpp_name, base_name, t_args);
194 const symbolt &symbol=*maybe_symbol;
214 error() <<
"compound tag '" << base_name <<
"' 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;
232 symbol.base_name=base_name;
248 error() <<
"cpp_typecheckt::typecheck_compound_type: "
249 <<
"symbol_table.move() failed" <<
eom;
261 id.class_identifier=new_symbol->
name;
280 qualifiers.
write(tag_type);
287 qualifiers.
write(tag_type);
302 bool is_cast_operator=
303 declaration.
type().
id()==
"cpp-cast-operator";
309 declarator.
name().
get_sub().front().id() == ID_operator);
326 if(final_type.
id() == ID_empty)
329 error() <<
"void-typed member not permitted" <<
eom;
350 error() <<
"declarator in compound needs to be simple name"
355 bool is_method=!is_typedef && final_type.
id()==ID_code;
362 final_type.
set(ID_C_member_name, symbol.
name);
366 if(is_virtual && !is_method)
369 error() <<
"only methods can be virtual" <<
eom;
373 if(is_inline && !is_method)
376 error() <<
"only methods can be inlined" <<
eom;
380 if(is_virtual && is_static)
383 error() <<
"static methods cannot be virtual" <<
eom;
387 if(is_cast_operator && is_static)
390 error() <<
"cast operators cannot be static" <<
eom;
397 error() <<
"constructors cannot be virtual" <<
eom;
404 error() <<
"only constructors can be explicit" <<
eom;
411 error() <<
"member function must return a value or void" <<
eom;
419 error() <<
"destructor with wrong name" <<
eom;
431 is_method || is_static)
442 identifier=base_name;
454 component.type().set(ID_C_is_operator,
true);
458 component.set(ID_is_cast_operator,
true);
464 const typet &method_qualifier=
465 static_cast<const typet &
>(declarator.
add(ID_method_qualifier));
470 component.type().set(ID_C_is_static,
true);
485 value.
id() == ID_code &&
499 virtual_name+=
"$const";
502 virtual_name +=
"$volatile";
505 virtual_name=
"@dtor";
508 std::set<irep_idt> virtual_bases;
510 for(
const auto &comp : components)
512 if(comp.get_bool(ID_is_virtual))
514 if(comp.get(ID_virtual_name) == virtual_name)
519 !code_type.
parameters().empty(),
"must have parameters");
523 virtual_bases.insert(
533 method_qualifier, value);
535 if(!value.
is_nil() && !is_static)
538 error() <<
"no initialization allowed here" <<
eom;
544 component.type().set(ID_C_is_virtual,
true);
545 component.type().set(ID_C_virtual_name, virtual_name);
555 error() <<
"expected 0 to mark pure virtual method, got " << i <<
eom;
577 vt_symb_type.pretty_name=vt_symb_type.base_name;
578 vt_symb_type.module=
module;
579 vt_symb_type.location=symbol.
location;
580 vt_symb_type.type.
set(ID_name, vt_symb_type.name);
591 compo.
set(ID_is_vtptr,
true);
592 compo.
set(ID_access, ID_public);
593 components.push_back(compo);
598 INVARIANT(vt.
id()==ID_struct,
"Virtual tables must be stored as struct");
601 component.set(ID_virtual_name, virtual_name);
602 component.set(ID_is_virtual, is_virtual);
606 id2string(vt_name) +
"::" + virtual_name,
610 vt_entry.
set(ID_access, ID_public);
612 virtual_table.
components().push_back(vt_entry);
615 while(!virtual_bases.empty())
624 func_symb.base_name =
component.get_base_name();
625 func_symb.pretty_name =
component.get_base_name();
627 func_symb.location=
component.source_location();
634 .
set(ID_identifier, virtual_base);
639 for(
auto &arg : args)
641 irep_idt param_base_name = arg.get_base_name();
643 if(param_base_name.
empty())
650 arg_symb.base_name = param_base_name;
651 arg_symb.pretty_name = param_base_name;
652 arg_symb.location=func_symb.location;
654 arg.set_identifier(arg_symb.name);
663 lookup(args[0].get_identifier()).symbol_expr(),
671 expr_call.
arguments().reserve(args.size());
673 for(
const auto &arg : args)
696 new_compo.
type()=func_symb.type;
698 components.push_back(new_compo);
709 virtual_bases.erase(virtual_bases.begin());
714 if(is_static && !is_method)
718 static_symbol.base_name =
component.get_base_name();
719 static_symbol.is_lvalue=
true;
720 static_symbol.is_static_lifetime=
true;
722 static_symbol.is_extern=
true;
731 error() <<
"redeclaration of static member '" << static_symbol.base_name
748 ops.push_back(value);
768 if(type.
id()==ID_array)
774 if(array_type.
size().
id() == ID_symbol)
798 if(base_name.
empty())
801 if(compound.
type().
id()==ID_code)
813 id.is_static_member=compound.
get_bool(ID_is_static);
836 for(
const auto &id_it : id_set)
842 if(!
id.is_class() && !
id.is_enum())
845 error() <<
"'" << base_name <<
"' already in compound scope" <<
eom;
859 id.is_static_member=compound.
get_bool(ID_is_static);
873 error() <<
"friend template not supported" <<
eom;
883 if(ftype.
id()!=ID_struct && ftype.
id()!=ID_union)
886 error() <<
"unexpected friend" <<
eom;
893 error() <<
"friend declaration must not have compound body" <<
eom;
909 std::cout <<
"friend declaration: " << declaration.
pretty() <<
'\n';
915 std::cout <<
"decl: " << sub_it.pretty() <<
"\n with value "
916 << sub_it.value().pretty() <<
'\n';
920 if(sub_it.value().is_not_nil())
924 cpp_declarator_converter.
is_friend =
true;
950 if(type.
id()==ID_union)
953 error() <<
"union types must not have bases" <<
eom;
968 bool found_ctor=
false;
969 bool found_dtor=
false;
975 if(it->id()==ID_cpp_declaration)
989 declaration.
set(ID_C_access, access);
1000 if(declaration.
type().
id()==ID_struct ||
1001 declaration.
type().
id()==ID_union ||
1002 declaration.
type().
id()==ID_c_enum)
1004 declaration.
type().
set(ID_C_tag_only_declaration,
true);
1017 error() <<
"invalid storage class specified for field" <<
eom;
1024 ((declaration.
type().
id() == ID_struct_tag &&
1027 (declaration.
type().
id() == ID_union_tag &&
1034 declaration.
type().
id() != ID_union_tag &&
1035 declaration.
type().
id() != ID_struct_tag)
1038 error() <<
"member declaration does not declare anything"
1044 declaration, access, components);
1065 declaration, declarator, components,
1066 access, is_static, is_typedef, is_mutable);
1069 else if(it->id()==
"cpp-public")
1071 else if(it->id()==
"cpp-private")
1073 else if(it->id()==
"cpp-protected")
1074 access=ID_protected;
1092 dtor,
dtor.declarators()[0], components,
1093 ID_public,
false,
false,
false);
1097 if(symbol.
type.
id()==ID_struct)
1103 exprt cpp_public(
"cpp-public");
1119 if(it->id()==ID_cpp_declaration)
1131 declarator.name().get_base_name();
1134 if(declarator.value().is_not_nil())
1136 if(declarator.find(ID_member_initializers).is_nil())
1137 declarator.set(ID_member_initializers, ID_member_initializers);
1139 if(type.
id() == ID_union)
1142 {}, type.
components(), declarator.member_initializers());
1149 declarator.member_initializers());
1154 declarator.member_initializers());
1166 declaration, declarator, components,
1167 access, is_static, is_typedef, is_mutable);
1170 else if(it->id()==
"cpp-public")
1172 else if(it->id()==
"cpp-private")
1174 else if(it->id()==
"cpp-protected")
1175 access=ID_protected;
1193 exprt value(ID_cpp_not_typechecked);
1200 ID_public,
false,
false,
false);
1220 ID_public,
false,
false,
false);
1229 irept &initializers,
1234 if(!initializers.
get_sub().empty())
1238 initializers.
find(ID_C_source_location));
1243 error() <<
"only constructors are allowed to "
1244 <<
"have member initializers" <<
eom;
1251 error() <<
"only constructors with body are allowed to "
1252 <<
"have member initializers" <<
eom;
1256 if(
to_code(value).get_statement() != ID_block)
1259 exprt::operandst::iterator o_it=value.
operands().begin();
1260 for(
const auto &initializer : initializers.
get_sub())
1263 value.
operands().insert(o_it,
static_cast<const exprt &
>(initializer));
1270 const symbolt &compound_symbol,
1272 irept &initializers,
1273 const typet &method_qualifier,
1280 if(!method_qualifier.
id().
empty())
1283 error() <<
"method is static -- no qualifiers allowed" <<
eom;
1314 symbolt symbol{identifier, type, compound_symbol.
mode};
1315 symbol.base_name=
component.get_base_name();
1316 symbol.value.swap(value);
1318 symbol.location=
component.source_location();
1327 *new_symbol = std::move(symbol);
1332 error() <<
"failed to insert new method symbol: " << symbol.name <<
'\n'
1333 <<
"name of previous symbol: " << new_symbol->
name <<
'\n'
1334 <<
"location of previous symbol: " << new_symbol->
location <<
eom;
1348 const symbolt &compound_symbol,
1350 const typet &method_qualifier)
1354 if(compound_symbol.
type.
id() == ID_union)
1360 subtype.
set(ID_C_constant,
true);
1363 subtype.
set(ID_C_volatile,
true);
1373 parameters.insert(parameters.begin(), parameter);
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;
1432 declaration.
type().
id() == ID_struct_tag
1437 symbolt &struct_union_symbol =
1444 error() <<
"storage class is not allowed here" <<
eom;
1451 error() <<
"anonymous struct/union member is not POD" <<
eom;
1462 typet compound_type;
1464 if(struct_union_symbol.type.id() == ID_union)
1482 struct_union_symbol.type.set(ID_C_unnamed_object, base_name);
1487 const exprt &
object,
1492 object.type().
id() == ID_struct_tag ||
object.type().
id() == ID_union_tag);
1495 object.type().
id() == ID_struct_tag
1509 if(
component.get_name()==component_name)
1518 member.
set(ID_C_not_accessible,
true);
1524 error() <<
"member '" << component_name <<
"' is not accessible ("
1530 if(
object.get_bool(ID_C_lvalue))
1531 member.
set(ID_C_lvalue,
true);
1534 object.type().get_bool(ID_C_constant) &&
1537 member.
type().
set(ID_C_constant,
true);
1545 (
component.type().id() == ID_struct_tag &&
1547 .
find(ID_C_unnamed_object)
1549 (
component.type().id() == ID_union_tag &&
1551 .
find(ID_C_unnamed_object)
1553 component.type().find(ID_C_unnamed_object).is_not_nil())
1558 component.type().id() == ID_union_tag ||
1562 if(
get_component(source_location, tmp, component_name, member))
1567 error() <<
"member '" << component_name <<
"' is not accessible"
1572 if(
object.get_bool(ID_C_lvalue))
1573 member.
set(ID_C_lvalue,
true);
1576 object.get_bool(ID_C_constant) &&
1579 member.
type().
set(ID_C_constant,
true);
1598 if(access == ID_noaccess)
1601 if(access==ID_public)
1604 PRECONDITION(access == ID_private || access == ID_protected);
1607 struct_union_type.
get(ID_name);
1610 !(pscope->is_root_scope());
1611 pscope = &(pscope->get_parent()))
1613 if(pscope->is_class())
1615 if(pscope->identifier==struct_identifier)
1632 for(
const auto &friend_symb : friends)
1638 !(pscope->is_root_scope());
1639 pscope = &(pscope->get_parent()))
1641 if(friend_scope.
identifier==pscope->identifier)
1644 if(pscope->is_class())
1654 std::set<irep_idt> &set_bases)
const
1656 for(
const auto &b : type.
bases())
1658 DATA_INVARIANT(b.id() == ID_base,
"base class expression expected");
1662 set_bases.insert(base.
get(ID_name));
1669 std::list<irep_idt> &vbases)
const
1671 if(std::find(vbases.begin(), vbases.end(), type.
get(ID_name))!=vbases.end())
1674 for(
const auto &b : type.
bases())
1676 DATA_INVARIANT(b.id() == ID_base,
"base class expression expected");
1680 if(b.get_bool(ID_virtual))
1681 vbases.push_back(base.
get(ID_name));
1691 if(from.
get(ID_name)==to.
get(ID_name))
1694 std::set<irep_idt> bases;
1698 return bases.find(to.
get(ID_name))!=bases.end();
pointer_typet pointer_type(const typet &subtype)
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
const typet & element_type() const
The type of the elements of the array.
const exprt & size() const
virtual void write(typet &src) const
symbol_table_baset & symbol_table
virtual void do_initializer(exprt &initializer, const typet &type, bool force_constant)
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.
void set_base_name(const irep_idt &name)
void set_identifier(const irep_idt &identifier)
std::vector< parametert > parameterst
const typet & return_type() const
void set_inlined(bool value)
const parameterst & parameters() const
const irep_idt & get_statement() const
bool is_destructor() const
const declaratorst & declarators() const
const cpp_storage_spect & storage_spec() const
const cpp_member_spect & member_spec() const
bool is_constructor() const
void name_anon_struct_union()
symbolt & convert(const typet &type, const cpp_storage_spect &storage_spec, const cpp_member_spect &member_spec, cpp_declaratort &declarator)
irept & member_initializers()
typet merge_type(const typet &declaration_type) const
bool is_template_scope() const
irep_idt class_identifier
void set_inline(bool value)
irep_idt get_base_name() const
const source_locationt & source_location() const
bool is_simple_name() const
cpp_scopet & current_scope()
cpp_scopet & set_scope(const irep_idt &identifier)
cpp_scopet & get_scope(const irep_idt &identifier)
cpp_idt & put_into_scope(const symbolt &symbol, cpp_scopet &scope, bool is_friend=false)
void go_to_global_scope()
cpp_scopet & get_global_scope()
cpp_scopet & get_parent() const
id_sett lookup(const irep_idt &base_name_to_lookup, lookup_kindt kind)
cpp_idt & insert(const irep_idt &_base_name)
bool contains(const irep_idt &base_name_to_lookup)
source_locationt & location()
cpp_scopet & resolve_scope(const cpp_namet &cpp_name, irep_idt &base_name, cpp_template_args_non_tct &template_args)
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)
std::optional< codet > cpp_constructor(const source_locationt &source_location, const exprt &object, const exprt::operandst &operands)
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)
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 make_ptr_typecast(exprt &expr, const pointer_typet &dest_type)
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 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
std::string::const_iterator begin() 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.
source_locationt & add_source_location()
const source_locationt & source_location() const
typet & type()
Return the type of the expression.
bool is_constant() const
Return whether the expression is a constant.
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
std::string pretty(unsigned indent=0, unsigned max_indent=0) 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)
const irep_idt & id() const
void move_to_sub(irept &irep)
const std::string & get_string(const irep_idt &name) const
irept & add(const irep_idt &name)
Extract member of struct or union.
source_locationt source_location
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
const symbolt & lookup(const irep_idt &name) const
Lookup a symbol in the namespace.
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
const typet & base_type() const
The type of the data what we point to.
A side_effect_exprt representation of a function call side effect.
exprt::operandst & arguments()
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_name() const
const irep_idt & get_base_name() const
void set_pretty_name(const irep_idt &name)
void set_base_name(const irep_idt &base_name)
void set_name(const irep_idt &name)
Base type for structs and unions.
irep_idt default_access() const
Return the access specification for members where access has not been modified.
bool is_incomplete() const
A struct/union may be incomplete.
const componentst & components() const
void make_incomplete()
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
virtual bool move(symbolt &symbol, symbolt *&new_symbol)=0
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 std::pair< symbolt &, bool > insert(symbolt symbol)=0
Move or copy a new symbol to the symbol table.
irep_idt base_name
Base (non-scoped) name.
source_locationt location
Source code location of definition of symbol.
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
typet type
Type of symbol.
irep_idt name
The unique identifier.
irep_idt pretty_name
Language-specific display name.
exprt value
Initial value of symbol.
irep_idt mode
Language mode.
Symbol table entry describing a data typeThis is a symbol generated as part of type checking.
Semantic type conversion.
The type of an expression, extends irept.
const source_locationt & source_location() const
source_locationt & add_source_location()
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)
static bool symbol_exists(const goto_modelt &goto_model, const irep_idt &name, const bool require_has_code_type, const bool require_body_available)
Returns true iff the given symbol exists and satisfies requirements.
#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.
#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)
const codet & to_code(const exprt &expr)
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
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 multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_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.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
static bool failed(bool error_indicator)
const type_with_subtypest & to_type_with_subtypes(const typet &type)