9
9
#include < util/i2string.h>
10
10
#include < util/std_types.h>
11
11
#include < util/arith_tools.h>
12
+ #include < util/namespace.h>
13
+ #include < util/symbol.h>
14
+ #include < util/symbol_table.h>
12
15
13
16
#include " type2name.h"
14
17
18
+ typedef hash_map_cont<irep_idt, std::pair<size_t , bool >, irep_id_hash>
19
+ symbol_numbert;
20
+
21
+ static std::string type2name (
22
+ const typet &type,
23
+ const namespacet &ns,
24
+ symbol_numbert &symbol_number);
25
+
26
+ /* ******************************************************************\
27
+
28
+ Function: type2name_symbol
29
+
30
+ Inputs:
31
+
32
+ Outputs:
33
+
34
+ Purpose:
35
+
36
+ \*******************************************************************/
37
+
38
+ static std::string type2name_symbol (
39
+ const typet &type,
40
+ const namespacet &ns,
41
+ symbol_numbert &symbol_number)
42
+ {
43
+ const irep_idt &identifier=type.get (ID_identifier);
44
+
45
+ const symbolt *symbol;
46
+
47
+ if (ns.lookup (identifier, symbol))
48
+ return " SYM#" +id2string (identifier)+" #" ;
49
+
50
+ assert (symbol && symbol->is_type );
51
+
52
+ if (symbol->type .id ()!=ID_struct &&
53
+ symbol->type .id ()!=ID_union)
54
+ return type2name (symbol->type , ns, symbol_number);
55
+
56
+ std::string result;
57
+
58
+ // assign each symbol a number when seen for the first time
59
+ std::pair<symbol_numbert::iterator, bool > entry=
60
+ symbol_number.insert (std::make_pair (
61
+ identifier,
62
+ std::make_pair (symbol_number.size (), true )));
63
+
64
+ // new entry, add definition
65
+ if (entry.second )
66
+ {
67
+ result=" SYM#" +i2string (entry.first ->second .first );
68
+ result+=" ={" ;
69
+ result+=type2name (symbol->type , ns, symbol_number);
70
+ result+=' }' ;
71
+
72
+ entry.first ->second .second =false ;
73
+ }
74
+ #if 0
75
+ // in recursion, print the shorthand only
76
+ else if(entry.first->second.second)
77
+ result="SYM#"+i2string(entry.first->second.first);
78
+ // entering recursion
79
+ else
80
+ {
81
+ entry.first->second.second=true;
82
+ result=type2name(symbol->type, ns, symbol_number);
83
+ entry.first->second.second=false;
84
+ }
85
+ #else
86
+ // shorthand only as structs/unions are always symbols
87
+ else
88
+ result=" SYM#" +i2string (entry.first ->second .first );
89
+ #endif
90
+
91
+ return result;
92
+ }
93
+
15
94
/* ******************************************************************\
16
95
17
96
Function: type2name
@@ -24,7 +103,11 @@ Function: type2name
24
103
25
104
\*******************************************************************/
26
105
27
- std::string type2name (const typet &type)
106
+ static bool parent_is_sym_check=false ;
107
+ static std::string type2name (
108
+ const typet &type,
109
+ const namespacet &ns,
110
+ symbol_numbert &symbol_number)
28
111
{
29
112
std::string result;
30
113
@@ -38,6 +121,14 @@ std::string type2name(const typet &type)
38
121
if (type.get_bool (ID_C_volatile))
39
122
result+=' v' ;
40
123
124
+ if (type.get_bool (ID_C_transparent_union))
125
+ result+=' t' ;
126
+
127
+ // this isn't really a qualifier, but the linker needs to
128
+ // distinguish these - should likely be fixed in the linker instead
129
+ if (!type.source_location ().get_function ().empty ())
130
+ result+=' l' ;
131
+
41
132
if (type.id ()==irep_idt ())
42
133
throw " Empty type encountered." ;
43
134
else if (type.id ()==ID_empty)
@@ -69,15 +160,15 @@ std::string type2name(const typet &type)
69
160
{
70
161
const code_typet &t=to_code_type (type);
71
162
const code_typet::parameterst parameters=t.parameters ();
72
- result+=" P (" ;
163
+ result+=type2name (t. return_type (), ns, symbol_number)+ " (" ;
73
164
74
165
for (code_typet::parameterst::const_iterator
75
166
it=parameters.begin ();
76
167
it!=parameters.end ();
77
168
it++)
78
169
{
79
170
if (it!=parameters.begin ()) result+=' |' ;
80
- result+=type2name (it->type ());
171
+ result+=type2name (it->type (), ns, symbol_number );
81
172
}
82
173
83
174
if (t.has_ellipsis ())
@@ -87,24 +178,32 @@ std::string type2name(const typet &type)
87
178
}
88
179
89
180
result+=" )->" ;
90
- result+=type2name (t.return_type ());
181
+ result+=type2name (t.return_type (), ns, symbol_number );
91
182
}
92
183
else if (type.id ()==ID_array)
93
184
{
94
185
const array_typet &t=to_array_type (type);
95
186
mp_integer size;
96
187
if (to_integer (t.size (), size))
97
188
result+=" ARR?" ;
189
+ else if (t.size ().id ()==ID_symbol)
190
+ result+=" ARR" +t.size ().get_string (ID_identifier);
98
191
else
99
192
result+=" ARR" +integer2string (size);
100
193
}
101
- else if (type.id ()==ID_symbol)
194
+ else if (type.id ()==ID_symbol ||
195
+ type.id ()==ID_c_enum_tag ||
196
+ type.id ()==ID_struct_tag ||
197
+ type.id ()==ID_union_tag)
102
198
{
103
- result+=" SYM#" +type.get_string (ID_identifier)+" #" ;
199
+ parent_is_sym_check=true ;
200
+ result+=type2name_symbol (type, ns, symbol_number);
104
201
}
105
202
else if (type.id ()==ID_struct ||
106
203
type.id ()==ID_union)
107
204
{
205
+ assert (parent_is_sym_check);
206
+ parent_is_sym_check=false ;
108
207
if (type.id ()==ID_struct) result+=" ST" ;
109
208
if (type.id ()==ID_union) result+=" UN" ;
110
209
const struct_union_typet &t=to_struct_union_type (type);
@@ -116,19 +215,31 @@ std::string type2name(const typet &type)
116
215
it++)
117
216
{
118
217
if (it!=components.begin ()) result+=' |' ;
119
- result+=type2name (it->type ());
120
- result+=" '" +it->get_string (ID_name)+" '| " ;
218
+ result+=type2name (it->type (), ns, symbol_number );
219
+ result+=" '" +it->get_string (ID_name)+" '" ;
121
220
}
122
221
result+=' ]' ;
123
222
}
124
223
else if (type.id ()==ID_incomplete_struct)
125
224
result +=" ST?" ;
126
225
else if (type.id ()==ID_incomplete_union)
127
226
result +=" UN?" ;
128
- else if (type.id ()==ID_c_enum_tag)
129
- result +=" EN" +to_c_enum_tag_type (type).get_string (ID_identifier)+" #" ;
130
227
else if (type.id ()==ID_c_enum)
131
- result +=" EN" +type.get_string (ID_width);
228
+ {
229
+ result +=" EN" ;
230
+ const c_enum_typet &t=to_c_enum_type (type);
231
+ const c_enum_typet::memberst &members=t.members ();
232
+ result+=' [' ;
233
+ for (c_enum_typet::memberst::const_iterator
234
+ it=members.begin ();
235
+ it!=members.end ();
236
+ ++it)
237
+ {
238
+ if (it!=members.begin ()) result+=' |' ;
239
+ result+=id2string (it->get_value ());
240
+ result+=" '" +id2string (it->get_identifier ())+" '" ;
241
+ }
242
+ }
132
243
else if (type.id ()==ID_incomplete_c_enum)
133
244
result +=" EN?" ;
134
245
else if (type.id ()==ID_c_bit_field)
@@ -143,7 +254,7 @@ std::string type2name(const typet &type)
143
254
if (type.has_subtype ())
144
255
{
145
256
result+=' {' ;
146
- result+=type2name (type.subtype ());
257
+ result+=type2name (type.subtype (), ns, symbol_number);
147
258
result+=' }' ;
148
259
}
149
260
@@ -152,13 +263,49 @@ std::string type2name(const typet &type)
152
263
result+=' $' ;
153
264
forall_subtypes (it, type)
154
265
{
155
- result+=type2name (*it);
156
- result+=" | " ;
266
+ result+=type2name (*it, ns, symbol_number );
267
+ result+=' | ' ;
157
268
}
158
- result.resize (result.size ()-1 );
159
- result+=' $' ;
269
+ result[result.size ()-1 ]=' $' ;
160
270
}
161
271
162
272
return result;
163
273
}
164
274
275
+ /* ******************************************************************\
276
+
277
+ Function: type2name
278
+
279
+ Inputs:
280
+
281
+ Outputs:
282
+
283
+ Purpose:
284
+
285
+ \*******************************************************************/
286
+
287
+ std::string type2name (const typet &type, const namespacet &ns)
288
+ {
289
+ parent_is_sym_check=true ;
290
+ symbol_numbert symbol_number;
291
+ return type2name (type, ns, symbol_number);
292
+ }
293
+
294
+ /* ******************************************************************\
295
+
296
+ Function: type2name
297
+
298
+ Inputs:
299
+
300
+ Outputs:
301
+
302
+ Purpose:
303
+
304
+ \*******************************************************************/
305
+
306
+ std::string type2name (const typet &type)
307
+ {
308
+ symbol_tablet symbol_table;
309
+ return type2name (type, namespacet (symbol_table));
310
+ }
311
+
0 commit comments