-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathorder.c
311 lines (270 loc) · 7.6 KB
/
order.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
/* $Source: /home/CVSROOT/c2ada/order.c,v $ */
/* $Revision: 1.1.1.1 $ $Date: 1999/02/02 12:01:51 $ */
#include "c2ada.h"
/* TBD: we're commandeering an unused bit, which should be renamed */
#define DONE_MARK(sym) ((sym)->emitted)
static void undone_type_requisites(symbols_t syms, typeinfo_pt type, unit_n unit);
static void undone_node_requisites(symbols_t syms, node_pt node, unit_n unit);
bool sym_done(symbol_t* sym)
{
if(DONE_MARK(sym))
return true;
if(sym->intrinsic)
return true;
switch(sym->sym_kind)
{
case enum_literal:
return sym_done(sym->sym_type->type_base);
case param_symbol:
return true;
default:
return false;
}
}
static void undone_sym(symbols_t syms, symbol_t* sym, unit_n unit)
{
if(pos_unit(sym->sym_def) != unit)
return;
if(sym_done(sym))
return;
symset_add(syms, sym);
}
static void undone_sym_requisites(symbols_t syms, symbol_t* sym, unit_n unit)
{
switch(sym->sym_kind)
{
case type_symbol:
/* type requisites */
undone_type_requisites(syms, sym->sym_type, unit);
break;
case func_symbol:
/* return type */
undone_type_requisites(syms, sym->sym_type, unit);
/* parameter types */
/* (TBD) ? body dependencies */
break;
case param_symbol:
/* type requisites */
undone_type_requisites(syms, sym->sym_type, unit);
case var_symbol:
/* type requisites */
undone_type_requisites(syms, sym->sym_type, unit);
/* initializer value requisites */
if(sym->has_initializer)
{
undone_node_requisites(syms, sym->sym_value.initializer, unit);
}
break;
case enum_literal:
/* (no additional requisites) */
break;
case pkg_symbol:
/* argument (type sym) requisites */
/* TBD */
break;
}
}
static void undone_type_requisites(symbols_t syms, typeinfo_pt type, unit_n unit)
{
if(!type)
return;
/* TBD what about requisites of type->type_base symbol? */
if(type->type_base)
{
undone_sym(syms, type->type_base, unit);
return;
}
switch(type->type_kind)
{
case pointer_to:
/* type_next requisites */
undone_type_requisites(syms, type->type_next, unit);
break;
case array_of:
/* type_next requisites */
undone_type_requisites(syms, type->type_next, unit);
break;
case struct_of:
case union_of:
/* field type requisites */
{
/* n
symbol_t* tag;
for (tag=type->typesym->sym_tags; tag; tag=tag->sym_parse_list)
{ undone_type_requisites( syms, tag->sym_type. unit );
}
*/
}
break;
case field_type:
/* (no additional requisites?) */
break;
case int_type:
/* (no additional requisties?) */
break;
case float_type:
/* (no additional requisites?) */
break;
case void_type:
/* (no additioanl requisites?) */
break;
case function_type:
/* return type */
undone_type_requisites(syms, type->type_next, unit);
/* argument types */
{
symbol_t* arg;
for(arg = type->type_info.formals; arg; arg = arg->sym_parse_list)
{
undone_type_requisites(syms, arg->sym_type, unit);
}
break;
}
case enum_type:
/* (no additional requisites) */
break;
case typemodifier:
/* (case shouldn't occur?) */
/* type_next requisites */
undone_type_requisites(syms, type->type_next, unit);
break;
}
return;
}
void undone_node_requisites(symbols_t syms, node_pt node, unit_n unit)
{
if(!node)
return;
switch(node->node_kind)
{
case _Error:
/* raise exception */
case _Ellipsis:
case _FP_Number:
case _Int_Number:
case _Char_Lit:
return;
case _Type:
/* undone_type ( node->node.typ) */
undone_type_requisites(syms, node->node.typ, unit);
break;
case _Sym:
/* node->node.sym */
undone_sym(syms, node->node.sym, unit);
break;
case _Ident:
break;
case _Macro_ID:
/* TBD */
break;
case _String:
break;
/* binary operators */
case _List:
case _Comma:
case _Bit_Field:
case _Dot_Selected:
case _Arrow_Selected:
case _Array_Index:
case _Func_Call:
case _Type_Cast:
case _Assign:
case _Mul_Assign:
case _Div_Assign:
case _Mod_Assign:
case _Add_Assign:
case _Sub_Assign:
case _Shl_Assign:
case _Shr_Assign:
case _Band_Assign:
case _Xor_Assign:
case _Bor_Assign:
case _Eq:
case _Ne:
case _Lt:
case _Le:
case _Gt:
case _Ge:
case _Land:
case _Lor:
case _Band:
case _Bor:
case _Xor:
case _Add:
case _Sub:
case _Mul:
case _Div:
case _Rem:
case _Shl:
case _Shr: /* last binary */
case _Exp: /* exponentiation, Ada only: binary */
undone_node_requisites(syms, node->node.binary.l, unit);
undone_node_requisites(syms, node->node.binary.r, unit);
break;
/* unary operators */
case _Sizeof: /* first unary */
case _Pre_Inc:
case _Pre_Dec:
case _Post_Inc:
case _Post_Dec:
case _Addrof:
case _Unary_Plus:
case _Unary_Minus:
case _Ones_Complement:
case _Not:
case _Aggregate:
case _Indirect:
case _BoolTyp:
case _UnBool:
case _Char_to_Int:
case _Int_to_Char:
/* node->node.unary */
undone_node_requisites(syms, node->node.unary, unit);
break;
case _Cond:
/* node->cond.{boolval,tru,fals} */
undone_node_requisites(syms, node->node.cond.boolval, unit);
undone_node_requisites(syms, node->node.cond.tru, unit);
undone_node_requisites(syms, node->node.cond.fals, unit);
break;
default:
break;
/* error */
}
}
/* TBD: can we assume that fix_stmt has enqueued all the necessary
* symbols (types)? After all, no forward refs in C.
*/
symbols_t undone_requisites(symbol_t* sym)
{
symbols_t syms;
unit_n unit = pos_unit(sym->sym_def);
syms = get_undone_requisites(sym);
if(syms)
{
/* update the current requisites */
symset_filter_undone(syms);
}
else
{
syms = new_symbols_set();
undone_sym_requisites(syms, sym, unit);
}
set_undone_requisites(sym, syms);
return syms;
}
bool has_undone_requisites(symbol_t* sym)
{
symbols_t syms = undone_requisites(sym);
bool result = symset_size(syms) > 0;
/* TBD: free reference to syms */
return result;
}
void set_symbol_done(symbol_t* sym)
{
DONE_MARK(sym) = true;
}
void postpone_doing(symbol_t* sym)
{
/* TBD: just a placeholder at the moment */
}