@@ -25,11 +25,35 @@ Author: Daniel Kroening, kroening@kroening.com
2525#include < util/string_utils.h>
2626
2727#include < ansi-c/expr2c.h>
28+ #include < ansi-c/type2name.h>
29+ #include < cpp/cpp_type2name.h>
2830#include < cpp/expr2cpp.h>
2931#include < linking/static_lifetime_init.h>
3032
3133#include " goto_program2code.h"
3234
35+ static std::string clean_identifier (const irep_idt &id)
36+ {
37+ std::string result;
38+ result.reserve (id2string (id).size ());
39+
40+ for (auto c : id2string (id))
41+ {
42+ if (c >= ' 0' && c <= ' 9' )
43+ result += c;
44+ else if (c >= ' A' && c <= ' Z' )
45+ result += c;
46+ else if (c >= ' a' && c <= ' z' )
47+ result += c;
48+ else if (c == ' _' || c == ' $' )
49+ result += c;
50+ else
51+ result += " _" + std::to_string (c);
52+ }
53+
54+ return result;
55+ }
56+
3357dump_c_configurationt dump_c_configurationt::default_configuration =
3458 dump_c_configurationt ();
3559
@@ -58,11 +82,32 @@ void dump_ct::operator()(std::ostream &os)
5882
5983 // add copies of struct types when ID_C_transparent_union is only
6084 // annotated to parameter
61- symbol_tablet symbols_transparent ;
85+ symbol_tablet additional_symbols ;
6286 for (const auto &named_symbol : copied_symbol_table.symbols )
6387 {
6488 const symbolt &symbol=named_symbol.second ;
6589
90+ if (
91+ (symbol.type .id () == ID_union || symbol.type .id () == ID_struct) &&
92+ !symbol.is_type )
93+ {
94+ type_symbolt ts{symbol.type };
95+ ts.mode = symbol.mode ;
96+ if (mode == ID_C)
97+ ts.name = " tag-" + type2name (symbol.type , ns);
98+ else if (mode == ID_cpp)
99+ ts.name = " tag-" + cpp_type2name (symbol.type );
100+ else
101+ UNREACHABLE;
102+ typet &type =
103+ copied_symbol_table.get_writeable_ref (named_symbol.first ).type ;
104+ if (ts.type .id () == ID_union)
105+ type = union_tag_typet{ts.name };
106+ else
107+ type = struct_tag_typet{ts.name };
108+ additional_symbols.add (ts);
109+ }
110+
66111 if (symbol.type .id ()!=ID_code)
67112 continue ;
68113
@@ -86,14 +131,14 @@ void dump_ct::operator()(std::ostream &os)
86131 new_type_sym.type .set (ID_C_transparent_union, true );
87132
88133 // we might have it already, in which case this has no effect
89- symbols_transparent .add (new_type_sym);
134+ additional_symbols .add (new_type_sym);
90135
91136 to_union_tag_type (type).set_identifier (new_type_sym.name );
92137 type.remove (ID_C_transparent_union);
93138 }
94139 }
95140 }
96- for (const auto &symbol_pair : symbols_transparent .symbols )
141+ for (const auto &symbol_pair : additional_symbols .symbols )
97142 {
98143 copied_symbol_table.add (symbol_pair.second );
99144 }
@@ -509,11 +554,11 @@ void dump_ct::convert_compound(
509554 collect_typedefs (comp.type (), true );
510555 }
511556
512- irep_idt comp_name=comp.get_name ();
513-
514- struct_body << indent (1 ) << " // " << comp_name << ' \n ' ;
557+ struct_body << indent (1 ) << " // " << comp.get_name () << ' \n ' ;
515558 struct_body << indent (1 );
516559
560+ irep_idt comp_name = clean_identifier (comp.get_name ());
561+
517562 // component names such as "main" would collide with other objects in the
518563 // namespace
519564 std::string fake_unique_name=" NO/SUCH/NS::" +id2string (comp_name);
@@ -1519,6 +1564,12 @@ void dump_ct::cleanup_expr(exprt &expr)
15191564 expr = unary_exprt{ID_initializer_list, bu.value ()};
15201565 }
15211566 }
1567+ else if (expr.id () == ID_member)
1568+ {
1569+ member_exprt &member_expr = to_member_expr (expr);
1570+ member_expr.set_component_name (
1571+ clean_identifier (member_expr.get_component_name ()));
1572+ }
15221573}
15231574
15241575void dump_ct::cleanup_type (typet &type)
0 commit comments