3 /******************************************************************************
5 For some things we need some internal static inline functions,
6 where otherwise we would have to use statements in
9 However, these are created only if/when needed.
11 ******************************************************************************/
13 static intnode
*dinits
;
15 Token
i_call_initialization (recID r
)
17 intnode
*n
= intfind (dinits
, r
);
20 Token n1
= name_of_struct (r
);
21 Token fn
= name_intern_ctor (r
);
22 Token xx
= RESERVED_x
;
23 Token yy
= RESERVED_y
;
24 Token ii
= RESERVED_i
;
25 Token XX
= RESERVED_X
;
28 - static inline void A__ICoNsTrUcTioN (struct A *x, const int u)
31 - for (i = 0; i < y; i++) {
32 - struct A *X = &xx [i];
33 - .. here we gen_construction_code from hier.c ...
38 OUTSTREAM IC
= new_stream ();
40 outprintf (IC
, RESERVED_static
, RESERVED_inline
, RESERVED_void
,
41 fn
, '(', iRESERVED_struct (r
), n1
, '*', xx
, ',', RESERVED_const
,
42 RESERVED_int
, yy
, ')', '{', RESERVED_int
, ii
, ';', RESERVED_for
, '(',
43 ii
, '=', RESERVED_0
, ';', ii
, '<', yy
, ';', ii
, PLUSPLUS
, ')', '{',
44 iRESERVED_struct (r
), n1
, '*', XX
, '=', '&', xx
, '[', ii
, ']', ';', -1);
46 gen_construction_code (IC
, r
, XX
);
48 outprintf (IC
, '}', '}', -1);
50 concate_streams (INTERNAL_CODE
, IC
);
52 union ival i
= { .i
= fn
};
53 intadd (&dinits
, r
, i
);
58 static intnode
*dcasts
;
60 Token
i_downcast_function (recID rb
, recID rd
)
62 int bdi
= rb
+ rd
* 3000;
63 intnode
*n
= intfind (dcasts
, bdi
);
69 if (n
= intfind (dcasts
, bdi
)) return n
->v
.i
;
71 Token base
= name_of_struct (rb
), der
= name_of_struct (rd
);
72 Token fname
= name_downcast (base
, der
);
75 bool va
= is_ancestor_runtime (rd
, rb
, &path
);
78 - static inline struct der *downcast (struct base *x)
80 - return (struct der*)((void*)x - (int) &(((struct der*)0)->path));
83 - static inline struct der *downcast (struct base *x)
85 - return (struct der*)((void*)x + x->_v_p_t_r_->base_der_DoWnCaSt);
87 - or broken into the above two:
88 - static inline struct der *downcast (struct base *x)
90 - return downcast (downcast (x));
94 #define VOIDCAST '(', RESERVED_void, '*', ')'
96 OUTSTREAM IC
= new_stream ();
97 outprintf (IC
, RESERVED_static
, RESERVED_inline
,
98 iRESERVED_struct (rd
), der
, '*', fname
, '(', RESERVED_const
,
99 iRESERVED_struct (rb
), base
, '*', x
, ')', '{', RESERVED_return
, -1);
103 '(', iRESERVED_struct (rd
), der
, '*', ')',
104 '(', VOIDCAST
, x
, '-', '(', RESERVED_int
, ')', '&',
105 '(', '(', '(', iRESERVED_struct (rd
), der
, '*', ')',
106 RESERVED_0
, ')', POINTSAT
, ISTR (path
), ')', ')', -1);
107 } else if (path
[1] == -1) {
110 downcast_rtti (rd
, rb
, rb
, path
);
112 '(', iRESERVED_struct (rd
), der
, '*', ')', '(',
113 VOIDCAST
, x
, '+', x
, POINTSAT
, ISTR (path
), ')', -1);
116 /* In this case, we can implement the first half of the downcast
117 -which is plain- with one of the above and call
118 only one DoWnCaSt function. Typically it makes no difference
119 because gcc can do great work recursively inlining all these.
120 So AFA assembly is concerned we don't have to do this optimization.
121 Having fewer DoWnCaSt functions in the output, would be
127 if (path
[1] == POINTSAT
)
128 mid
= ancest_named (rd
, path
[0]);
129 else for (mid
= rd
, i
= 0; path
[i
+ 1] != POINTSAT
&& path
[i
+ 1] != -1; i
+= 2)
130 mid
= ancest_named (mid
, path
[i
]);
133 '(', iRESERVED_struct (rd
), name_of_struct (rd
), '*', ')',
134 i_downcast_function (mid
, rd
), '(',
135 i_downcast_function (rb
, mid
), '(', x
, ')',
139 outprintf (IC
, ';', '}', -1);
140 concate_streams (INTERNAL_CODE
, IC
);
142 union ival i
= { .i
= fname
};
143 intadd (&dcasts
, bdi
, i
);
147 static intnode
*dcasts_safe
;
149 Token
i_downcast_null_safe (recID rb
, recID rd
)
151 int bdi
= rb
+ rd
* 3000;
152 intnode
*n
= intfind (dcasts_safe
, bdi
);
153 if (n
) return n
->v
.i
;
156 - static inline struct der* downcast_safe (struct base *x)
158 - return x ? Downcast (x) : 0;
162 OUTSTREAM IC
= new_stream ();
163 Token base
= name_of_struct (rb
), der
= name_of_struct (rd
);
164 Token fname
= name_downcast_safe (base
, der
);
165 Token x
= RESERVED_x
;
167 outprintf (IC
, RESERVED_static
, RESERVED_inline
, iRESERVED_struct (rd
),
168 der
, '*', fname
, '(', iRESERVED_struct (rb
),
169 base
, '*', x
, ')', '{', RESERVED_return
,
170 x
, '?', i_downcast_function (rb
, rd
), '(', x
, ')', ':',
171 RESERVED_0
, ';', '}', -1);
173 concate_streams (INTERNAL_CODE
, IC
);
175 union ival i
= { .i
= fname
};
176 intadd (&dcasts_safe
, bdi
, i
);
180 static intnode
*upcasts
;
182 Token
i_upcast_null_safe (recID rb
, recID rd
, Token
*path
, bool ptrpath
)
184 int bdi
= rb
+ rd
* 3000;
185 intnode
*n
= intfind (upcasts
, bdi
);
186 if (n
) return n
->v
.i
;
189 - static inline struct base* upcast_safe (struct der *x)
191 - return x ? &x->path : 0;
195 Token base
= name_of_struct (rb
), der
= name_of_struct (rd
);
196 Token fname
= name_upcast_safe (base
, der
);
197 Token x
= RESERVED_x
;
199 outprintf (INTERNAL_CODE
, RESERVED_static
, RESERVED_inline
,
200 iRESERVED_struct (rb
), base
, '*', fname
,
201 '(', iRESERVED_struct (rd
), der
, '*', x
, ')', '{',
202 RESERVED_return
, x
, '?', ptrpath
? BLANKT
: '&', x
,
203 POINTSAT
, ISTR (path
), ':', RESERVED_0
, ';', '}', -1);
205 union ival i
= { .i
= fname
};
206 intadd (&upcasts
, bdi
, i
);
210 static intnode
*vcalls
;
212 Token
i_member_virtual (recID r
, Token n
, typeID
*argt
, flookup
*rF
)
214 Token vpath
[128], *proto
;
217 bool modular
= rF
->flagz
& FUNCP_MODULAR
;
219 rF
->flagz
&= ~FUNCP_MODULAR
;
220 if (!lookup_virtual_function_member (r
, n
, argt
, vpath
, &F
))
221 parse_error_ll ("error && bug");
223 rF
->oname
= F
.oname
= vpath
[intlen (vpath
) - 1];
224 if (intfind (vcalls
, F
.oname
))
227 // create the new prototype
228 proto
= allocaint (intlen (F
.prototype
) + 10);
229 intcpy (proto
, F
.prototype
);
232 for (i
= 0; proto
[i
] != MARKER
; i
++);
233 while (proto
[i
] != '(') i
++;
234 Token
*rest
= allocaint (intlen (proto
+ i
) + 1);
235 intcpy (rest
, proto
+ ++i
);
236 sintprintf (proto
+ i
, RESERVED_const
, iRESERVED_struct (r
),
237 name_of_struct (r
), '*', RESERVED_this
, -1);
241 sintprintf (proto
+ i
, ISTR (rest
), -1);
243 intsubst1 (proto
, MARKER
, F
.oname
);
244 rF
->prototype
= intdup (proto
);
246 i
= modular
&& F
.xargs
[0] == -1 ? 0 : 1;
247 outprintf (INTERNAL_CODE
, intchr (proto
, RESERVED_static
) ? BLANKT
: RESERVED_static
,
248 intchr (proto
, RESERVED_inline
) ? BLANKT
: RESERVED_inline
,
249 ISTR (proto
), '{', RESERVED_return
, RESERVED_this
, POINTSAT
,
251 modular
? (F
.xargs
[0] != -1 ? F
.xargs
[0] : BLANKT
) : RESERVED_this
, -1);
252 for (; F
.xargs
[i
] != -1; i
++)
253 outprintf (INTERNAL_CODE
, ',', F
.xargs
[i
], -1);
254 outprintf (INTERNAL_CODE
, ')', ';', '}', -1);
257 intadd (&vcalls
, F
.oname
, I
);
261 static intnode
*trftree
;
263 Token
i_trampoline_func (flookup
*F
, bool argb
[])
270 parse_error_ll ("Can't do it");
272 for (i
= 0; argb
[i
] != -1; i
++)
273 snm
[i
] = argb
[i
] ? '1' : '0';
274 snm
[i
] = 0; strcat (snm
, "trampoline");
276 tfn
= tokstrcat (F
->oname
, snm
);
277 if (intfind (trftree
, tfn
))
280 Token
*proto
= mallocint (intlen (F
->prototype
) + 1);
281 intcpy (proto
, F
->prototype
);
282 if (intchr (proto
, F
->oname
))
283 intsubst (proto
, F
->oname
, tfn
);
284 else if (intchr (proto
, MARKER
))
285 intsubst (proto
, MARKER
, tfn
);
286 else parse_error_ll ("Nasty alien outlaw bug");
288 if (intchr (proto
, RESERVED__CLASS_
))
289 repl__CLASS_ (&proto
, base_of (open_typeID (F
->t
)[2]));
291 for (i
= 0; argb
[i
] != -1; i
++)
293 for (j
= 2; proto
[j
] != F
->xargs
[i
]; j
++);
294 if (proto
[j
- 1] == RESERVED_const
)
295 proto
[j
- 2] = BLANKT
;
296 proto
[j
- 1] = BLANKT
;
299 outprintf (INTERNAL_CODE
, intchr (proto
, RESERVED_static
) ? BLANKT
: RESERVED_static
,
300 intchr (proto
, RESERVED_inline
) ? BLANKT
: RESERVED_inline
,
301 ISTR (proto
), '{', -1);
303 outprintf (INTERNAL_CODE
, RESERVED_return
, F
->oname
, '(', -1);
304 for (i
= 0; argb
[i
] != -1; i
++) {
305 outprintf (INTERNAL_CODE
, argb
[i
] ? '&' : BLANKT
, F
->xargs
[i
],
306 argb
[i
+ 1] == -1 ? BLANKT
: ',', -1);
308 outprintf (INTERNAL_CODE
, ')', ';', '}', -1);
312 intadd (&trftree
, tfn
, I
);
316 static intnode
*ebntree
;
318 Token
i_enum_by_name (Token e
)
321 intnode
*n
= intfind (ebntree
, e
);
325 if (!is_enum (e
)) parse_error_tok (e
, "__enumstr__: enumerator not defined");
327 Token fname
= name_ebn_func (e
), *consts
= enum_syms (lookup_enum (e
));
329 outprintf (INTERNAL_CODE
, RESERVED_const
, RESERVED_char
, '*', fname
, '(',
330 RESERVED_int
, ')', linkonce_text (fname
), ';',
331 RESERVED_const
, RESERVED_char
, '*', fname
, '(', RESERVED_int
, RESERVED_X
, ')',
332 '{', RESERVED_switch
, '(', RESERVED_X
, ')', '{', -1);
333 for (i
= 0; consts
[i
] != -1; i
++)
334 outprintf (INTERNAL_CODE
, RESERVED_case
, consts
[i
], ':',
335 RESERVED_return
, new_value_string (expand (consts
[i
])), ';', -1);
336 outprintf (INTERNAL_CODE
, RESERVED_default
, ':', RESERVED_return
,
337 RESERVED_0
, ';', '}', '}', -1);
339 union ival I
= { .i
= fname
};
340 intadd (&ebntree
, e
, I
);
344 static intnode
*typeidt
;
346 Token
i_typeid_var (Token c
)
348 intnode
*n
= intfind (typeidt
, c
);
352 Token fname
= name_typeid_var (c
);
354 outprintf (GVARS
, RESERVED_const
, RESERVED_char
, fname
, '[', ']',
355 linkonce_rodata (fname
), '=', stringify (c
), ';', -1);
357 union ival I
= { .i
= fname
};
358 intadd (&typeidt
, c
, I
);
363 static intnode
*arrdtortree
;
365 Token
i_arrdtor_func (recID r
)
367 Token i
= RESERVED_i
, p
= RESERVED_p
;
368 intnode
*n
= intfind (arrdtortree
, r
);
373 arrdtor
= new_symbol ("ArRdToR");
374 outprintf (INTERNAL_CODE
, RESERVED_struct
, arrdtor
, '{', RESERVED_void
, '*',
375 p
, ';', RESERVED_int
, i
, ';', '}', ';', -1);
378 Token fname
= name_arrdtor (r
);
380 outprintf (INTERNAL_CODE
, RESERVED_static
, RESERVED_inline
, RESERVED_void
, fname
, '(',
381 RESERVED_struct
, arrdtor
, '*', RESERVED_this
, ')', '{',
382 iRESERVED_struct (r
), name_of_struct (r
), '*', p
, '=',
383 RESERVED_this
, POINTSAT
, p
, ';', RESERVED_int
, i
, '=',
384 RESERVED_this
, POINTSAT
, i
, ';', RESERVED_while
, '(', i
, ')',
385 dtor_name (r
), '(', '&', p
, '[', MINUSMINUS
, i
, ']', ')', ';', '}', -1);
387 union ival I
= { .i
= fname
};
388 intadd (&arrdtortree
, r
, I
);
392 /***********************************************
393 These are called by expressions
394 ***********************************************/
396 void alloc_and_init (OUTSTREAM o
, recID r
, Token tid
, Token alloc
, Token vec
)
398 Token sn
= name_of_struct (r
);
402 - = (struct sn*) malloc_alloca (sizeof (struct sn));
403 - sn___CoNsTruCTion (x, 1);
405 - = (struct sn*) malloc_alloca (sizeof (struct sn) * n);
406 - sn___CoNsTruCTion (x, n);
407 - or with custom allocator
408 - = (struct sn*) allocator_fn ();
409 - sn___CoNsTruCTion (x, 1);
411 outprintf (o
, '=', '(', iRESERVED_struct (r
), sn
, '*', ')', alloc
, '(', -1);
412 if (in2 (alloc
, new_wrap
, INTERN_alloca
))
413 outprintf (o
, RESERVED_sizeof
, '(', iRESERVED_struct (r
), sn
, ')', -1);
414 if (vec
) outprintf (o
, '*', vec
, -1);
415 outprintf (o
, ')', ';', -1);
417 if (need_construction (r
)) {
418 ic
= i_call_initialization (r
);
419 outprintf (o
, ic
, '(', tid
, ',', vec
?: RESERVED_1
, ')', ';', -1);
423 void alloc_and_init_dcl (OUTSTREAM o
, recID r
, Token tid
, bool array
)
427 if (o
== GLOBAL_INIT_FUNC
) GlobInitUsed
= true;
429 - A__CoNsTruCTioN (&a, 1);
431 - A__CoNsTruCTioN (a, sizeof a / sizeof a [0]);
433 ic
= i_call_initialization (r
);
434 if (array
) outprintf (o
, ic
, '(', tid
, ',', RESERVED_sizeof
, tid
,
435 '/', RESERVED_sizeof
, tid
, '[', RESERVED_0
, ']', ')', ';', -1);
436 else outprintf (o
, ic
, '(', '&', tid
, ',', RESERVED_1
, ')', ';', -1);