2 |
7u83 |
1 |
/*
|
|
|
2 |
Crown Copyright (c) 1997, 1998
|
|
|
3 |
|
|
|
4 |
This TenDRA(r) Computer Program is subject to Copyright
|
|
|
5 |
owned by the United Kingdom Secretary of State for Defence
|
|
|
6 |
acting through the Defence Evaluation and Research Agency
|
|
|
7 |
(DERA). It is made available to Recipients with a
|
|
|
8 |
royalty-free licence for its use, reproduction, transfer
|
|
|
9 |
to other parties and amendment for any purpose not excluding
|
|
|
10 |
product development provided that any such use et cetera
|
|
|
11 |
shall be deemed to be acceptance of the following conditions:-
|
|
|
12 |
|
|
|
13 |
(1) Its Recipients shall ensure that this Notice is
|
|
|
14 |
reproduced upon any copies or amended versions of it;
|
|
|
15 |
|
|
|
16 |
(2) Any amended version of it shall be clearly marked to
|
|
|
17 |
show both the nature of and the organisation responsible
|
|
|
18 |
for the relevant amendment or amendments;
|
|
|
19 |
|
|
|
20 |
(3) Its onward transfer from a recipient to another
|
|
|
21 |
party shall be deemed to be that party's acceptance of
|
|
|
22 |
these conditions;
|
|
|
23 |
|
|
|
24 |
(4) DERA gives no warranty or assurance as to its
|
|
|
25 |
quality or suitability for any purpose and DERA accepts
|
|
|
26 |
no liability whatsoever in relation to any use to which
|
|
|
27 |
it may be put.
|
|
|
28 |
*/
|
|
|
29 |
|
|
|
30 |
|
|
|
31 |
#include "config.h"
|
|
|
32 |
#include "version.h"
|
|
|
33 |
#include "c_types.h"
|
|
|
34 |
#include "ctype_ops.h"
|
|
|
35 |
#include "exp_ops.h"
|
|
|
36 |
#include "graph_ops.h"
|
|
|
37 |
#include "hashid_ops.h"
|
|
|
38 |
#include "id_ops.h"
|
|
|
39 |
#include "itype_ops.h"
|
|
|
40 |
#include "member_ops.h"
|
|
|
41 |
#include "nspace_ops.h"
|
|
|
42 |
#include "off_ops.h"
|
|
|
43 |
#include "type_ops.h"
|
|
|
44 |
#include "virt_ops.h"
|
|
|
45 |
#include "error.h"
|
|
|
46 |
#include "tdf.h"
|
|
|
47 |
#include "allocate.h"
|
|
|
48 |
#include "basetype.h"
|
|
|
49 |
#include "buffer.h"
|
|
|
50 |
#include "capsule.h"
|
|
|
51 |
#include "check.h"
|
|
|
52 |
#include "chktype.h"
|
|
|
53 |
#include "class.h"
|
|
|
54 |
#include "compile.h"
|
|
|
55 |
#include "constant.h"
|
|
|
56 |
#include "construct.h"
|
|
|
57 |
#include "derive.h"
|
|
|
58 |
#include "destroy.h"
|
|
|
59 |
#include "encode.h"
|
|
|
60 |
#include "exp.h"
|
|
|
61 |
#include "function.h"
|
|
|
62 |
#include "hash.h"
|
|
|
63 |
#include "init.h"
|
|
|
64 |
#include "initialise.h"
|
|
|
65 |
#include "interface.h"
|
|
|
66 |
#include "mangle.h"
|
|
|
67 |
#include "member.h"
|
|
|
68 |
#include "namespace.h"
|
|
|
69 |
#include "print.h"
|
|
|
70 |
#include "shape.h"
|
|
|
71 |
#include "struct.h"
|
|
|
72 |
#include "syntax.h"
|
|
|
73 |
#include "tok.h"
|
|
|
74 |
#include "token.h"
|
|
|
75 |
#include "virtual.h"
|
|
|
76 |
#if TDF_OUTPUT
|
|
|
77 |
|
|
|
78 |
|
|
|
79 |
/*
|
|
|
80 |
CLASS AND GRAPH TOKEN NUMBERS
|
|
|
81 |
|
|
|
82 |
Each node of a base class graph has three associated token numbers.
|
|
|
83 |
The use of these numbers varies depending on whether the node is
|
|
|
84 |
the top node of a graph, a virtual base class, or a non-virtual base
|
|
|
85 |
class. These macros give mnemonic values for these uses. Names are
|
|
|
86 |
also given to the various class type token numbers.
|
|
|
87 |
*/
|
|
|
88 |
|
|
|
89 |
#define ctype_shape( A ) ctype_tok1 ( ( A ) )
|
|
|
90 |
#define ctype_null_exp( A ) ctype_tok2 ( ( A ) )
|
|
|
91 |
#define graph_al_tag( A ) graph_tok1 ( ( A ) )
|
|
|
92 |
#define graph_core_off( A ) graph_tok2 ( ( A ) )
|
|
|
93 |
#define graph_base_off( A ) graph_tok1 ( ( A ) )
|
|
|
94 |
#define graph_real_off( A ) graph_tok2 ( ( A ) )
|
|
|
95 |
|
|
|
96 |
|
|
|
97 |
/*
|
|
|
98 |
DUMMY CLASS TYPE
|
|
|
99 |
|
|
|
100 |
These types are dummies used in the class layout routines.
|
|
|
101 |
*/
|
|
|
102 |
|
|
|
103 |
TYPE dummy_class = NULL_type ;
|
|
|
104 |
TYPE dummy_vtab = NULL_type ;
|
|
|
105 |
TYPE dummy_count = NULL_type ;
|
|
|
106 |
TYPE ptr_dummy_class = NULL_type ;
|
|
|
107 |
TYPE ptr_dummy_vtab = NULL_type ;
|
|
|
108 |
TYPE dummy_func = NULL_type ;
|
|
|
109 |
ulong size_dummy_vtab = 0 ;
|
|
|
110 |
OFFSET off_size_t = NULL_off ;
|
|
|
111 |
IDENTIFIER dummy_type_name = NULL_id ;
|
|
|
112 |
|
|
|
113 |
|
|
|
114 |
/*
|
|
|
115 |
ENCODE AN EXPRESSION TOKEN APPLICATION
|
|
|
116 |
|
|
|
117 |
This routine adds an application of the simple expression token n to
|
|
|
118 |
the bitstream bs.
|
|
|
119 |
*/
|
|
|
120 |
|
|
|
121 |
static BITSTREAM *enc_exp_token
|
|
|
122 |
PROTO_N ( ( bs, n ) )
|
|
|
123 |
PROTO_T ( BITSTREAM *bs X ulong n )
|
|
|
124 |
{
|
|
|
125 |
ulong m = link_no ( bs, n, VAR_token ) ;
|
|
|
126 |
ENC_exp_apply_token ( bs ) ;
|
|
|
127 |
ENC_make_tok ( bs, m ) ;
|
|
|
128 |
ENC_LEN_SMALL ( bs, 0 ) ;
|
|
|
129 |
return ( bs ) ;
|
|
|
130 |
}
|
|
|
131 |
|
|
|
132 |
|
|
|
133 |
/*
|
|
|
134 |
ENCODE A SHAPE TOKEN APPLICATION
|
|
|
135 |
|
|
|
136 |
This routine adds an application of the simple shape token n to the
|
|
|
137 |
bitstream bs.
|
|
|
138 |
*/
|
|
|
139 |
|
|
|
140 |
static BITSTREAM *enc_shape_token
|
|
|
141 |
PROTO_N ( ( bs, n ) )
|
|
|
142 |
PROTO_T ( BITSTREAM *bs X ulong n )
|
|
|
143 |
{
|
|
|
144 |
ulong m = link_no ( bs, n, VAR_token ) ;
|
|
|
145 |
ENC_shape_apply_token ( bs ) ;
|
|
|
146 |
ENC_make_tok ( bs, m ) ;
|
|
|
147 |
ENC_LEN_SMALL ( bs, 0 ) ;
|
|
|
148 |
return ( bs ) ;
|
|
|
149 |
}
|
|
|
150 |
|
|
|
151 |
|
|
|
152 |
/*
|
|
|
153 |
VIRTUAL FUNCTION TABLE ROUTINES
|
|
|
154 |
|
|
|
155 |
The virtual function table and run-time type information routines are
|
|
|
156 |
only included in the C++ producer.
|
|
|
157 |
*/
|
|
|
158 |
|
|
|
159 |
#if LANGUAGE_CPP
|
|
|
160 |
|
|
|
161 |
|
|
|
162 |
/*
|
|
|
163 |
ENCODE A BUFFER AS A STRING LITERAL
|
|
|
164 |
|
|
|
165 |
This routine adds the contents of the buffer bf to the bitstream bs
|
|
|
166 |
as a string literal.
|
|
|
167 |
*/
|
|
|
168 |
|
|
|
169 |
static BITSTREAM *enc_buffer
|
|
|
170 |
PROTO_N ( ( bs, bf ) )
|
|
|
171 |
PROTO_T ( BITSTREAM *bs X BUFFER *bf )
|
|
|
172 |
{
|
|
|
173 |
string s = bf->start ;
|
|
|
174 |
unsigned long n = ( unsigned long ) ( bf->posn - s ) ;
|
|
|
175 |
|
|
|
176 |
/* Declare the string literal */
|
|
|
177 |
ulong m = capsule_no ( NULL_string, VAR_tag ) ;
|
|
|
178 |
BITSTREAM *ts = enc_tagdec_start ( NULL_id, m, NULL_type, 1 ) ;
|
|
|
179 |
ENC_nof ( ts ) ;
|
|
|
180 |
ENC_make_nat ( ts ) ;
|
|
|
181 |
ENC_INT ( ts, n ) ;
|
|
|
182 |
ts = enc_shape ( ts, type_char ) ;
|
|
|
183 |
enc_tagdec_end ( ts ) ;
|
|
|
184 |
|
|
|
185 |
/* Define the string literal */
|
|
|
186 |
ts = enc_tagdef_start ( NULL_id, m, NULL_type, 1 ) ;
|
|
|
187 |
ENC_make_nof_int ( ts ) ;
|
|
|
188 |
ts = enc_variety ( ts, type_char ) ;
|
|
|
189 |
ENC_make_string ( ts ) ;
|
|
|
190 |
ts = enc_tdfstring ( ts, n, s ) ;
|
|
|
191 |
enc_tagdef_end ( ts ) ;
|
|
|
192 |
|
|
|
193 |
/* Encode the result */
|
|
|
194 |
m = link_no ( bs, m, VAR_tag ) ;
|
|
|
195 |
ENC_obtain_tag ( bs ) ;
|
|
|
196 |
ENC_make_tag ( bs, m ) ;
|
|
|
197 |
return ( bs ) ;
|
|
|
198 |
}
|
|
|
199 |
|
|
|
200 |
|
|
|
201 |
/*
|
|
|
202 |
ENCODE RUN-TIME BASE CLASS INFORMATION
|
|
|
203 |
|
|
|
204 |
This routine defines the run-time base class information for the base
|
|
|
205 |
classes br or the sub-types pt and adds the address of the first base
|
|
|
206 |
to bs.
|
|
|
207 |
*/
|
|
|
208 |
|
|
|
209 |
static BITSTREAM *enc_rtti_bases
|
|
|
210 |
PROTO_N ( ( bs, br, pt, sz ) )
|
|
|
211 |
PROTO_T ( BITSTREAM *bs X LIST ( GRAPH ) br X LIST ( TYPE ) pt X NAT sz )
|
|
|
212 |
{
|
|
|
213 |
TYPE t ;
|
|
|
214 |
ulong n, m ;
|
|
|
215 |
BITSTREAM *ts, *us ;
|
|
|
216 |
int a = INFO_public ;
|
|
|
217 |
|
|
|
218 |
if ( !IS_NULL_list ( br ) ) {
|
|
|
219 |
/* Get base class information */
|
|
|
220 |
VIRTUAL vt ;
|
|
|
221 |
CLASS_TYPE ct ;
|
|
|
222 |
GRAPH gr = DEREF_graph ( HEAD_list ( br ) ) ;
|
|
|
223 |
DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
|
|
|
224 |
br = TAIL_list ( br ) ;
|
|
|
225 |
|
|
|
226 |
/* Find base class information */
|
|
|
227 |
ct = DEREF_ctype ( graph_head ( gr ) ) ;
|
|
|
228 |
t = make_class_type ( ct ) ;
|
|
|
229 |
vt = DEREF_virt ( ctype_virt ( ct ) ) ;
|
|
|
230 |
if ( !IS_NULL_virt ( vt ) ) {
|
|
|
231 |
/* Make sure base class is declared */
|
|
|
232 |
int used = DEREF_int ( virt_table_rtti_used ( vt ) ) ;
|
|
|
233 |
if ( !used ) {
|
|
|
234 |
IDENTIFIER cid = DEREF_id ( ctype_name ( ct ) ) ;
|
|
|
235 |
COPY_int ( virt_table_rtti_used ( vt ), 1 ) ;
|
|
|
236 |
compile_virtual ( ct, !has_linkage ( cid ) ) ;
|
|
|
237 |
}
|
|
|
238 |
}
|
|
|
239 |
if ( acc & dspec_virtual ) sz = small_nat [1] ;
|
|
|
240 |
acc &= dspec_access ;
|
|
|
241 |
if ( acc == dspec_protected ) {
|
|
|
242 |
a = INFO_protected ;
|
|
|
243 |
} else if ( acc == dspec_private ) {
|
|
|
244 |
a = INFO_private ;
|
|
|
245 |
}
|
|
|
246 |
m = DEREF_ulong ( graph_base_off ( gr ) ) ;
|
|
|
247 |
|
|
|
248 |
} else if ( !IS_NULL_list ( pt ) ) {
|
|
|
249 |
/* Get sub-type information */
|
|
|
250 |
t = DEREF_type ( HEAD_list ( pt ) ) ;
|
|
|
251 |
pt = TAIL_list ( pt ) ;
|
|
|
252 |
if ( !IS_NULL_type ( t ) ) {
|
|
|
253 |
CV_SPEC cv = DEREF_cv ( type_qual ( t ) ) ;
|
|
|
254 |
if ( IS_type_func ( t ) ) {
|
|
|
255 |
/* Allow for function qualifiers */
|
|
|
256 |
cv = DEREF_cv ( type_func_mqual ( t ) ) ;
|
|
|
257 |
}
|
|
|
258 |
if ( cv ) {
|
|
|
259 |
if ( cv & cv_const ) a |= INFO_const ;
|
|
|
260 |
if ( cv & cv_volatile ) a |= INFO_volatile ;
|
|
|
261 |
t = qualify_type ( t, cv_none, 0 ) ;
|
|
|
262 |
}
|
|
|
263 |
}
|
|
|
264 |
m = LINK_NONE ;
|
|
|
265 |
|
|
|
266 |
} else {
|
|
|
267 |
/* Output end of list */
|
|
|
268 |
ENC_make_null_ptr ( bs ) ;
|
|
|
269 |
ENC_alignment ( bs ) ;
|
|
|
270 |
bs = enc_special ( bs, TOK_baseid_type ) ;
|
|
|
271 |
return ( bs ) ;
|
|
|
272 |
}
|
|
|
273 |
|
|
|
274 |
/* Declare base structure */
|
|
|
275 |
n = capsule_no ( NULL_string, VAR_tag ) ;
|
|
|
276 |
ts = enc_tagdec_start ( NULL_id, n, NULL_type, 1 ) ;
|
|
|
277 |
ts = enc_special ( ts, TOK_baseid_type ) ;
|
|
|
278 |
enc_tagdec_end ( ts ) ;
|
|
|
279 |
|
|
|
280 |
/* Define base structure */
|
|
|
281 |
ts = enc_tagdef_start ( NULL_id, n, NULL_type, 1 ) ;
|
|
|
282 |
ts = enc_special ( ts, TOK_baseid_make ) ;
|
|
|
283 |
us = start_bitstream ( NIL ( FILE ), ts->link ) ;
|
|
|
284 |
us = enc_rtti_type ( us, t, lex_typeid ) ;
|
|
|
285 |
if ( m == LINK_NONE ) {
|
|
|
286 |
ENC_offset_zero ( us ) ;
|
|
|
287 |
us = enc_alignment ( us, type_sint ) ;
|
|
|
288 |
} else {
|
|
|
289 |
us = enc_exp_token ( us, m ) ;
|
|
|
290 |
}
|
|
|
291 |
us = enc_rtti_bases ( us, br, pt, NULL_nat ) ;
|
|
|
292 |
us = enc_make_snat ( us, a ) ;
|
|
|
293 |
us = enc_snat ( us, sz, 0, 0 ) ;
|
|
|
294 |
ts = enc_bitstream ( ts, us ) ;
|
|
|
295 |
enc_tagdef_end ( ts ) ;
|
|
|
296 |
|
|
|
297 |
/* Encode the result */
|
|
|
298 |
n = link_no ( bs, n, VAR_tag ) ;
|
|
|
299 |
ENC_obtain_tag ( bs ) ;
|
|
|
300 |
ENC_make_tag ( bs, n ) ;
|
|
|
301 |
return ( bs ) ;
|
|
|
302 |
}
|
|
|
303 |
|
|
|
304 |
|
|
|
305 |
/*
|
|
|
306 |
ENCODE A RUN-TIME TYPE INFORMATION STRUCTURE
|
|
|
307 |
|
|
|
308 |
This routine defines the tag n to be the run-time type information
|
|
|
309 |
structure for the type t. If def is false then only the declaration
|
|
|
310 |
is output.
|
|
|
311 |
*/
|
|
|
312 |
|
|
|
313 |
static void enc_rtti_struct
|
|
|
314 |
PROTO_N ( ( t, n, def ) )
|
|
|
315 |
PROTO_T ( TYPE t X ulong n X int def )
|
|
|
316 |
{
|
|
|
317 |
unsigned acc = find_usage ( n, VAR_tag ) ;
|
|
|
318 |
if ( !( acc & USAGE_DECL ) ) {
|
|
|
319 |
BITSTREAM *bs = enc_tagdec_start ( NULL_id, n, NULL_type, 1 ) ;
|
|
|
320 |
bs = enc_special ( bs, TOK_typeid_type ) ;
|
|
|
321 |
enc_tagdec_end ( bs ) ;
|
|
|
322 |
}
|
|
|
323 |
if ( def && !( acc & USAGE_DEFN ) ) {
|
|
|
324 |
int c = RTTI_void ;
|
|
|
325 |
NAT sz = NULL_nat ;
|
|
|
326 |
BITSTREAM *bs, *ts ;
|
|
|
327 |
LIST ( TYPE ) p = NULL_list ( TYPE ) ;
|
|
|
328 |
LIST ( GRAPH ) br = NULL_list ( GRAPH ) ;
|
|
|
329 |
BUFFER *bf = clear_buffer ( &print_buff, NIL ( FILE ) ) ;
|
|
|
330 |
print_uniq_anon++ ;
|
|
|
331 |
IGNORE print_type ( t, bf, 0 ) ;
|
|
|
332 |
print_uniq_anon-- ;
|
|
|
333 |
bfputc ( bf, 0 ) ;
|
|
|
334 |
switch ( TAG_type ( t ) ) {
|
|
|
335 |
case type_integer_tag : {
|
|
|
336 |
/* Integral types */
|
|
|
337 |
c = RTTI_integer ;
|
|
|
338 |
break ;
|
|
|
339 |
}
|
|
|
340 |
case type_floating_tag : {
|
|
|
341 |
/* Floating-point types */
|
|
|
342 |
c = RTTI_float ;
|
|
|
343 |
break ;
|
|
|
344 |
}
|
|
|
345 |
case type_ptr_tag : {
|
|
|
346 |
/* Pointer types */
|
|
|
347 |
TYPE s = DEREF_type ( type_ptr_sub ( t ) ) ;
|
|
|
348 |
CONS_type ( s, p, p ) ;
|
|
|
349 |
c = RTTI_ptr ;
|
|
|
350 |
break ;
|
|
|
351 |
}
|
|
|
352 |
case type_ref_tag : {
|
|
|
353 |
/* Reference types */
|
|
|
354 |
TYPE s = DEREF_type ( type_ref_sub ( t ) ) ;
|
|
|
355 |
CONS_type ( s, p, p ) ;
|
|
|
356 |
c = RTTI_ref ;
|
|
|
357 |
break ;
|
|
|
358 |
}
|
|
|
359 |
case type_ptr_mem_tag : {
|
|
|
360 |
/* Pointer to member types */
|
|
|
361 |
TYPE s = DEREF_type ( type_ptr_mem_sub ( t ) ) ;
|
|
|
362 |
CLASS_TYPE cs = DEREF_ctype ( type_ptr_mem_of ( t ) ) ;
|
|
|
363 |
CONS_type ( s, p, p ) ;
|
|
|
364 |
s = make_class_type ( cs ) ;
|
|
|
365 |
CONS_type ( s, p, p ) ;
|
|
|
366 |
c = RTTI_ptr_mem ;
|
|
|
367 |
break ;
|
|
|
368 |
}
|
|
|
369 |
case type_func_tag : {
|
|
|
370 |
/* Function types */
|
|
|
371 |
TYPE s = DEREF_type ( type_func_ret ( t ) ) ;
|
|
|
372 |
CV_SPEC mq = DEREF_cv ( type_func_mqual ( t ) ) ;
|
|
|
373 |
int ell = DEREF_int ( type_func_ellipsis ( t ) ) ;
|
|
|
374 |
LIST ( TYPE ) q = DEREF_list ( type_func_ptypes ( t ) ) ;
|
|
|
375 |
CONS_type ( s, p, p ) ;
|
|
|
376 |
while ( !IS_NULL_list ( q ) ) {
|
|
|
377 |
s = DEREF_type ( HEAD_list ( q ) ) ;
|
|
|
378 |
CONS_type ( s, p, p ) ;
|
|
|
379 |
q = TAIL_list ( q ) ;
|
|
|
380 |
}
|
|
|
381 |
if ( ell & FUNC_ELLIPSIS ) {
|
|
|
382 |
CONS_type ( type_any, p, p ) ;
|
|
|
383 |
}
|
|
|
384 |
p = REVERSE_list ( p ) ;
|
|
|
385 |
if ( mq & cv_c ) {
|
|
|
386 |
c = RTTI_c_func ;
|
|
|
387 |
} else {
|
|
|
388 |
c = RTTI_func ;
|
|
|
389 |
}
|
|
|
390 |
break ;
|
|
|
391 |
}
|
|
|
392 |
case type_array_tag : {
|
|
|
393 |
/* Array types */
|
|
|
394 |
TYPE s = DEREF_type ( type_array_sub ( t ) ) ;
|
|
|
395 |
CONS_type ( s, p, p ) ;
|
|
|
396 |
sz = DEREF_nat ( type_array_size ( t ) ) ;
|
|
|
397 |
c = RTTI_array ;
|
|
|
398 |
break ;
|
|
|
399 |
}
|
|
|
400 |
case type_bitfield_tag : {
|
|
|
401 |
/* Bitfield types */
|
|
|
402 |
INT_TYPE it = DEREF_itype ( type_bitfield_defn ( t ) ) ;
|
|
|
403 |
TYPE s = DEREF_type ( itype_bitfield_sub ( it ) ) ;
|
|
|
404 |
CONS_type ( s, p, p ) ;
|
|
|
405 |
sz = DEREF_nat ( itype_bitfield_size ( it ) ) ;
|
|
|
406 |
c = RTTI_bitfield ;
|
|
|
407 |
break ;
|
|
|
408 |
}
|
|
|
409 |
case type_compound_tag : {
|
|
|
410 |
/* Class types */
|
|
|
411 |
CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
|
|
|
412 |
CLASS_INFO ci = DEREF_cinfo ( ctype_info ( ct ) ) ;
|
|
|
413 |
GRAPH gr = DEREF_graph ( ctype_base ( ct ) ) ;
|
|
|
414 |
br = DEREF_list ( graph_tails ( gr ) ) ;
|
|
|
415 |
if ( ci & cinfo_union ) {
|
|
|
416 |
c = RTTI_union ;
|
|
|
417 |
} else {
|
|
|
418 |
c = RTTI_class ;
|
|
|
419 |
}
|
|
|
420 |
break ;
|
|
|
421 |
}
|
|
|
422 |
case type_enumerate_tag : {
|
|
|
423 |
/* Enumeration types */
|
|
|
424 |
c = RTTI_enum ;
|
|
|
425 |
break ;
|
|
|
426 |
}
|
|
|
427 |
}
|
|
|
428 |
bs = enc_tagdef_start ( NULL_id, n, NULL_type, 1 ) ;
|
|
|
429 |
bs = enc_special ( bs, TOK_typeid_make ) ;
|
|
|
430 |
ts = start_bitstream ( NIL ( FILE ), bs->link ) ;
|
|
|
431 |
ts = enc_make_snat ( ts, c ) ;
|
|
|
432 |
ts = enc_buffer ( ts, bf ) ;
|
|
|
433 |
ts = enc_rtti_bases ( ts, br, p, sz ) ;
|
|
|
434 |
DESTROY_list ( p, SIZE_type ) ;
|
|
|
435 |
bs = enc_bitstream ( bs, ts ) ;
|
|
|
436 |
enc_tagdef_end ( bs ) ;
|
|
|
437 |
}
|
|
|
438 |
return ;
|
|
|
439 |
}
|
|
|
440 |
|
|
|
441 |
|
|
|
442 |
/*
|
|
|
443 |
LIST OF RUN-TIME TYPE INFORMATION STRUCTURES
|
|
|
444 |
|
|
|
445 |
These lists gives the tag numbers for the various type information
|
|
|
446 |
structures output. Polymorphic classes, which form the most common
|
|
|
447 |
such types, are dealt with separately as part of the virtual function
|
|
|
448 |
table.
|
|
|
449 |
*/
|
|
|
450 |
|
|
|
451 |
static LIST ( TYPE ) rtti_types = NULL_list ( TYPE ) ;
|
|
|
452 |
static LIST ( ulong ) rtti_tags = NULL_list ( ulong ) ;
|
|
|
453 |
|
|
|
454 |
|
|
|
455 |
/*
|
|
|
456 |
ENCODE THE RUN-TIME TYPE INFORMATION FOR A TYPE
|
|
|
457 |
|
|
|
458 |
This routine adds a reference to the run-time type information
|
|
|
459 |
structure for the type t to the bitstream bs, defining this if
|
|
|
460 |
necessary.
|
|
|
461 |
*/
|
|
|
462 |
|
|
|
463 |
BITSTREAM *enc_rtti_type
|
|
|
464 |
PROTO_N ( ( bs, t, op ) )
|
|
|
465 |
PROTO_T ( BITSTREAM *bs X TYPE t X int op )
|
|
|
466 |
{
|
|
|
467 |
ulong n = LINK_NONE ;
|
|
|
468 |
if ( IS_NULL_type ( t ) ) {
|
|
|
469 |
/* Map null type to null pointer */
|
|
|
470 |
ENC_make_null_ptr ( bs ) ;
|
|
|
471 |
ENC_alignment ( bs ) ;
|
|
|
472 |
bs = enc_special ( bs, TOK_typeid_type ) ;
|
|
|
473 |
return ( bs ) ;
|
|
|
474 |
}
|
|
|
475 |
if ( op == lex_typeid && !output_rtti ) {
|
|
|
476 |
/* Use dummy type if RTTI suppressed */
|
|
|
477 |
t = type_error ;
|
|
|
478 |
}
|
|
|
479 |
switch ( TAG_type ( t ) ) {
|
|
|
480 |
case type_top_tag :
|
|
|
481 |
case type_bottom_tag :
|
|
|
482 |
case type_integer_tag :
|
|
|
483 |
case type_floating_tag :
|
|
|
484 |
case type_pre_tag :
|
|
|
485 |
case type_error_tag : {
|
|
|
486 |
/* Built-in types */
|
|
|
487 |
BITSTREAM *ts ;
|
|
|
488 |
bs = enc_special ( bs, TOK_typeid_basic ) ;
|
|
|
489 |
ts = start_bitstream ( NIL ( FILE ), bs->link ) ;
|
|
|
490 |
ts = enc_arith ( ts, t, 1 ) ;
|
|
|
491 |
bs = enc_bitstream ( bs, ts ) ;
|
|
|
492 |
return ( bs ) ;
|
|
|
493 |
}
|
|
|
494 |
case type_compound_tag : {
|
|
|
495 |
/* Class types */
|
|
|
496 |
CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
|
|
|
497 |
CLASS_INFO ci = DEREF_cinfo ( ctype_info ( ct ) ) ;
|
|
|
498 |
if ( ci & cinfo_polymorphic ) {
|
|
|
499 |
/* Polymorphic class types */
|
|
|
500 |
int used ;
|
|
|
501 |
VIRTUAL vt = DEREF_virt ( ctype_virt ( ct ) ) ;
|
|
|
502 |
n = DEREF_ulong ( virt_table_rtti ( vt ) ) ;
|
|
|
503 |
if ( n == LINK_NONE ) {
|
|
|
504 |
IGNORE compile_class ( ct ) ;
|
|
|
505 |
n = DEREF_ulong ( virt_table_rtti ( vt ) ) ;
|
|
|
506 |
}
|
|
|
507 |
used = DEREF_int ( virt_table_rtti_used ( vt ) ) ;
|
|
|
508 |
if ( !used ) {
|
|
|
509 |
IDENTIFIER cid = DEREF_id ( ctype_name ( ct ) ) ;
|
|
|
510 |
COPY_int ( virt_table_rtti_used ( vt ), 1 ) ;
|
|
|
511 |
compile_virtual ( ct, !has_linkage ( cid ) ) ;
|
|
|
512 |
}
|
|
|
513 |
if ( op == lex_vtable ) {
|
|
|
514 |
/* Deal with virtual function tables */
|
|
|
515 |
/* NOT YET IMPLEMENTED */
|
|
|
516 |
n = DEREF_ulong ( virt_table_tbl ( vt ) ) ;
|
|
|
517 |
n = link_no ( bs, n, VAR_tag ) ;
|
|
|
518 |
ENC_obtain_tag ( bs ) ;
|
|
|
519 |
ENC_make_tag ( bs, n ) ;
|
|
|
520 |
return ( bs ) ;
|
|
|
521 |
}
|
|
|
522 |
} else {
|
|
|
523 |
IGNORE compile_class ( ct ) ;
|
|
|
524 |
}
|
|
|
525 |
break ;
|
|
|
526 |
}
|
|
|
527 |
}
|
|
|
528 |
if ( n == LINK_NONE ) {
|
|
|
529 |
/* Check for previous definition */
|
|
|
530 |
LIST ( TYPE ) p = rtti_types ;
|
|
|
531 |
LIST ( ulong ) q = rtti_tags ;
|
|
|
532 |
while ( !IS_NULL_list ( p ) ) {
|
|
|
533 |
TYPE s = DEREF_type ( HEAD_list ( p ) ) ;
|
|
|
534 |
if ( eq_type ( s, t ) ) {
|
|
|
535 |
n = DEREF_ulong ( HEAD_list ( q ) ) ;
|
|
|
536 |
break ;
|
|
|
537 |
}
|
|
|
538 |
q = TAIL_list ( q ) ;
|
|
|
539 |
p = TAIL_list ( p ) ;
|
|
|
540 |
}
|
|
|
541 |
if ( n == LINK_NONE ) {
|
|
|
542 |
/* Define a new structure */
|
|
|
543 |
string s = NULL ;
|
|
|
544 |
if ( output_all ) s = mangle_tname ( "__ti__", t ) ;
|
|
|
545 |
n = capsule_no ( s, VAR_tag ) ;
|
|
|
546 |
CONS_type ( t, rtti_types, rtti_types ) ;
|
|
|
547 |
CONS_ulong ( n, rtti_tags, rtti_tags ) ;
|
|
|
548 |
enc_rtti_struct ( t, n, 1 ) ;
|
|
|
549 |
}
|
|
|
550 |
}
|
|
|
551 |
n = link_no ( bs, n, VAR_tag ) ;
|
|
|
552 |
ENC_obtain_tag ( bs ) ;
|
|
|
553 |
ENC_make_tag ( bs, n ) ;
|
|
|
554 |
return ( bs ) ;
|
|
|
555 |
}
|
|
|
556 |
|
|
|
557 |
|
|
|
558 |
/*
|
|
|
559 |
ENCODE THE RUN-TIME TYPE INFORMATION FOR AN EXPRESSION
|
|
|
560 |
|
|
|
561 |
This routine adds the run-time type information expression e to
|
|
|
562 |
the bitstream bs.
|
|
|
563 |
*/
|
|
|
564 |
|
|
|
565 |
BITSTREAM *enc_rtti_exp
|
|
|
566 |
PROTO_N ( ( bs, e ) )
|
|
|
567 |
PROTO_T ( BITSTREAM *bs X EXP e )
|
|
|
568 |
{
|
|
|
569 |
EXP a = DEREF_exp ( exp_rtti_arg ( e ) ) ;
|
|
|
570 |
EXP b = DEREF_exp ( exp_rtti_except ( e ) ) ;
|
|
|
571 |
int op = DEREF_int ( exp_rtti_op ( e ) ) ;
|
|
|
572 |
TYPE t = DEREF_type ( exp_type ( a ) ) ;
|
|
|
573 |
if ( IS_type_ptr_etc ( t ) ) {
|
|
|
574 |
TYPE s = DEREF_type ( type_ptr_etc_sub ( t ) ) ;
|
|
|
575 |
if ( IS_type_compound ( s ) ) {
|
|
|
576 |
CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( s ) ) ;
|
|
|
577 |
VIRTUAL vt = DEREF_virt ( ctype_virt ( ct ) ) ;
|
|
|
578 |
if ( !IS_NULL_virt ( vt ) ) {
|
|
|
579 |
/* Pointer to polymorphic class */
|
|
|
580 |
EXP a1 ;
|
|
|
581 |
int used ;
|
|
|
582 |
OFFSET off ;
|
|
|
583 |
ulong n, m ;
|
|
|
584 |
BITSTREAM *ts ;
|
|
|
585 |
IGNORE compile_class ( ct ) ;
|
|
|
586 |
off = DEREF_off ( virt_table_off ( vt ) ) ;
|
|
|
587 |
n = DEREF_ulong ( virt_table_tok ( vt ) ) ;
|
|
|
588 |
|
|
|
589 |
/* Introduce variable for pointer */
|
|
|
590 |
a1 = DEREF_exp ( exp_dummy_value ( a ) ) ;
|
|
|
591 |
m = unit_no ( bs, NULL_id, VAR_tag, 1 ) ;
|
|
|
592 |
ENC_variable ( bs ) ;
|
|
|
593 |
bs = enc_access ( bs, crt_func_access ) ;
|
|
|
594 |
ENC_make_tag ( bs, m ) ;
|
|
|
595 |
bs = enc_exp ( bs, a ) ;
|
|
|
596 |
COPY_ulong ( exp_dummy_no ( a ), m ) ;
|
|
|
597 |
COPY_exp ( exp_dummy_value ( a ), NULL_exp ) ;
|
|
|
598 |
|
|
|
599 |
/* Check for null pointers */
|
|
|
600 |
if ( !IS_NULL_exp ( b ) ) {
|
|
|
601 |
ulong lab = unit_no ( bs, NULL_id, VAR_label, 1 ) ;
|
|
|
602 |
ENC_SEQ_SMALL ( bs, 1 ) ;
|
|
|
603 |
ENC_conditional ( bs ) ;
|
|
|
604 |
ENC_make_label ( bs, lab ) ;
|
|
|
605 |
ENC_SEQ_SMALL ( bs, 1 ) ;
|
|
|
606 |
ENC_pointer_test ( bs ) ;
|
|
|
607 |
ENC_OFF ( bs ) ;
|
|
|
608 |
ENC_equal ( bs ) ;
|
|
|
609 |
ENC_make_label ( bs, lab ) ;
|
|
|
610 |
bs = enc_exp ( bs, a ) ;
|
|
|
611 |
bs = enc_null_exp ( bs, t ) ;
|
|
|
612 |
bs = enc_exp ( bs, b ) ;
|
|
|
613 |
ENC_make_top ( bs ) ;
|
|
|
614 |
}
|
|
|
615 |
|
|
|
616 |
/* Find the run-time type information */
|
|
|
617 |
ts = start_bitstream ( NIL ( FILE ), bs->link ) ;
|
|
|
618 |
if ( op == lex_typeid ) {
|
|
|
619 |
bs = enc_special ( bs, TOK_typeid_ref ) ;
|
|
|
620 |
} else {
|
|
|
621 |
bs = enc_special ( bs, TOK_vtab_func ) ;
|
|
|
622 |
}
|
|
|
623 |
ENC_add_to_ptr ( ts ) ;
|
|
|
624 |
ts = enc_add_ptr ( ts, a, LINK_NONE, off, 0 ) ;
|
|
|
625 |
ts = enc_exp_token ( ts, n ) ;
|
|
|
626 |
if ( op != lex_typeid ) {
|
|
|
627 |
ENC_make_signed_nat ( ts ) ;
|
|
|
628 |
ENC_OFF ( ts ) ;
|
|
|
629 |
ENC_INT_SMALL ( ts, 0 ) ;
|
|
|
630 |
}
|
|
|
631 |
bs = enc_bitstream ( bs, ts ) ;
|
|
|
632 |
used = DEREF_int ( virt_table_rtti_used ( vt ) ) ;
|
|
|
633 |
if ( !used ) {
|
|
|
634 |
IDENTIFIER cid = DEREF_id ( ctype_name ( ct ) ) ;
|
|
|
635 |
COPY_int ( virt_table_rtti_used ( vt ), 1 ) ;
|
|
|
636 |
compile_virtual ( ct, !has_linkage ( cid ) ) ;
|
|
|
637 |
}
|
|
|
638 |
COPY_exp ( exp_dummy_value ( a ), a1 ) ;
|
|
|
639 |
return ( bs ) ;
|
|
|
640 |
}
|
|
|
641 |
}
|
|
|
642 |
}
|
|
|
643 |
bs = enc_rtti_type ( bs, t, op ) ;
|
|
|
644 |
return ( bs ) ;
|
|
|
645 |
}
|
|
|
646 |
|
|
|
647 |
|
|
|
648 |
/*
|
|
|
649 |
ENCODE A DYNAMIC CAST EXPRESSION
|
|
|
650 |
|
|
|
651 |
This routine adds the dynamic cast expression e to the bitstream bs.
|
|
|
652 |
*/
|
|
|
653 |
|
|
|
654 |
BITSTREAM *enc_dyn_cast
|
|
|
655 |
PROTO_N ( ( bs, e ) )
|
|
|
656 |
PROTO_T ( BITSTREAM *bs X EXP e )
|
|
|
657 |
{
|
|
|
658 |
ulong m ;
|
|
|
659 |
int used ;
|
|
|
660 |
OFFSET off ;
|
|
|
661 |
VIRTUAL vt ;
|
|
|
662 |
CLASS_TYPE ct ;
|
|
|
663 |
BITSTREAM *ts, *us ;
|
|
|
664 |
ulong r = LINK_NONE ;
|
|
|
665 |
TYPE t = DEREF_type ( exp_type ( e ) ) ;
|
|
|
666 |
EXP a = DEREF_exp ( exp_dyn_cast_arg ( e ) ) ;
|
|
|
667 |
TYPE s = DEREF_type ( exp_type ( a ) ) ;
|
|
|
668 |
EXP a1 = DEREF_exp ( exp_dummy_value ( a ) ) ;
|
|
|
669 |
EXP b = DEREF_exp ( exp_dyn_cast_except ( e ) ) ;
|
|
|
670 |
|
|
|
671 |
/* Introduce identity for argument */
|
|
|
672 |
ulong n = unit_no ( bs, NULL_id, VAR_tag, 1 ) ;
|
|
|
673 |
ENC_identify ( bs ) ;
|
|
|
674 |
bs = enc_access ( bs, dspec_none ) ;
|
|
|
675 |
ENC_make_tag ( bs, n ) ;
|
|
|
676 |
bs = enc_exp ( bs, a1 ) ;
|
|
|
677 |
COPY_exp ( exp_dummy_value ( a ), NULL_exp ) ;
|
|
|
678 |
COPY_ulong ( exp_dummy_no ( a ), n ) ;
|
|
|
679 |
|
|
|
680 |
/* Convert to result type */
|
|
|
681 |
bs = enc_special ( bs, TOK_from_ptr_void ) ;
|
|
|
682 |
ts = start_bitstream ( NIL ( FILE ), bs->link ) ;
|
|
|
683 |
t = DEREF_type ( type_ptr_etc_sub ( t ) ) ;
|
|
|
684 |
ts = enc_alignment ( ts, t ) ;
|
|
|
685 |
|
|
|
686 |
/* Introduce variable in exception case */
|
|
|
687 |
if ( !IS_NULL_exp ( b ) ) {
|
|
|
688 |
r = unit_no ( ts, NULL_id, VAR_tag, 1 ) ;
|
|
|
689 |
ENC_variable ( ts ) ;
|
|
|
690 |
ts = enc_access ( ts, crt_func_access ) ;
|
|
|
691 |
ENC_make_tag ( ts, r ) ;
|
|
|
692 |
}
|
|
|
693 |
|
|
|
694 |
/* Encode main token */
|
|
|
695 |
ts = enc_special ( ts, TOK_dynam_cast ) ;
|
|
|
696 |
us = start_bitstream ( NIL ( FILE ), ts->link ) ;
|
|
|
697 |
|
|
|
698 |
/* Encode address of virtual function table */
|
|
|
699 |
s = DEREF_type ( type_ptr_etc_sub ( s ) ) ;
|
|
|
700 |
ct = DEREF_ctype ( type_compound_defn ( s ) ) ;
|
|
|
701 |
IGNORE compile_class ( ct ) ;
|
|
|
702 |
vt = DEREF_virt ( ctype_virt ( ct ) ) ;
|
|
|
703 |
off = DEREF_off ( virt_table_off ( vt ) ) ;
|
|
|
704 |
m = DEREF_ulong ( virt_table_tok ( vt ) ) ;
|
|
|
705 |
ENC_add_to_ptr ( us ) ;
|
|
|
706 |
us = enc_add_ptr ( us, a, LINK_NONE, off, 0 ) ;
|
|
|
707 |
us = enc_exp_token ( us, m ) ;
|
|
|
708 |
used = DEREF_int ( virt_table_rtti_used ( vt ) ) ;
|
|
|
709 |
if ( !used ) {
|
|
|
710 |
IDENTIFIER cid = DEREF_id ( ctype_name ( ct ) ) ;
|
|
|
711 |
COPY_int ( virt_table_rtti_used ( vt ), 1 ) ;
|
|
|
712 |
compile_virtual ( ct, !has_linkage ( cid ) ) ;
|
|
|
713 |
}
|
|
|
714 |
|
|
|
715 |
/* Output run-time type information */
|
|
|
716 |
us = enc_rtti_type ( us, t, lex_typeid ) ;
|
|
|
717 |
ts = enc_bitstream ( ts, us ) ;
|
|
|
718 |
|
|
|
719 |
/* Check for exceptions */
|
|
|
720 |
if ( !IS_NULL_exp ( b ) ) {
|
|
|
721 |
ulong lab = unit_no ( ts, NULL_id, VAR_label, 1 ) ;
|
|
|
722 |
ENC_SEQ_SMALL ( ts, 1 ) ;
|
|
|
723 |
ENC_conditional ( ts ) ;
|
|
|
724 |
ENC_make_label ( ts, lab ) ;
|
|
|
725 |
ENC_SEQ_SMALL ( ts, 1 ) ;
|
|
|
726 |
ts = enc_special ( ts, TOK_pv_test ) ;
|
|
|
727 |
us = start_bitstream ( NIL ( FILE ), ts->link ) ;
|
|
|
728 |
ENC_contents ( us ) ;
|
|
|
729 |
us = enc_special ( us, TOK_ptr_void ) ;
|
|
|
730 |
ENC_obtain_tag ( us ) ;
|
|
|
731 |
ENC_make_tag ( us, r ) ;
|
|
|
732 |
ENC_make_label ( us, lab ) ;
|
|
|
733 |
ENC_equal ( us ) ;
|
|
|
734 |
ts = enc_bitstream ( ts, us ) ;
|
|
|
735 |
ts = enc_exp ( ts, b ) ;
|
|
|
736 |
ENC_make_top ( ts ) ;
|
|
|
737 |
ENC_contents ( ts ) ;
|
|
|
738 |
ts = enc_special ( ts, TOK_ptr_void ) ;
|
|
|
739 |
ENC_obtain_tag ( ts ) ;
|
|
|
740 |
ENC_make_tag ( ts, r ) ;
|
|
|
741 |
}
|
|
|
742 |
|
|
|
743 |
/* End conversion expression */
|
|
|
744 |
bs = enc_bitstream ( bs, ts ) ;
|
|
|
745 |
COPY_exp ( exp_dummy_value ( a ), a1 ) ;
|
|
|
746 |
return ( bs ) ;
|
|
|
747 |
}
|
|
|
748 |
|
|
|
749 |
|
|
|
750 |
/*
|
|
|
751 |
LIST OF PREVIOUSLY DEFINED THUNKS
|
|
|
752 |
|
|
|
753 |
A list of all previously defined thunks is maintained to avoid
|
|
|
754 |
unnecessary duplication.
|
|
|
755 |
*/
|
|
|
756 |
|
|
|
757 |
static VIRTUAL all_thunks = NULL_virt ;
|
|
|
758 |
|
|
|
759 |
|
|
|
760 |
/*
|
|
|
761 |
CREATE A THUNK FUNCTION
|
|
|
762 |
|
|
|
763 |
This routine creates a dummy function of type f which calls fid with
|
|
|
764 |
its given arguments and returns its result with the base class conversion
|
|
|
765 |
given by ret applied. The tag number of the dummy function is returned.
|
|
|
766 |
This is used for overriding virtual functions in which the return
|
|
|
767 |
type differs.
|
|
|
768 |
*/
|
|
|
769 |
|
|
|
770 |
static ulong make_thunk
|
|
|
771 |
PROTO_N ( ( f, fid, ret ) )
|
|
|
772 |
PROTO_T ( TYPE f X IDENTIFIER fid X GRAPH ret )
|
|
|
773 |
{
|
|
|
774 |
ulong n ;
|
|
|
775 |
DECL_SPEC acc = DEREF_dspec ( graph_access ( ret ) ) ;
|
|
|
776 |
IGNORE capsule_id ( fid, VAR_tag ) ;
|
|
|
777 |
if ( acc & dspec_ignore ) {
|
|
|
778 |
/* Use fid for trivial conversions */
|
|
|
779 |
n = DEREF_ulong ( id_no ( fid ) ) ;
|
|
|
780 |
|
|
|
781 |
} else {
|
|
|
782 |
EXP e ;
|
|
|
783 |
int ell ;
|
|
|
784 |
TYPE f2 ;
|
|
|
785 |
OFFSET off ;
|
|
|
786 |
unsigned np ;
|
|
|
787 |
TYPE r1, r2 ;
|
|
|
788 |
ulong rn, pn ;
|
|
|
789 |
LIST ( TYPE ) p ;
|
|
|
790 |
BITSTREAM *bs, *ts ;
|
|
|
791 |
|
|
|
792 |
/* Check previously defined thunks */
|
|
|
793 |
VIRTUAL vt = all_thunks ;
|
|
|
794 |
while ( !IS_NULL_virt ( vt ) ) {
|
|
|
795 |
IDENTIFIER vn = DEREF_id ( virt_func ( vt ) ) ;
|
|
|
796 |
if ( EQ_id ( vn, fid ) ) {
|
|
|
797 |
GRAPH gv = DEREF_graph ( virt_base ( vt ) ) ;
|
|
|
798 |
if ( EQ_graph ( gv, ret ) ) {
|
|
|
799 |
n = DEREF_ulong ( virt_no ( vt ) ) ;
|
|
|
800 |
return ( n ) ;
|
|
|
801 |
}
|
|
|
802 |
}
|
|
|
803 |
vt = DEREF_virt ( virt_next ( vt ) ) ;
|
|
|
804 |
}
|
|
|
805 |
|
|
|
806 |
/* Find type information */
|
|
|
807 |
while ( IS_type_templ ( f ) ) {
|
|
|
808 |
f = DEREF_type ( type_templ_defn ( f ) ) ;
|
|
|
809 |
}
|
|
|
810 |
r1 = DEREF_type ( type_func_ret ( f ) ) ;
|
|
|
811 |
p = DEREF_list ( type_func_mtypes ( f ) ) ;
|
|
|
812 |
np = LENGTH_list ( p ) ;
|
|
|
813 |
ell = DEREF_int ( type_func_ellipsis ( f ) ) ;
|
|
|
814 |
f2 = DEREF_type ( id_function_etc_type ( fid ) ) ;
|
|
|
815 |
while ( IS_type_templ ( f2 ) ) {
|
|
|
816 |
f2 = DEREF_type ( type_templ_defn ( f2 ) ) ;
|
|
|
817 |
}
|
|
|
818 |
r2 = DEREF_type ( type_func_ret ( f2 ) ) ;
|
|
|
819 |
|
|
|
820 |
/* Declare the thunk function */
|
|
|
821 |
n = capsule_no ( NULL_string, VAR_tag ) ;
|
|
|
822 |
enc_tagdec ( NULL_id, n, f, 0 ) ;
|
|
|
823 |
bs = enc_tagdef_start ( NULL_id, n, f, 0 ) ;
|
|
|
824 |
ts = start_bitstream ( NIL ( FILE ), bs->link ) ;
|
|
|
825 |
ENC_make_proc ( bs ) ;
|
|
|
826 |
bs = enc_shape ( bs, r1 ) ;
|
|
|
827 |
ENC_LIST ( bs, np ) ;
|
|
|
828 |
ENC_LIST ( ts, np ) ;
|
|
|
829 |
while ( !IS_NULL_list ( p ) ) {
|
|
|
830 |
/* Scan through parameter types */
|
|
|
831 |
TYPE pt = DEREF_type ( HEAD_list ( p ) ) ;
|
|
|
832 |
ulong m = unit_no ( bs, NULL_id, VAR_tag, 1 ) ;
|
|
|
833 |
ENC_contents ( ts ) ;
|
|
|
834 |
if ( pass_complex_type ( pt ) ) {
|
|
|
835 |
ENC_pointer ( bs ) ;
|
|
|
836 |
bs = enc_alignment ( bs, pt ) ;
|
|
|
837 |
ENC_pointer ( ts ) ;
|
|
|
838 |
ts = enc_alignment ( ts, pt ) ;
|
|
|
839 |
} else {
|
|
|
840 |
bs = enc_shape ( bs, pt ) ;
|
|
|
841 |
ts = enc_shape ( ts, pt ) ;
|
|
|
842 |
}
|
|
|
843 |
bs = enc_access ( bs, dspec_none ) ;
|
|
|
844 |
ENC_make_tag ( bs, m ) ;
|
|
|
845 |
ENC_obtain_tag ( ts ) ;
|
|
|
846 |
ENC_make_tag ( ts, m ) ;
|
|
|
847 |
p = TAIL_list ( p ) ;
|
|
|
848 |
}
|
|
|
849 |
if ( ell & FUNC_ELLIPSIS ) {
|
|
|
850 |
/* Check for ellipsis */
|
|
|
851 |
ulong m = unit_no ( bs, NULL_id, VAR_tag, 1 ) ;
|
|
|
852 |
ENC_ON ( bs ) ;
|
|
|
853 |
ENC_make_tag ( bs, m ) ;
|
|
|
854 |
bs = enc_access ( bs, dspec_none ) ;
|
|
|
855 |
/* NOT YET IMPLEMENTED: use same_callees? */
|
|
|
856 |
} else {
|
|
|
857 |
ENC_OFF ( bs ) ;
|
|
|
858 |
}
|
|
|
859 |
ENC_OFF ( ts ) ;
|
|
|
860 |
|
|
|
861 |
/* Output the function body */
|
|
|
862 |
rn = unit_no ( bs, NULL_id, VAR_tag, 1 ) ;
|
|
|
863 |
MAKE_exp_dummy ( r2, NULL_exp, rn, NULL_off, 1, e ) ;
|
|
|
864 |
ENC_variable ( bs ) ;
|
|
|
865 |
bs = enc_access ( bs, dspec_none ) ;
|
|
|
866 |
ENC_make_tag ( bs, rn ) ;
|
|
|
867 |
ENC_apply_proc ( bs ) ;
|
|
|
868 |
bs = enc_shape ( bs, r2 ) ;
|
|
|
869 |
pn = unit_no ( bs, fid, VAR_tag, 0 ) ;
|
|
|
870 |
ENC_obtain_tag ( bs ) ;
|
|
|
871 |
ENC_make_tag ( bs, pn ) ;
|
|
|
872 |
bs = join_bitstreams ( bs, ts ) ;
|
|
|
873 |
if ( IS_type_ptr ( r2 ) ) {
|
|
|
874 |
/* Test for null pointers */
|
|
|
875 |
ulong lab = unit_no ( bs, NULL_id, VAR_label, 1 ) ;
|
|
|
876 |
ENC_conditional ( bs ) ;
|
|
|
877 |
ENC_make_label ( bs, lab ) ;
|
|
|
878 |
ENC_SEQ_SMALL ( bs, 1 ) ;
|
|
|
879 |
bs = enc_compare ( bs, e, NULL_exp, ntest_eq, lab, LINK_NONE ) ;
|
|
|
880 |
ENC_return ( bs ) ;
|
|
|
881 |
bs = enc_null_exp ( bs, r1 ) ;
|
|
|
882 |
}
|
|
|
883 |
ENC_return ( bs ) ;
|
|
|
884 |
off = DEREF_off ( graph_off ( ret ) ) ;
|
|
|
885 |
bs = enc_add_ptr ( bs, e, LINK_NONE, off, 1 ) ;
|
|
|
886 |
enc_tagdef_end ( bs ) ;
|
|
|
887 |
free_exp ( e, 1 ) ;
|
|
|
888 |
|
|
|
889 |
/* Add to list of all thunks */
|
|
|
890 |
MAKE_virt_simple ( fid, n, ret, vt ) ;
|
|
|
891 |
COPY_virt ( virt_next ( vt ), all_thunks ) ;
|
|
|
892 |
all_thunks = vt ;
|
|
|
893 |
}
|
|
|
894 |
return ( n ) ;
|
|
|
895 |
}
|
|
|
896 |
|
|
|
897 |
|
|
|
898 |
/*
|
|
|
899 |
ENCODE THE SHAPE OF A VIRTUAL FUNCTION TABLE
|
|
|
900 |
|
|
|
901 |
This routine adds the shape of a virtual function table containing
|
|
|
902 |
n functions to the bitstream bs.
|
|
|
903 |
*/
|
|
|
904 |
|
|
|
905 |
BITSTREAM *enc_vtable_shape
|
|
|
906 |
PROTO_N ( ( bs, n ) )
|
|
|
907 |
PROTO_T ( BITSTREAM *bs X ulong n )
|
|
|
908 |
{
|
|
|
909 |
BITSTREAM *ts ;
|
|
|
910 |
bs = enc_special ( bs, TOK_vtab_type ) ;
|
|
|
911 |
ts = start_bitstream ( NIL ( FILE ), bs->link ) ;
|
|
|
912 |
ENC_make_nat ( ts ) ;
|
|
|
913 |
ENC_INT ( ts, n + VIRTUAL_EXTRA ) ;
|
|
|
914 |
bs = enc_bitstream ( bs, ts ) ;
|
|
|
915 |
return ( bs ) ;
|
|
|
916 |
}
|
|
|
917 |
|
|
|
918 |
|
|
|
919 |
/*
|
|
|
920 |
ENCODE THE DEFINITION OF A VIRTUAL FUNCTION TABLE
|
|
|
921 |
|
|
|
922 |
This routine encodes the definition of the virtual function table vt.
|
|
|
923 |
n gives the tag number for the table, gr is the table offset and the
|
|
|
924 |
flag inherited is true for secondary tables. rtti gives the tag
|
|
|
925 |
number for the run-time type information.
|
|
|
926 |
*/
|
|
|
927 |
|
|
|
928 |
static void enc_vtable_defn
|
|
|
929 |
PROTO_N ( ( vt, n, ct, gr, inherited, rtti ) )
|
|
|
930 |
PROTO_T ( VIRTUAL vt X ulong n X CLASS_TYPE ct X GRAPH gr X
|
|
|
931 |
int inherited X ulong rtti )
|
|
|
932 |
{
|
|
|
933 |
ulong r ;
|
|
|
934 |
BITSTREAM *bs, *ts, *us ;
|
|
|
935 |
ulong m = DEREF_ulong ( virt_no ( vt ) ) ;
|
|
|
936 |
ulong p = DEREF_ulong ( virt_table_tok ( vt ) ) ;
|
|
|
937 |
OFFSET off = DEREF_off ( virt_table_off ( vt ) ) ;
|
|
|
938 |
LIST ( VIRTUAL ) pt = DEREF_list ( virt_table_entries ( vt ) ) ;
|
|
|
939 |
|
|
|
940 |
/* Output start of table */
|
|
|
941 |
bs = enc_tagdef_start ( NULL_id, n, NULL_type, 1 ) ;
|
|
|
942 |
bs = enc_special ( bs, TOK_vtab_make ) ;
|
|
|
943 |
ts = start_bitstream ( NIL ( FILE ), bs->link ) ;
|
|
|
944 |
ENC_obtain_tag ( ts ) ;
|
|
|
945 |
r = link_no ( ts, rtti, VAR_tag ) ;
|
|
|
946 |
ENC_make_tag ( ts, r ) ;
|
|
|
947 |
if ( inherited ) {
|
|
|
948 |
/* Add base class offset */
|
|
|
949 |
OFFSET off2 = DEREF_off ( graph_off ( gr ) ) ;
|
|
|
950 |
if ( !is_zero_offset ( off2 ) ) {
|
|
|
951 |
ENC_offset_add ( ts ) ;
|
|
|
952 |
ts = enc_offset ( ts, off2 ) ;
|
|
|
953 |
}
|
|
|
954 |
}
|
|
|
955 |
if ( !is_zero_offset ( off ) ) {
|
|
|
956 |
/* Add inherited table offset */
|
|
|
957 |
ENC_offset_add ( ts ) ;
|
|
|
958 |
ts = enc_offset ( ts, off ) ;
|
|
|
959 |
}
|
|
|
960 |
ts = enc_exp_token ( ts, p ) ;
|
|
|
961 |
ENC_make_nat ( ts ) ;
|
|
|
962 |
ENC_INT ( ts, m + VIRTUAL_EXTRA ) ;
|
|
|
963 |
|
|
|
964 |
/* Output virtual functions */
|
|
|
965 |
ENC_make_nof ( ts ) ;
|
|
|
966 |
ENC_LIST ( ts, m ) ;
|
|
|
967 |
while ( !IS_NULL_list ( pt ) ) {
|
|
|
968 |
GRAPH gs ;
|
|
|
969 |
DECL_SPEC ds ;
|
|
|
970 |
IDENTIFIER fid ;
|
|
|
971 |
GRAPH ret = NULL_graph ;
|
|
|
972 |
IDENTIFIER pid = NULL_id ;
|
|
|
973 |
VIRTUAL at = DEREF_virt ( HEAD_list ( pt ) ) ;
|
|
|
974 |
while ( IS_virt_link ( at ) ) {
|
|
|
975 |
/* Allow for symbolic links */
|
|
|
976 |
at = DEREF_virt ( DEREF_ptr ( virt_link_to ( at ) ) ) ;
|
|
|
977 |
}
|
|
|
978 |
if ( inherited ) {
|
|
|
979 |
/* Allow for inherited function tables */
|
|
|
980 |
VIRTUAL as ;
|
|
|
981 |
pid = DEREF_id ( virt_func ( at ) ) ;
|
|
|
982 |
as = find_overrider ( ct, pid, gr, &ret ) ;
|
|
|
983 |
if ( !IS_NULL_virt ( as ) ) at = as ;
|
|
|
984 |
}
|
|
|
985 |
fid = DEREF_id ( virt_func ( at ) ) ;
|
|
|
986 |
ds = DEREF_dspec ( id_storage ( fid ) ) ;
|
|
|
987 |
gs = DEREF_graph ( virt_base ( at ) ) ;
|
|
|
988 |
|
|
|
989 |
/* Output pointer to member function */
|
|
|
990 |
ts = enc_special ( ts, TOK_pmf_make ) ;
|
|
|
991 |
us = start_bitstream ( NIL ( FILE ), ts->link ) ;
|
|
|
992 |
if ( ds & dspec_pure ) {
|
|
|
993 |
/* Pure virtual function */
|
|
|
994 |
us = enc_special ( us, TOK_vtab_pure ) ;
|
|
|
995 |
} else {
|
|
|
996 |
if ( IS_NULL_graph ( ret ) ) {
|
|
|
997 |
IGNORE capsule_id ( fid, VAR_tag ) ;
|
|
|
998 |
r = unit_no ( us, fid, VAR_tag, 0 ) ;
|
|
|
999 |
} else {
|
|
|
1000 |
TYPE f = DEREF_type ( id_function_etc_type ( pid ) ) ;
|
|
|
1001 |
r = make_thunk ( f, fid, ret ) ;
|
|
|
1002 |
r = link_no ( us, r, VAR_tag ) ;
|
|
|
1003 |
}
|
|
|
1004 |
ENC_obtain_tag ( us ) ;
|
|
|
1005 |
ENC_make_tag ( us, r ) ;
|
|
|
1006 |
}
|
|
|
1007 |
us = enc_base ( us, gs, 0 ) ;
|
|
|
1008 |
us = enc_base ( us, gr, 0 ) ;
|
|
|
1009 |
ts = enc_bitstream ( ts, us ) ;
|
|
|
1010 |
pt = TAIL_list ( pt ) ;
|
|
|
1011 |
}
|
|
|
1012 |
bs = enc_bitstream ( bs, ts ) ;
|
|
|
1013 |
enc_tagdef_end ( bs ) ;
|
|
|
1014 |
return ;
|
|
|
1015 |
}
|
|
|
1016 |
|
|
|
1017 |
|
|
|
1018 |
/*
|
|
|
1019 |
DEFINE VIRTUAL FUNCTION TABLES
|
|
|
1020 |
|
|
|
1021 |
This routine defines or declares the virtual function tables for
|
|
|
1022 |
the class ct depending on the value of def. The tables are given
|
|
|
1023 |
external names only if ext is true.
|
|
|
1024 |
*/
|
|
|
1025 |
|
|
|
1026 |
void define_vtable
|
|
|
1027 |
PROTO_N ( ( ct, def, ext ) )
|
|
|
1028 |
PROTO_T ( CLASS_TYPE ct X int def X int ext )
|
|
|
1029 |
{
|
|
|
1030 |
ulong r ;
|
|
|
1031 |
int used ;
|
|
|
1032 |
int have_main_table = 0 ;
|
|
|
1033 |
VIRTUAL vt = DEREF_virt ( ctype_virt ( ct ) ) ;
|
|
|
1034 |
if ( IS_NULL_virt ( vt ) ) return ;
|
|
|
1035 |
if ( output_all ) ext = 1 ;
|
|
|
1036 |
if ( def == 2 ) {
|
|
|
1037 |
/* Force definition in this case */
|
|
|
1038 |
IGNORE compile_class ( ct ) ;
|
|
|
1039 |
} else {
|
|
|
1040 |
ulong n = DEREF_ulong ( ctype_shape ( ct ) ) ;
|
|
|
1041 |
if ( n == LINK_NONE ) return ;
|
|
|
1042 |
}
|
|
|
1043 |
|
|
|
1044 |
/* Output run-time type information */
|
|
|
1045 |
r = DEREF_ulong ( virt_table_rtti ( vt ) ) ;
|
|
|
1046 |
used = DEREF_int ( virt_table_rtti_used ( vt ) ) ;
|
|
|
1047 |
if ( used || def ) {
|
|
|
1048 |
TYPE t = dummy_class ;
|
|
|
1049 |
if ( ext ) {
|
|
|
1050 |
/* Make up external name */
|
|
|
1051 |
string s = mangle_typeid ( "__ti__", ct ) ;
|
|
|
1052 |
r = capsule_name ( r, &s, VAR_tag ) ;
|
|
|
1053 |
}
|
|
|
1054 |
record_usage ( r, VAR_tag, USAGE_USE ) ;
|
|
|
1055 |
COPY_int ( virt_table_rtti_used ( vt ), 1 ) ;
|
|
|
1056 |
COPY_ctype ( type_compound_defn ( t ), ct ) ;
|
|
|
1057 |
enc_rtti_struct ( t, r, def ) ;
|
|
|
1058 |
}
|
|
|
1059 |
|
|
|
1060 |
/* Output virtual function tables */
|
|
|
1061 |
while ( !IS_NULL_virt ( vt ) ) {
|
|
|
1062 |
ulong n ;
|
|
|
1063 |
VIRTUAL vs ;
|
|
|
1064 |
unsigned acc ;
|
|
|
1065 |
CLASS_TYPE cs ;
|
|
|
1066 |
int inherited = 1 ;
|
|
|
1067 |
GRAPH gr = DEREF_graph ( virt_base ( vt ) ) ;
|
|
|
1068 |
DECL_SPEC gacc = DEREF_dspec ( graph_access ( gr ) ) ;
|
|
|
1069 |
if ( ( gacc & dspec_ignore ) && !have_main_table ) {
|
|
|
1070 |
/* Main virtual function table */
|
|
|
1071 |
gr = DEREF_graph ( graph_top ( gr ) ) ;
|
|
|
1072 |
have_main_table = 1 ;
|
|
|
1073 |
inherited = 0 ;
|
|
|
1074 |
}
|
|
|
1075 |
cs = DEREF_ctype ( graph_head ( gr ) ) ;
|
|
|
1076 |
vs = DEREF_virt ( ctype_virt ( cs ) ) ;
|
|
|
1077 |
n = DEREF_ulong ( virt_table_tbl ( vt ) ) ;
|
|
|
1078 |
record_usage ( n, VAR_tag, USAGE_USE ) ;
|
|
|
1079 |
acc = find_usage ( n, VAR_tag ) ;
|
|
|
1080 |
if ( ext ) {
|
|
|
1081 |
/* Make up external name */
|
|
|
1082 |
string s = mangle_vtable ( "__vt__", gr ) ;
|
|
|
1083 |
n = capsule_name ( n, &s, VAR_tag ) ;
|
|
|
1084 |
}
|
|
|
1085 |
if ( !( acc & USAGE_DECL ) ) {
|
|
|
1086 |
/* Output table declaration */
|
|
|
1087 |
ulong m = DEREF_ulong ( virt_no ( vs ) ) ;
|
|
|
1088 |
BITSTREAM *ts = enc_tagdec_start ( NULL_id, n, NULL_type, 1 ) ;
|
|
|
1089 |
ts = enc_vtable_shape ( ts, m ) ;
|
|
|
1090 |
enc_tagdec_end ( ts ) ;
|
|
|
1091 |
}
|
|
|
1092 |
if ( def && !( acc & USAGE_DEFN ) ) {
|
|
|
1093 |
/* Output table definition */
|
|
|
1094 |
enc_vtable_defn ( vs, n, ct, gr, inherited, r ) ;
|
|
|
1095 |
}
|
|
|
1096 |
vt = DEREF_virt ( virt_next ( vt ) ) ;
|
|
|
1097 |
}
|
|
|
1098 |
return ;
|
|
|
1099 |
}
|
|
|
1100 |
|
|
|
1101 |
|
|
|
1102 |
/*
|
|
|
1103 |
ALLOCATE TAG NUMBERS FOR VIRTUAL FUNCTION TABLES
|
|
|
1104 |
|
|
|
1105 |
This routine allocates tag and token numbers for the virtual function
|
|
|
1106 |
tables of the polymorphic class ct and its base classes.
|
|
|
1107 |
*/
|
|
|
1108 |
|
|
|
1109 |
static ulong declare_vtable
|
|
|
1110 |
PROTO_N ( ( ct ) )
|
|
|
1111 |
PROTO_T ( CLASS_TYPE ct )
|
|
|
1112 |
{
|
|
|
1113 |
ulong n = LINK_NONE ;
|
|
|
1114 |
ulong r = LINK_NONE ;
|
|
|
1115 |
VIRTUAL vt = DEREF_virt ( ctype_virt ( ct ) ) ;
|
|
|
1116 |
while ( !IS_NULL_virt ( vt ) ) {
|
|
|
1117 |
ulong t ;
|
|
|
1118 |
OFFSET off ;
|
|
|
1119 |
ulong m = DEREF_ulong ( virt_table_tok ( vt ) ) ;
|
|
|
1120 |
if ( m != LINK_NONE ) {
|
|
|
1121 |
/* Already declared */
|
|
|
1122 |
return ( m ) ;
|
|
|
1123 |
}
|
|
|
1124 |
off = DEREF_off ( virt_table_off ( vt ) ) ;
|
|
|
1125 |
if ( IS_NULL_off ( off ) ) {
|
|
|
1126 |
/* New virtual function table required */
|
|
|
1127 |
m = capsule_no ( NULL_string, VAR_token ) ;
|
|
|
1128 |
} else if ( IS_off_base ( off ) ) {
|
|
|
1129 |
/* Use existing virtual function table */
|
|
|
1130 |
GRAPH gs = DEREF_graph ( off_base_graph ( off ) ) ;
|
|
|
1131 |
CLASS_TYPE cs = DEREF_ctype ( graph_head ( gs ) ) ;
|
|
|
1132 |
m = declare_vtable ( cs ) ;
|
|
|
1133 |
} else {
|
|
|
1134 |
/* Use existing virtual function table */
|
|
|
1135 |
GRAPH gs = DEREF_graph ( off_deriv_graph ( off ) ) ;
|
|
|
1136 |
CLASS_TYPE cs = DEREF_ctype ( graph_head ( gs ) ) ;
|
|
|
1137 |
m = declare_vtable ( cs ) ;
|
|
|
1138 |
}
|
|
|
1139 |
if ( n == LINK_NONE ) n = m ;
|
|
|
1140 |
|
|
|
1141 |
/* Allocate (but not define) virtual table tags */
|
|
|
1142 |
t = capsule_no ( NULL_string, VAR_tag ) ;
|
|
|
1143 |
clear_usage ( t, VAR_tag ) ;
|
|
|
1144 |
if ( r == LINK_NONE ) {
|
|
|
1145 |
r = capsule_no ( NULL_string, VAR_tag ) ;
|
|
|
1146 |
clear_usage ( r, VAR_tag ) ;
|
|
|
1147 |
}
|
|
|
1148 |
COPY_ulong ( virt_table_tbl ( vt ), t ) ;
|
|
|
1149 |
COPY_ulong ( virt_table_rtti ( vt ), r ) ;
|
|
|
1150 |
COPY_ulong ( virt_table_tok ( vt ), m ) ;
|
|
|
1151 |
vt = DEREF_virt ( virt_next ( vt ) ) ;
|
|
|
1152 |
}
|
|
|
1153 |
return ( n ) ;
|
|
|
1154 |
}
|
|
|
1155 |
|
|
|
1156 |
|
|
|
1157 |
/*
|
|
|
1158 |
END OF RUN-TIME TYPE INFORMATION ROUTINES
|
|
|
1159 |
|
|
|
1160 |
The remaining routines are common to both the C and C++ producers.
|
|
|
1161 |
*/
|
|
|
1162 |
|
|
|
1163 |
#endif /* LANGUAGE_CPP */
|
|
|
1164 |
|
|
|
1165 |
|
|
|
1166 |
/*
|
|
|
1167 |
FIND THE TABLE OFFSET OF A VIRTUAL FUNCTION
|
|
|
1168 |
|
|
|
1169 |
This routine finds the position of the virtual function id in the
|
|
|
1170 |
virtual function table vt.
|
|
|
1171 |
*/
|
|
|
1172 |
|
|
|
1173 |
ulong virtual_no
|
|
|
1174 |
PROTO_N ( ( id, vt ) )
|
|
|
1175 |
PROTO_T ( IDENTIFIER id X VIRTUAL vt )
|
|
|
1176 |
{
|
|
|
1177 |
LIST ( VIRTUAL ) pv = DEREF_list ( virt_table_entries ( vt ) ) ;
|
|
|
1178 |
while ( !IS_NULL_list ( pv ) ) {
|
|
|
1179 |
VIRTUAL vs = DEREF_virt ( HEAD_list ( pv ) ) ;
|
|
|
1180 |
IDENTIFIER vid = DEREF_id ( virt_func ( vs ) ) ;
|
|
|
1181 |
if ( EQ_id ( vid, id ) ) {
|
|
|
1182 |
ulong m = DEREF_ulong ( virt_no ( vs ) ) ;
|
|
|
1183 |
return ( m + VIRTUAL_EXTRA ) ;
|
|
|
1184 |
}
|
|
|
1185 |
pv = TAIL_list ( pv ) ;
|
|
|
1186 |
}
|
|
|
1187 |
return ( VIRTUAL_EXTRA ) ;
|
|
|
1188 |
}
|
|
|
1189 |
|
|
|
1190 |
|
|
|
1191 |
/*
|
|
|
1192 |
IS A TYPE A ZERO SIZED BITFIELD?
|
|
|
1193 |
|
|
|
1194 |
This routine checks whether the type t represents a zero sized
|
|
|
1195 |
bitfield. These force an alignment in a class rather than being
|
|
|
1196 |
a proper class member.
|
|
|
1197 |
*/
|
|
|
1198 |
|
|
|
1199 |
static int is_zero_bitfield
|
|
|
1200 |
PROTO_N ( ( t ) )
|
|
|
1201 |
PROTO_T ( TYPE t )
|
|
|
1202 |
{
|
|
|
1203 |
if ( !IS_NULL_type ( t ) && IS_type_bitfield ( t ) ) {
|
|
|
1204 |
INT_TYPE bf = DEREF_itype ( type_bitfield_defn ( t ) ) ;
|
|
|
1205 |
DECL_SPEC ds = DEREF_dspec ( itype_bitfield_info ( bf ) ) ;
|
|
|
1206 |
if ( ds & dspec_pure ) return ( 1 ) ;
|
|
|
1207 |
}
|
|
|
1208 |
return ( 0 ) ;
|
|
|
1209 |
}
|
|
|
1210 |
|
|
|
1211 |
|
|
|
1212 |
/*
|
|
|
1213 |
ENCODE A SHAPE OFFSET EXPRESSION
|
|
|
1214 |
|
|
|
1215 |
This routine adds the offset of the type t to the bitstream bs,
|
|
|
1216 |
unless t is dummy_class, when the offset of the type excluding the
|
|
|
1217 |
virtual bases is added.
|
|
|
1218 |
*/
|
|
|
1219 |
|
|
|
1220 |
static BITSTREAM *enc_offset_add
|
|
|
1221 |
PROTO_N ( ( bs, t ) )
|
|
|
1222 |
PROTO_T ( BITSTREAM *bs X TYPE t )
|
|
|
1223 |
{
|
|
|
1224 |
if ( EQ_type ( t, dummy_class ) ) {
|
|
|
1225 |
/* Class offset */
|
|
|
1226 |
CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
|
|
|
1227 |
GRAPH gr = DEREF_graph ( ctype_base ( ct ) ) ;
|
|
|
1228 |
ulong m = DEREF_ulong ( graph_core_off ( gr ) ) ;
|
|
|
1229 |
if ( m != LINK_NONE ) {
|
|
|
1230 |
bs = enc_exp_token ( bs, m ) ;
|
|
|
1231 |
return ( bs ) ;
|
|
|
1232 |
}
|
|
|
1233 |
}
|
|
|
1234 |
ENC_shape_offset ( bs ) ;
|
|
|
1235 |
bs = enc_shape ( bs, t ) ;
|
|
|
1236 |
return ( bs ) ;
|
|
|
1237 |
}
|
|
|
1238 |
|
|
|
1239 |
|
|
|
1240 |
/*
|
|
|
1241 |
ENCODE AN OFFSET PAD EXPRESSION
|
|
|
1242 |
|
|
|
1243 |
This routine adds the offset of a structure member of type s
|
|
|
1244 |
which follows a member of type t with offset given by the token n
|
|
|
1245 |
to the bitstream bs. Note that bitfield types are awkward.
|
|
|
1246 |
*/
|
|
|
1247 |
|
|
|
1248 |
static BITSTREAM *enc_offset_pad
|
|
|
1249 |
PROTO_N ( ( bs, n, t, s ) )
|
|
|
1250 |
PROTO_T ( BITSTREAM *bs X ulong n X TYPE t X TYPE s )
|
|
|
1251 |
{
|
|
|
1252 |
BITSTREAM *ts ;
|
|
|
1253 |
unsigned tag = null_tag ;
|
|
|
1254 |
int z = is_zero_bitfield ( t ) ;
|
|
|
1255 |
if ( !IS_NULL_type ( s ) ) {
|
|
|
1256 |
if ( is_zero_bitfield ( s ) ) {
|
|
|
1257 |
/* Force an alignment */
|
|
|
1258 |
s = find_bitfield_type ( s ) ;
|
|
|
1259 |
}
|
|
|
1260 |
ENC_offset_pad ( bs ) ;
|
|
|
1261 |
bs = enc_alignment ( bs, s ) ;
|
|
|
1262 |
tag = TAG_type ( s ) ;
|
|
|
1263 |
}
|
|
|
1264 |
if ( tag == type_bitfield_tag ) {
|
|
|
1265 |
/* Use token for bitfields */
|
|
|
1266 |
bs = enc_special ( bs, TOK_pad ) ;
|
|
|
1267 |
ts = start_bitstream ( NIL ( FILE ), bs->link ) ;
|
|
|
1268 |
} else {
|
|
|
1269 |
ts = bs ;
|
|
|
1270 |
}
|
|
|
1271 |
|
|
|
1272 |
/* Add offset (except for zero sized bitfields) */
|
|
|
1273 |
if ( !z ) ENC_offset_add ( ts ) ;
|
|
|
1274 |
ts = enc_exp_token ( ts, n ) ;
|
|
|
1275 |
if ( !z ) ts = enc_offset_add ( ts, t ) ;
|
|
|
1276 |
|
|
|
1277 |
/* Encode extra bitfield arguments */
|
|
|
1278 |
if ( tag == type_bitfield_tag ) {
|
|
|
1279 |
TYPE r = find_bitfield_type ( s ) ;
|
|
|
1280 |
ts = enc_shape ( ts, r ) ;
|
|
|
1281 |
ts = enc_shape ( ts, s ) ;
|
|
|
1282 |
bs = enc_bitstream ( bs, ts ) ;
|
|
|
1283 |
} else {
|
|
|
1284 |
bs = ts ;
|
|
|
1285 |
}
|
|
|
1286 |
return ( bs ) ;
|
|
|
1287 |
}
|
|
|
1288 |
|
|
|
1289 |
|
|
|
1290 |
/*
|
|
|
1291 |
DEFINE AN ALIGNMENT TAG
|
|
|
1292 |
|
|
|
1293 |
This routine defines the alignment tag m to be the token n. The value
|
|
|
1294 |
LINK_NONE for n is used to indicate an incomplete structure.
|
|
|
1295 |
*/
|
|
|
1296 |
|
|
|
1297 |
static void enc_al_tagdef
|
|
|
1298 |
PROTO_N ( ( m, n ) )
|
|
|
1299 |
PROTO_T ( ulong m X ulong n )
|
|
|
1300 |
{
|
|
|
1301 |
unsigned acc = find_usage ( m, VAR_alignment ) ;
|
|
|
1302 |
if ( !( acc & USAGE_DEFN ) ) {
|
|
|
1303 |
BITSTREAM *bs = aldef_unit ;
|
|
|
1304 |
ulong r = link_no ( bs, m, VAR_alignment ) ;
|
|
|
1305 |
ENC_make_al_tagdef ( bs ) ;
|
|
|
1306 |
ENC_INT ( bs, r ) ;
|
|
|
1307 |
if ( n == LINK_NONE ) {
|
|
|
1308 |
bs = enc_special ( bs, TOK_empty_align ) ;
|
|
|
1309 |
} else {
|
|
|
1310 |
ENC_alignment ( bs ) ;
|
|
|
1311 |
bs = enc_shape_token ( bs, n ) ;
|
|
|
1312 |
}
|
|
|
1313 |
record_usage ( m, VAR_alignment, USAGE_DEFN ) ;
|
|
|
1314 |
count_item ( bs ) ;
|
|
|
1315 |
aldef_unit = bs ;
|
|
|
1316 |
}
|
|
|
1317 |
return ;
|
|
|
1318 |
}
|
|
|
1319 |
|
|
|
1320 |
|
|
|
1321 |
/*
|
|
|
1322 |
ENCODE A TDF COMPOUND SHAPE
|
|
|
1323 |
|
|
|
1324 |
This routine defines all the shape and offset tokens associated with
|
|
|
1325 |
the compound type ct. It returns the external (capsule) number of
|
|
|
1326 |
a token giving the overall shape of the result.
|
|
|
1327 |
*/
|
|
|
1328 |
|
|
|
1329 |
ulong compile_class
|
|
|
1330 |
PROTO_N ( ( ct ) )
|
|
|
1331 |
PROTO_T ( CLASS_TYPE ct )
|
|
|
1332 |
{
|
|
|
1333 |
ulong n = DEREF_ulong ( ctype_shape ( ct ) ) ;
|
|
|
1334 |
if ( n == LINK_NONE ) {
|
|
|
1335 |
ulong m ;
|
|
|
1336 |
HASHID nm ;
|
|
|
1337 |
NAMESPACE ns ;
|
|
|
1338 |
BITSTREAM *bs ;
|
|
|
1339 |
BITSTREAM *ts ;
|
|
|
1340 |
LIST ( GRAPH ) br ;
|
|
|
1341 |
TYPE pt = NULL_type ;
|
|
|
1342 |
int ext = output_all ;
|
|
|
1343 |
ulong pm = LINK_NONE ;
|
|
|
1344 |
ulong vo = LINK_NONE ;
|
|
|
1345 |
unsigned no_mems = 0 ;
|
|
|
1346 |
unsigned no_bases = 0 ;
|
|
|
1347 |
DECL_SPEC macc = dspec_none ;
|
|
|
1348 |
GRAPH gr = DEREF_graph ( ctype_base ( ct ) ) ;
|
|
|
1349 |
CLASS_INFO ci = DEREF_cinfo ( ctype_info ( ct ) ) ;
|
|
|
1350 |
CLASS_TYPE cd = DEREF_ctype ( type_compound_defn ( dummy_class ) ) ;
|
|
|
1351 |
#if LANGUAGE_CPP
|
|
|
1352 |
VIRTUAL vt = DEREF_virt ( ctype_virt ( ct ) ) ;
|
|
|
1353 |
#endif
|
|
|
1354 |
|
|
|
1355 |
/* Check for tokenised types */
|
|
|
1356 |
if ( ci & cinfo_token ) {
|
|
|
1357 |
IDENTIFIER id = DEREF_id ( ctype_name ( ct ) ) ;
|
|
|
1358 |
id = find_token ( id ) ;
|
|
|
1359 |
IGNORE enc_tokdef ( id, 0 ) ;
|
|
|
1360 |
n = DEREF_ulong ( id_no ( id ) ) ;
|
|
|
1361 |
COPY_ulong ( ctype_shape ( ct ), n ) ;
|
|
|
1362 |
return ( n ) ;
|
|
|
1363 |
}
|
|
|
1364 |
|
|
|
1365 |
/* Assign token number */
|
|
|
1366 |
n = capsule_no ( NULL_string, VAR_token ) ;
|
|
|
1367 |
COPY_ulong ( ctype_shape ( ct ), n ) ;
|
|
|
1368 |
|
|
|
1369 |
/* Allow for recursive types */
|
|
|
1370 |
if ( ci & cinfo_recursive ) {
|
|
|
1371 |
m = DEREF_ulong ( graph_al_tag ( gr ) ) ;
|
|
|
1372 |
if ( m == LINK_NONE ) {
|
|
|
1373 |
m = capsule_no ( NULL_string, VAR_alignment ) ;
|
|
|
1374 |
if ( ext ) {
|
|
|
1375 |
string s = mangle_typeid ( "~cpp.al.", ct ) ;
|
|
|
1376 |
m = capsule_name ( m, &s, VAR_alignment ) ;
|
|
|
1377 |
}
|
|
|
1378 |
COPY_ulong ( graph_al_tag ( gr ), m ) ;
|
|
|
1379 |
}
|
|
|
1380 |
}
|
|
|
1381 |
|
|
|
1382 |
/* Assign virtual function tokens */
|
|
|
1383 |
#if LANGUAGE_CPP
|
|
|
1384 |
if ( !IS_NULL_virt ( vt ) ) {
|
|
|
1385 |
OFFSET off = DEREF_off ( virt_table_off ( vt ) ) ;
|
|
|
1386 |
if ( !IS_NULL_off ( off ) ) vt = NULL_virt ;
|
|
|
1387 |
IGNORE declare_vtable ( ct ) ;
|
|
|
1388 |
}
|
|
|
1389 |
#endif
|
|
|
1390 |
|
|
|
1391 |
/* Scan through direct base classes */
|
|
|
1392 |
br = DEREF_list ( graph_tails ( gr ) ) ;
|
|
|
1393 |
while ( !IS_NULL_list ( br ) ) {
|
|
|
1394 |
int virt = 0 ;
|
|
|
1395 |
GRAPH gs = DEREF_graph ( HEAD_list ( br ) ) ;
|
|
|
1396 |
DECL_SPEC acc = DEREF_dspec ( graph_access ( gs ) ) ;
|
|
|
1397 |
CLASS_TYPE cs = DEREF_ctype ( graph_head ( gs ) ) ;
|
|
|
1398 |
|
|
|
1399 |
/* Define offset token */
|
|
|
1400 |
IGNORE compile_class ( cs ) ;
|
|
|
1401 |
m = capsule_no ( NULL_string, VAR_token ) ;
|
|
|
1402 |
if ( ext ) {
|
|
|
1403 |
string s = mangle_vtable ( "~cpp.base.", gs ) ;
|
|
|
1404 |
m = capsule_name ( m, &s, VAR_token ) ;
|
|
|
1405 |
}
|
|
|
1406 |
COPY_ulong ( graph_base_off ( gs ), m ) ;
|
|
|
1407 |
bs = enc_tokdef_start ( m, "E", NIL ( ulong ), 1 ) ;
|
|
|
1408 |
if ( pm == LINK_NONE ) {
|
|
|
1409 |
/* First base class */
|
|
|
1410 |
ENC_offset_zero ( bs ) ;
|
|
|
1411 |
if ( acc & dspec_virtual ) {
|
|
|
1412 |
ENC_alignment ( bs ) ;
|
|
|
1413 |
ENC_pointer ( bs ) ;
|
|
|
1414 |
ENC_alignment ( bs ) ;
|
|
|
1415 |
ENC_top ( bs ) ;
|
|
|
1416 |
virt = 1 ;
|
|
|
1417 |
} else {
|
|
|
1418 |
bs = enc_al_ctype ( bs, cs ) ;
|
|
|
1419 |
}
|
|
|
1420 |
} else {
|
|
|
1421 |
/* Subsequent base classes */
|
|
|
1422 |
ENC_offset_pad ( bs ) ;
|
|
|
1423 |
if ( acc & dspec_virtual ) {
|
|
|
1424 |
ENC_alignment ( bs ) ;
|
|
|
1425 |
ENC_pointer ( bs ) ;
|
|
|
1426 |
ENC_alignment ( bs ) ;
|
|
|
1427 |
ENC_top ( bs ) ;
|
|
|
1428 |
virt = 1 ;
|
|
|
1429 |
} else {
|
|
|
1430 |
bs = enc_al_ctype ( bs, cs ) ;
|
|
|
1431 |
}
|
|
|
1432 |
ENC_offset_add ( bs ) ;
|
|
|
1433 |
bs = enc_exp_token ( bs, pm ) ;
|
|
|
1434 |
bs = enc_offset_add ( bs, pt ) ;
|
|
|
1435 |
}
|
|
|
1436 |
enc_tokdef_end ( m, bs ) ;
|
|
|
1437 |
|
|
|
1438 |
/* Find member type */
|
|
|
1439 |
pt = dummy_class ;
|
|
|
1440 |
COPY_ctype ( type_compound_defn ( pt ), cs ) ;
|
|
|
1441 |
if ( virt ) {
|
|
|
1442 |
pt = ptr_dummy_class ;
|
|
|
1443 |
} else {
|
|
|
1444 |
no_bases++ ;
|
|
|
1445 |
}
|
|
|
1446 |
pm = m ;
|
|
|
1447 |
br = TAIL_list ( br ) ;
|
|
|
1448 |
}
|
|
|
1449 |
|
|
|
1450 |
/* Scan through data members */
|
|
|
1451 |
ts = start_bitstream ( NIL ( FILE ), tokdef_unit->link ) ;
|
|
|
1452 |
ns = DEREF_nspace ( ctype_member ( ct ) ) ;
|
|
|
1453 |
if ( output_order ) macc = dspec_public ;
|
|
|
1454 |
do {
|
|
|
1455 |
DECL_SPEC nacc = dspec_none ;
|
|
|
1456 |
MEMBER mem = DEREF_member ( nspace_ctype_first ( ns ) ) ;
|
|
|
1457 |
mem = next_data_member ( mem, 1 ) ;
|
|
|
1458 |
while ( !IS_NULL_member ( mem ) ) {
|
|
|
1459 |
unsigned real_mem = 1 ;
|
|
|
1460 |
IDENTIFIER mid = DEREF_id ( member_id ( mem ) ) ;
|
|
|
1461 |
TYPE t = DEREF_type ( id_member_type ( mid ) ) ;
|
|
|
1462 |
if ( ci & cinfo_union ) {
|
|
|
1463 |
/* Union types */
|
|
|
1464 |
m = LINK_ZERO ;
|
|
|
1465 |
if ( !IS_NULL_type ( pt ) ) {
|
|
|
1466 |
ENC_offset_max ( ts ) ;
|
|
|
1467 |
ENC_shape_offset ( ts ) ;
|
|
|
1468 |
ts = enc_shape ( ts, pt ) ;
|
|
|
1469 |
}
|
|
|
1470 |
no_mems = 1 ;
|
|
|
1471 |
} else {
|
|
|
1472 |
/* Structure types */
|
|
|
1473 |
if ( macc ) {
|
|
|
1474 |
/* Check member access */
|
|
|
1475 |
DECL_SPEC acc = DEREF_dspec ( id_storage ( mid ) ) ;
|
|
|
1476 |
acc &= dspec_access ;
|
|
|
1477 |
if ( acc != macc ) {
|
|
|
1478 |
mem = DEREF_member ( member_next ( mem ) ) ;
|
|
|
1479 |
mem = next_data_member ( mem, 1 ) ;
|
|
|
1480 |
if ( acc > macc ) {
|
|
|
1481 |
/* Find next access to check */
|
|
|
1482 |
if ( acc == dspec_protected ) {
|
|
|
1483 |
nacc = dspec_protected ;
|
|
|
1484 |
} else if ( nacc == dspec_none ) {
|
|
|
1485 |
nacc = dspec_private ;
|
|
|
1486 |
}
|
|
|
1487 |
}
|
|
|
1488 |
continue ;
|
|
|
1489 |
}
|
|
|
1490 |
}
|
|
|
1491 |
m = DEREF_ulong ( id_no ( mid ) ) ;
|
|
|
1492 |
if ( m == LINK_NONE ) {
|
|
|
1493 |
m = capsule_no ( NULL_string, VAR_token ) ;
|
|
|
1494 |
if ( ext ) {
|
|
|
1495 |
string s = mangle_name ( mid, VAR_token, 0 ) ;
|
|
|
1496 |
m = capsule_name ( m, &s, VAR_token ) ;
|
|
|
1497 |
}
|
|
|
1498 |
bs = enc_tokdef_start ( m, "E", NIL ( ulong ), 1 ) ;
|
|
|
1499 |
if ( pm == LINK_NONE ) {
|
|
|
1500 |
/* First member */
|
|
|
1501 |
if ( IS_type_bitfield ( t ) ) {
|
|
|
1502 |
/* Bitfield members */
|
|
|
1503 |
TYPE r = find_bitfield_type ( t ) ;
|
|
|
1504 |
if ( !is_zero_bitfield ( t ) ) {
|
|
|
1505 |
ENC_offset_pad ( bs ) ;
|
|
|
1506 |
bs = enc_alignment ( bs, t ) ;
|
|
|
1507 |
}
|
|
|
1508 |
ENC_offset_zero ( bs ) ;
|
|
|
1509 |
bs = enc_alignment ( bs, r ) ;
|
|
|
1510 |
nm = DEREF_hashid ( id_name ( mid ) ) ;
|
|
|
1511 |
if ( IS_hashid_anon ( nm ) ) real_mem = 0 ;
|
|
|
1512 |
} else {
|
|
|
1513 |
/* Non-bitfield members */
|
|
|
1514 |
ENC_offset_zero ( bs ) ;
|
|
|
1515 |
bs = enc_alignment ( bs, t ) ;
|
|
|
1516 |
}
|
|
|
1517 |
} else {
|
|
|
1518 |
/* Subsequent members */
|
|
|
1519 |
bs = enc_offset_pad ( bs, pm, pt, t ) ;
|
|
|
1520 |
if ( IS_type_bitfield ( t ) ) {
|
|
|
1521 |
nm = DEREF_hashid ( id_name ( mid ) ) ;
|
|
|
1522 |
if ( IS_hashid_anon ( nm ) ) real_mem = 0 ;
|
|
|
1523 |
}
|
|
|
1524 |
}
|
|
|
1525 |
enc_tokdef_end ( m, bs ) ;
|
|
|
1526 |
}
|
|
|
1527 |
no_mems += real_mem ;
|
|
|
1528 |
pm = m ;
|
|
|
1529 |
}
|
|
|
1530 |
COPY_ulong ( id_no ( mid ), m ) ;
|
|
|
1531 |
pt = t ;
|
|
|
1532 |
mem = DEREF_member ( member_next ( mem ) ) ;
|
|
|
1533 |
mem = next_data_member ( mem, 1 ) ;
|
|
|
1534 |
}
|
|
|
1535 |
macc = nacc ;
|
|
|
1536 |
} while ( macc ) ;
|
|
|
1537 |
|
|
|
1538 |
/* Allow for virtual function table */
|
|
|
1539 |
#if LANGUAGE_CPP
|
|
|
1540 |
if ( !IS_NULL_virt ( vt ) ) {
|
|
|
1541 |
TYPE t = ptr_dummy_vtab ;
|
|
|
1542 |
m = DEREF_ulong ( virt_table_tok ( vt ) ) ;
|
|
|
1543 |
if ( ext ) {
|
|
|
1544 |
string s = mangle_typeid ( "~cpp.vptr.", ct ) ;
|
|
|
1545 |
m = capsule_name ( m, &s, VAR_token ) ;
|
|
|
1546 |
}
|
|
|
1547 |
size_dummy_vtab = DEREF_ulong ( virt_no ( vt ) ) ;
|
|
|
1548 |
bs = enc_tokdef_start ( m, "E", NIL ( ulong ), 1 ) ;
|
|
|
1549 |
if ( pm == LINK_NONE ) {
|
|
|
1550 |
ENC_offset_zero ( bs ) ;
|
|
|
1551 |
bs = enc_alignment ( bs, t ) ;
|
|
|
1552 |
} else {
|
|
|
1553 |
bs = enc_offset_pad ( bs, pm, pt, t ) ;
|
|
|
1554 |
}
|
|
|
1555 |
enc_tokdef_end ( m, bs ) ;
|
|
|
1556 |
pt = t ;
|
|
|
1557 |
pm = m ;
|
|
|
1558 |
no_bases++ ;
|
|
|
1559 |
}
|
|
|
1560 |
#endif
|
|
|
1561 |
|
|
|
1562 |
/* Scan through virtual bases */
|
|
|
1563 |
br = DEREF_list ( ctype_vbase ( ct ) ) ;
|
|
|
1564 |
while ( !IS_NULL_list ( br ) ) {
|
|
|
1565 |
GRAPH gs = DEREF_graph ( HEAD_list ( br ) ) ;
|
|
|
1566 |
CLASS_TYPE cs = DEREF_ctype ( graph_head ( gs ) ) ;
|
|
|
1567 |
|
|
|
1568 |
/* Define offset token */
|
|
|
1569 |
IGNORE compile_class ( cs ) ;
|
|
|
1570 |
m = capsule_no ( NULL_string, VAR_token ) ;
|
|
|
1571 |
if ( ext ) {
|
|
|
1572 |
string s = mangle_vtable ( "~cpp.virt.", gs ) ;
|
|
|
1573 |
m = capsule_name ( m, &s, VAR_token ) ;
|
|
|
1574 |
}
|
|
|
1575 |
bs = enc_tokdef_start ( m, "E", NIL ( ulong ), 1 ) ;
|
|
|
1576 |
ENC_offset_pad ( bs ) ;
|
|
|
1577 |
bs = enc_al_ctype ( bs, cs ) ;
|
|
|
1578 |
ENC_offset_add ( bs ) ;
|
|
|
1579 |
bs = enc_exp_token ( bs, pm ) ;
|
|
|
1580 |
bs = enc_offset_add ( bs, pt ) ;
|
|
|
1581 |
enc_tokdef_end ( m, bs ) ;
|
|
|
1582 |
do {
|
|
|
1583 |
/* All copies have the same real offset */
|
|
|
1584 |
COPY_ulong ( graph_real_off ( gs ), m ) ;
|
|
|
1585 |
gs = DEREF_graph ( graph_equal ( gs ) ) ;
|
|
|
1586 |
} while ( !IS_NULL_graph ( gs ) ) ;
|
|
|
1587 |
if ( vo == LINK_NONE ) vo = m ;
|
|
|
1588 |
pt = dummy_class ;
|
|
|
1589 |
COPY_ctype ( type_compound_defn ( pt ), cs ) ;
|
|
|
1590 |
pm = m ;
|
|
|
1591 |
no_bases++ ;
|
|
|
1592 |
br = TAIL_list ( br ) ;
|
|
|
1593 |
}
|
|
|
1594 |
|
|
|
1595 |
/* Define the overall shape token */
|
|
|
1596 |
no_mems += no_bases ;
|
|
|
1597 |
if ( no_mems ) {
|
|
|
1598 |
/* Non-empty structure offset definition */
|
|
|
1599 |
m = capsule_no ( NULL_string, VAR_token ) ;
|
|
|
1600 |
if ( ext ) {
|
|
|
1601 |
string s = mangle_typeid ( "~cpp.off.", ct ) ;
|
|
|
1602 |
m = capsule_name ( m, &s, VAR_token ) ;
|
|
|
1603 |
}
|
|
|
1604 |
bs = enc_tokdef_start ( m, "E", NIL ( ulong ), 1 ) ;
|
|
|
1605 |
bs = enc_special ( bs, TOK_comp_off ) ;
|
|
|
1606 |
if ( ci & cinfo_union ) {
|
|
|
1607 |
/* Complete union definition */
|
|
|
1608 |
ENC_shape_offset ( ts ) ;
|
|
|
1609 |
ts = enc_shape ( ts, pt ) ;
|
|
|
1610 |
} else {
|
|
|
1611 |
/* Complete structure definition */
|
|
|
1612 |
ts = enc_offset_pad ( ts, pm, pt, NULL_type ) ;
|
|
|
1613 |
}
|
|
|
1614 |
bs = enc_bitstream ( bs, ts ) ;
|
|
|
1615 |
enc_tokdef_end ( m, bs ) ;
|
|
|
1616 |
|
|
|
1617 |
/* Record offset of non-virtual components */
|
|
|
1618 |
if ( vo == LINK_NONE ) vo = m ;
|
|
|
1619 |
COPY_ulong ( graph_core_off ( gr ), vo ) ;
|
|
|
1620 |
|
|
|
1621 |
/* Non-empty structure shape definition */
|
|
|
1622 |
if ( ext ) {
|
|
|
1623 |
string s = mangle_typeid ( "~cpp.sh.", ct ) ;
|
|
|
1624 |
n = capsule_name ( n, &s, VAR_token ) ;
|
|
|
1625 |
}
|
|
|
1626 |
bs = enc_tokdef_start ( n, "S", NIL ( ulong ), 1 ) ;
|
|
|
1627 |
ENC_compound ( bs ) ;
|
|
|
1628 |
bs = enc_exp_token ( bs, m ) ;
|
|
|
1629 |
enc_tokdef_end ( n, bs ) ;
|
|
|
1630 |
ci &= ~cinfo_empty ;
|
|
|
1631 |
|
|
|
1632 |
} else {
|
|
|
1633 |
/* Empty structure definition */
|
|
|
1634 |
clear_usage ( n, VAR_token ) ;
|
|
|
1635 |
n = special_no ( TOK_empty_shape ) ;
|
|
|
1636 |
COPY_ulong ( ctype_shape ( ct ), n ) ;
|
|
|
1637 |
vo = special_no ( TOK_empty_offset ) ;
|
|
|
1638 |
COPY_ulong ( graph_core_off ( gr ), vo ) ;
|
|
|
1639 |
ci |= cinfo_empty ;
|
|
|
1640 |
}
|
|
|
1641 |
COPY_cinfo ( ctype_info ( ct ), ci ) ;
|
|
|
1642 |
|
|
|
1643 |
/* Define associated alignment tag */
|
|
|
1644 |
m = DEREF_ulong ( graph_al_tag ( gr ) ) ;
|
|
|
1645 |
if ( m != LINK_NONE ) enc_al_tagdef ( m, n ) ;
|
|
|
1646 |
COPY_ctype ( type_compound_defn ( dummy_class ), cd ) ;
|
|
|
1647 |
}
|
|
|
1648 |
return ( n ) ;
|
|
|
1649 |
}
|
|
|
1650 |
|
|
|
1651 |
|
|
|
1652 |
/*
|
|
|
1653 |
ENCODE THE SHAPE OF A CLASS TYPE
|
|
|
1654 |
|
|
|
1655 |
This routine adds the class type ct to the bitstream bs as a TDF SHAPE.
|
|
|
1656 |
*/
|
|
|
1657 |
|
|
|
1658 |
BITSTREAM *enc_ctype
|
|
|
1659 |
PROTO_N ( ( bs, ct ) )
|
|
|
1660 |
PROTO_T ( BITSTREAM *bs X CLASS_TYPE ct )
|
|
|
1661 |
{
|
|
|
1662 |
ulong n = compile_class ( ct ) ;
|
|
|
1663 |
bs = enc_shape_token ( bs, n ) ;
|
|
|
1664 |
return ( bs ) ;
|
|
|
1665 |
}
|
|
|
1666 |
|
|
|
1667 |
|
|
|
1668 |
/*
|
|
|
1669 |
LIST OF INCOMPLETE CLASSES
|
|
|
1670 |
|
|
|
1671 |
This list is used to hold all the classes which are used while they
|
|
|
1672 |
are incomplete. An alignment tag is introduced for each such class
|
|
|
1673 |
which may be defined later if the class is completed.
|
|
|
1674 |
*/
|
|
|
1675 |
|
|
|
1676 |
static LIST ( CLASS_TYPE ) incompl_classes = NULL_list ( CLASS_TYPE ) ;
|
|
|
1677 |
|
|
|
1678 |
|
|
|
1679 |
/*
|
|
|
1680 |
DEFINE INCOMPLETE CLASSES
|
|
|
1681 |
|
|
|
1682 |
This routine defines the alignment tags for the incomplete classes
|
|
|
1683 |
in this list above. Note that the class is not compiled if it has
|
|
|
1684 |
not already been so.
|
|
|
1685 |
*/
|
|
|
1686 |
|
|
|
1687 |
void compile_incompl
|
|
|
1688 |
PROTO_Z ()
|
|
|
1689 |
{
|
|
|
1690 |
LIST ( CLASS_TYPE ) p = incompl_classes ;
|
|
|
1691 |
while ( !IS_NULL_list ( p ) ) {
|
|
|
1692 |
CLASS_TYPE ct = DEREF_ctype ( HEAD_list ( p ) ) ;
|
|
|
1693 |
ulong n = DEREF_ulong ( ctype_shape ( ct ) ) ;
|
|
|
1694 |
if ( n == LINK_NONE ) {
|
|
|
1695 |
/* Uncompiled or incomplete class */
|
|
|
1696 |
GRAPH gr = DEREF_graph ( ctype_base ( ct ) ) ;
|
|
|
1697 |
ulong m = DEREF_ulong ( graph_al_tag ( gr ) ) ;
|
|
|
1698 |
enc_al_tagdef ( m, n ) ;
|
|
|
1699 |
}
|
|
|
1700 |
p = TAIL_list ( p ) ;
|
|
|
1701 |
}
|
|
|
1702 |
DESTROY_list ( incompl_classes, SIZE_ctype ) ;
|
|
|
1703 |
incompl_classes = NULL_list ( CLASS_TYPE ) ;
|
|
|
1704 |
return ;
|
|
|
1705 |
}
|
|
|
1706 |
|
|
|
1707 |
|
|
|
1708 |
/*
|
|
|
1709 |
ENCODE THE ALIGNMENT OF A CLASS TYPE
|
|
|
1710 |
|
|
|
1711 |
This routine adds the alignment of the class type ct to the bitstream
|
|
|
1712 |
bs. Note that ct is not compiled by this routine.
|
|
|
1713 |
*/
|
|
|
1714 |
|
|
|
1715 |
BITSTREAM *enc_al_ctype
|
|
|
1716 |
PROTO_N ( ( bs, ct ) )
|
|
|
1717 |
PROTO_T ( BITSTREAM *bs X CLASS_TYPE ct )
|
|
|
1718 |
{
|
|
|
1719 |
GRAPH gr = DEREF_graph ( ctype_base ( ct ) ) ;
|
|
|
1720 |
ulong m = DEREF_ulong ( graph_al_tag ( gr ) ) ;
|
|
|
1721 |
if ( m == LINK_NONE ) {
|
|
|
1722 |
string s = NULL ;
|
|
|
1723 |
ulong n = DEREF_ulong ( ctype_shape ( ct ) ) ;
|
|
|
1724 |
if ( n != LINK_NONE ) {
|
|
|
1725 |
/* Class already compiled */
|
|
|
1726 |
ENC_alignment ( bs ) ;
|
|
|
1727 |
bs = enc_shape_token ( bs, n ) ;
|
|
|
1728 |
return ( bs ) ;
|
|
|
1729 |
}
|
|
|
1730 |
if ( output_all ) s = mangle_typeid ( "~cpp.al.", ct ) ;
|
|
|
1731 |
m = capsule_no ( s, VAR_alignment ) ;
|
|
|
1732 |
COPY_ulong ( graph_al_tag ( gr ), m ) ;
|
|
|
1733 |
CONS_ctype ( ct, incompl_classes, incompl_classes ) ;
|
|
|
1734 |
}
|
|
|
1735 |
m = link_no ( bs, m, VAR_alignment ) ;
|
|
|
1736 |
ENC_obtain_al_tag ( bs ) ;
|
|
|
1737 |
ENC_make_al_tag ( bs, m ) ;
|
|
|
1738 |
return ( bs ) ;
|
|
|
1739 |
}
|
|
|
1740 |
|
|
|
1741 |
|
|
|
1742 |
/*
|
|
|
1743 |
COMPILE A BASE CLASS
|
|
|
1744 |
|
|
|
1745 |
This routine compiles the base class graph gr returning a token
|
|
|
1746 |
number representing the base class offset. If gr is a virtual base
|
|
|
1747 |
and ptr is true then this is the offset of the pointer to the base,
|
|
|
1748 |
otherwise it is the actual base.
|
|
|
1749 |
*/
|
|
|
1750 |
|
|
|
1751 |
static ulong compile_base
|
|
|
1752 |
PROTO_N ( ( gr, ptr ) )
|
|
|
1753 |
PROTO_T ( GRAPH gr X int ptr )
|
|
|
1754 |
{
|
|
|
1755 |
ulong n, m ;
|
|
|
1756 |
GRAPH g1, g2 ;
|
|
|
1757 |
BITSTREAM *bs ;
|
|
|
1758 |
string s = NULL ;
|
|
|
1759 |
OFFSET off = DEREF_off ( graph_off ( gr ) ) ;
|
|
|
1760 |
DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
|
|
|
1761 |
if ( ( acc & dspec_virtual ) && !ptr ) {
|
|
|
1762 |
/* Virtual base class */
|
|
|
1763 |
n = DEREF_ulong ( graph_real_off ( gr ) ) ;
|
|
|
1764 |
return ( n ) ;
|
|
|
1765 |
}
|
|
|
1766 |
if ( IS_off_base ( off ) ) {
|
|
|
1767 |
/* Direct base class */
|
|
|
1768 |
n = DEREF_ulong ( graph_base_off ( gr ) ) ;
|
|
|
1769 |
return ( n ) ;
|
|
|
1770 |
}
|
|
|
1771 |
|
|
|
1772 |
/* Check for recorded values */
|
|
|
1773 |
if ( ptr ) {
|
|
|
1774 |
n = DEREF_ulong ( graph_base_off ( gr ) ) ;
|
|
|
1775 |
} else {
|
|
|
1776 |
n = DEREF_ulong ( graph_real_off ( gr ) ) ;
|
|
|
1777 |
}
|
|
|
1778 |
if ( n != LINK_NONE ) return ( n ) ;
|
|
|
1779 |
if ( output_all ) {
|
|
|
1780 |
CONST char *pre = "~cpp.base." ;
|
|
|
1781 |
if ( ( acc & dspec_mutable ) && !ptr ) pre = "~cpp.virt." ;
|
|
|
1782 |
s = mangle_vtable ( pre, gr ) ;
|
|
|
1783 |
}
|
|
|
1784 |
n = capsule_no ( s, VAR_token ) ;
|
|
|
1785 |
|
|
|
1786 |
/* Decompose base offset */
|
|
|
1787 |
if ( acc & dspec_mutable ) {
|
|
|
1788 |
/* Base of virtual base */
|
|
|
1789 |
CLASS_TYPE cs ;
|
|
|
1790 |
g1 = DEREF_graph ( graph_up ( gr ) ) ;
|
|
|
1791 |
cs = DEREF_ctype ( graph_head ( g1 ) ) ;
|
|
|
1792 |
g2 = DEREF_graph ( ctype_base ( cs ) ) ;
|
|
|
1793 |
g2 = find_subgraph ( g2, g1, gr ) ;
|
|
|
1794 |
if ( ptr ) {
|
|
|
1795 |
COPY_ulong ( graph_base_off ( gr ), n ) ;
|
|
|
1796 |
} else {
|
|
|
1797 |
COPY_ulong ( graph_real_off ( gr ), n ) ;
|
|
|
1798 |
}
|
|
|
1799 |
} else {
|
|
|
1800 |
/* Indirect base */
|
|
|
1801 |
OFFSET off1 = DEREF_off ( off_deriv_direct ( off ) ) ;
|
|
|
1802 |
OFFSET off2 = DEREF_off ( off_deriv_indirect ( off ) ) ;
|
|
|
1803 |
g1 = DEREF_graph ( off_base_graph ( off1 ) ) ;
|
|
|
1804 |
if ( IS_off_base ( off2 ) ) {
|
|
|
1805 |
g2 = DEREF_graph ( off_base_graph ( off2 ) ) ;
|
|
|
1806 |
} else {
|
|
|
1807 |
g2 = DEREF_graph ( off_deriv_graph ( off2 ) ) ;
|
|
|
1808 |
}
|
|
|
1809 |
COPY_ulong ( graph_base_off ( gr ), n ) ;
|
|
|
1810 |
COPY_ulong ( graph_real_off ( gr ), n ) ;
|
|
|
1811 |
}
|
|
|
1812 |
|
|
|
1813 |
/* Define the token */
|
|
|
1814 |
bs = enc_tokdef_start ( n, "E", NIL ( ulong ), 1 ) ;
|
|
|
1815 |
ENC_offset_add ( bs ) ;
|
|
|
1816 |
m = compile_base ( g1, 0 ) ;
|
|
|
1817 |
bs = enc_exp_token ( bs, m ) ;
|
|
|
1818 |
m = compile_base ( g2, ptr ) ;
|
|
|
1819 |
bs = enc_exp_token ( bs, m ) ;
|
|
|
1820 |
enc_tokdef_end ( n, bs ) ;
|
|
|
1821 |
return ( n ) ;
|
|
|
1822 |
}
|
|
|
1823 |
|
|
|
1824 |
|
|
|
1825 |
/*
|
|
|
1826 |
ENCODE A BASE CLASS OFFSET
|
|
|
1827 |
|
|
|
1828 |
This routine adds an offset representing the base class graph gr
|
|
|
1829 |
to the bitstream bs. For virtual bases this is the offset of the
|
|
|
1830 |
pointer to the base if ptr is true and the offset of the actual base
|
|
|
1831 |
otherwise.
|
|
|
1832 |
*/
|
|
|
1833 |
|
|
|
1834 |
BITSTREAM *enc_base
|
|
|
1835 |
PROTO_N ( ( bs, gr, ptr ) )
|
|
|
1836 |
PROTO_T ( BITSTREAM *bs X GRAPH gr X int ptr )
|
|
|
1837 |
{
|
|
|
1838 |
GRAPH gt = DEREF_graph ( graph_top ( gr ) ) ;
|
|
|
1839 |
CLASS_TYPE ct = DEREF_ctype ( graph_head ( gt ) ) ;
|
|
|
1840 |
if ( EQ_graph ( gr, gt ) ) {
|
|
|
1841 |
ENC_offset_zero ( bs ) ;
|
|
|
1842 |
bs = enc_al_ctype ( bs, ct ) ;
|
|
|
1843 |
} else {
|
|
|
1844 |
ulong n ;
|
|
|
1845 |
IGNORE compile_class ( ct ) ;
|
|
|
1846 |
n = compile_base ( gr, ptr ) ;
|
|
|
1847 |
bs = enc_exp_token ( bs, n ) ;
|
|
|
1848 |
}
|
|
|
1849 |
return ( bs ) ;
|
|
|
1850 |
}
|
|
|
1851 |
|
|
|
1852 |
|
|
|
1853 |
/*
|
|
|
1854 |
ENCODE THE START OF A VIRTUAL BASE CLASS POINTER EXPRESSION
|
|
|
1855 |
|
|
|
1856 |
This routine adds the start of a virtual base class pointer expression
|
|
|
1857 |
to the bitstream bs. off1 gives the direct component of the offset
|
|
|
1858 |
and off2 gives the indirect component.
|
|
|
1859 |
*/
|
|
|
1860 |
|
|
|
1861 |
BITSTREAM *enc_add_base
|
|
|
1862 |
PROTO_N ( ( bs, off1, off2 ) )
|
|
|
1863 |
PROTO_T ( BITSTREAM *bs X OFFSET off1 X OFFSET off2 )
|
|
|
1864 |
{
|
|
|
1865 |
GRAPH gr = DEREF_graph ( off_base_graph ( off1 ) ) ;
|
|
|
1866 |
DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
|
|
|
1867 |
if ( !IS_NULL_off ( off2 ) ) {
|
|
|
1868 |
if ( IS_off_deriv ( off2 ) ) {
|
|
|
1869 |
OFFSET off3 = DEREF_off ( off_deriv_direct ( off2 ) ) ;
|
|
|
1870 |
OFFSET off4 = DEREF_off ( off_deriv_indirect ( off2 ) ) ;
|
|
|
1871 |
bs = enc_add_base ( bs, off3, off4 ) ;
|
|
|
1872 |
} else {
|
|
|
1873 |
bs = enc_add_base ( bs, off2, NULL_off ) ;
|
|
|
1874 |
}
|
|
|
1875 |
}
|
|
|
1876 |
if ( acc & dspec_virtual ) {
|
|
|
1877 |
/* Indirection for virtual bases */
|
|
|
1878 |
CLASS_TYPE ct = DEREF_ctype ( graph_head ( gr ) ) ;
|
|
|
1879 |
ENC_contents ( bs ) ;
|
|
|
1880 |
ENC_pointer ( bs ) ;
|
|
|
1881 |
bs = enc_al_ctype ( bs, ct ) ;
|
|
|
1882 |
}
|
|
|
1883 |
if ( !( acc & dspec_ignore ) ) {
|
|
|
1884 |
/* Add base class offset */
|
|
|
1885 |
ENC_add_to_ptr ( bs ) ;
|
|
|
1886 |
}
|
|
|
1887 |
return ( bs ) ;
|
|
|
1888 |
}
|
|
|
1889 |
|
|
|
1890 |
|
|
|
1891 |
/*
|
|
|
1892 |
ENCODE THE END OF A VIRTUAL BASE CLASS POINTER EXPRESSION
|
|
|
1893 |
|
|
|
1894 |
This routine adds the end of a virtual base class pointer expression
|
|
|
1895 |
to the bitstream bs. off1 gives the direct component of the offset
|
|
|
1896 |
and off2 gives the indirect component.
|
|
|
1897 |
*/
|
|
|
1898 |
|
|
|
1899 |
BITSTREAM *enc_end_base
|
|
|
1900 |
PROTO_N ( ( bs, off1, off2 ) )
|
|
|
1901 |
PROTO_T ( BITSTREAM *bs X OFFSET off1 X OFFSET off2 )
|
|
|
1902 |
{
|
|
|
1903 |
GRAPH gr = DEREF_graph ( off_base_graph ( off1 ) ) ;
|
|
|
1904 |
DECL_SPEC acc = DEREF_dspec ( graph_access ( gr ) ) ;
|
|
|
1905 |
if ( !( acc & dspec_ignore ) ) {
|
|
|
1906 |
/* Output base class offset */
|
|
|
1907 |
ulong n = DEREF_ulong ( graph_base_off ( gr ) ) ;
|
|
|
1908 |
if ( n == LINK_NONE ) {
|
|
|
1909 |
/* Compile class if necessary */
|
|
|
1910 |
GRAPH gt = DEREF_graph ( graph_top ( gr ) ) ;
|
|
|
1911 |
CLASS_TYPE ct = DEREF_ctype ( graph_head ( gt ) ) ;
|
|
|
1912 |
IGNORE compile_class ( ct ) ;
|
|
|
1913 |
n = DEREF_ulong ( graph_base_off ( gr ) ) ;
|
|
|
1914 |
}
|
|
|
1915 |
bs = enc_exp_token ( bs, n ) ;
|
|
|
1916 |
}
|
|
|
1917 |
if ( !IS_NULL_off ( off2 ) ) {
|
|
|
1918 |
if ( IS_off_deriv ( off2 ) ) {
|
|
|
1919 |
OFFSET off3 = DEREF_off ( off_deriv_direct ( off2 ) ) ;
|
|
|
1920 |
OFFSET off4 = DEREF_off ( off_deriv_indirect ( off2 ) ) ;
|
|
|
1921 |
bs = enc_end_base ( bs, off3, off4 ) ;
|
|
|
1922 |
} else {
|
|
|
1923 |
bs = enc_end_base ( bs, off2, NULL_off ) ;
|
|
|
1924 |
}
|
|
|
1925 |
}
|
|
|
1926 |
return ( bs ) ;
|
|
|
1927 |
}
|
|
|
1928 |
|
|
|
1929 |
|
|
|
1930 |
/*
|
|
|
1931 |
ENCODE A MEMBER OFFSET
|
|
|
1932 |
|
|
|
1933 |
This routine adds the offset of the member id to the bitstream bs.
|
|
|
1934 |
If id is a data member this is the offset of the member from the start
|
|
|
1935 |
of the structure.
|
|
|
1936 |
*/
|
|
|
1937 |
|
|
|
1938 |
BITSTREAM *enc_member
|
|
|
1939 |
PROTO_N ( ( bs, id ) )
|
|
|
1940 |
PROTO_T ( BITSTREAM *bs X IDENTIFIER id )
|
|
|
1941 |
{
|
|
|
1942 |
ulong tok ;
|
|
|
1943 |
unsigned tag = TAG_id ( id ) ;
|
|
|
1944 |
if ( tag == id_member_tag ) {
|
|
|
1945 |
/* Simple data member */
|
|
|
1946 |
OFFSET off = DEREF_off ( id_member_off ( id ) ) ;
|
|
|
1947 |
if ( IS_off_member ( off ) ) {
|
|
|
1948 |
tok = DEREF_ulong ( id_no ( id ) ) ;
|
|
|
1949 |
if ( tok == LINK_NONE ) {
|
|
|
1950 |
CLASS_TYPE ct = parent_class ( id ) ;
|
|
|
1951 |
IGNORE compile_class ( ct ) ;
|
|
|
1952 |
tok = DEREF_ulong ( id_no ( id ) ) ;
|
|
|
1953 |
}
|
|
|
1954 |
if ( tok == LINK_ZERO ) {
|
|
|
1955 |
/* Union member */
|
|
|
1956 |
TYPE t = DEREF_type ( id_member_type ( id ) ) ;
|
|
|
1957 |
ENC_offset_zero ( bs ) ;
|
|
|
1958 |
bs = enc_alignment ( bs, t ) ;
|
|
|
1959 |
} else {
|
|
|
1960 |
/* Structure member */
|
|
|
1961 |
bs = enc_exp_token ( bs, tok ) ;
|
|
|
1962 |
}
|
|
|
1963 |
} else {
|
|
|
1964 |
bs = enc_offset ( bs, off ) ;
|
|
|
1965 |
}
|
|
|
1966 |
} else {
|
|
|
1967 |
/* Static data members and member functions */
|
|
|
1968 |
IGNORE capsule_id ( id, VAR_tag ) ;
|
|
|
1969 |
tok = unit_no ( bs, id, VAR_tag, 0 ) ;
|
|
|
1970 |
ENC_obtain_tag ( bs ) ;
|
|
|
1971 |
ENC_make_tag ( bs, tok ) ;
|
|
|
1972 |
}
|
|
|
1973 |
return ( bs ) ;
|
|
|
1974 |
}
|
|
|
1975 |
|
|
|
1976 |
|
|
|
1977 |
/*
|
|
|
1978 |
ENCODE A NULL CLASS OBJECT DEFINITION
|
|
|
1979 |
|
|
|
1980 |
This routine adds an expression representing a null value of type
|
|
|
1981 |
ct to the bitstream bs. The virtual base components are only
|
|
|
1982 |
included if virt is true. Note that the order of the components
|
|
|
1983 |
is not necessarily the same as that in compile_class, but the
|
|
|
1984 |
installers always sort make_compound expressions into the correct
|
|
|
1985 |
order.
|
|
|
1986 |
*/
|
|
|
1987 |
|
|
|
1988 |
static BITSTREAM *enc_null_class_aux
|
|
|
1989 |
PROTO_N ( ( bs, ct, virt ) )
|
|
|
1990 |
PROTO_T ( BITSTREAM *bs X CLASS_TYPE ct X int virt )
|
|
|
1991 |
{
|
|
|
1992 |
CLASS_INFO ci = DEREF_cinfo ( ctype_info ( ct ) ) ;
|
|
|
1993 |
if ( ci & ( cinfo_empty | cinfo_token ) ) {
|
|
|
1994 |
/* Tokenised and empty classes */
|
|
|
1995 |
ENC_make_value ( bs ) ;
|
|
|
1996 |
bs = enc_ctype ( bs, ct ) ;
|
|
|
1997 |
} else {
|
|
|
1998 |
/* Non-empty classes */
|
|
|
1999 |
MEMBER mem ;
|
|
|
2000 |
unsigned no_mems = 0 ;
|
|
|
2001 |
GRAPH gr = DEREF_graph ( ctype_base ( ct ) ) ;
|
|
|
2002 |
LIST ( GRAPH ) br = DEREF_list ( graph_tails ( gr ) ) ;
|
|
|
2003 |
LIST ( GRAPH ) bv = DEREF_list ( ctype_vbase ( ct ) ) ;
|
|
|
2004 |
NAMESPACE ns = DEREF_nspace ( ctype_member ( ct ) ) ;
|
|
|
2005 |
BITSTREAM *ts = start_bitstream ( NIL ( FILE ), bs->link ) ;
|
|
|
2006 |
|
|
|
2007 |
/* Scan through direct base classes */
|
|
|
2008 |
while ( !IS_NULL_list ( br ) ) {
|
|
|
2009 |
GRAPH gs = DEREF_graph ( HEAD_list ( br ) ) ;
|
|
|
2010 |
DECL_SPEC acc = DEREF_dspec ( graph_access ( gs ) ) ;
|
|
|
2011 |
CLASS_TYPE cs = DEREF_ctype ( graph_head ( gs ) ) ;
|
|
|
2012 |
ulong m = DEREF_ulong ( graph_base_off ( gs ) ) ;
|
|
|
2013 |
if ( acc & dspec_virtual ) {
|
|
|
2014 |
ts = enc_exp_token ( ts, m ) ;
|
|
|
2015 |
ENC_make_null_ptr ( ts ) ;
|
|
|
2016 |
ts = enc_al_ctype ( ts, cs ) ;
|
|
|
2017 |
no_mems++ ;
|
|
|
2018 |
} else {
|
|
|
2019 |
CLASS_INFO cj = DEREF_cinfo ( ctype_info ( cs ) ) ;
|
|
|
2020 |
if ( !( cj & cinfo_empty ) ) {
|
|
|
2021 |
ts = enc_exp_token ( ts, m ) ;
|
|
|
2022 |
ts = enc_null_class_aux ( ts, cs, 0 ) ;
|
|
|
2023 |
no_mems++ ;
|
|
|
2024 |
}
|
|
|
2025 |
}
|
|
|
2026 |
br = TAIL_list ( br ) ;
|
|
|
2027 |
}
|
|
|
2028 |
|
|
|
2029 |
/* Scan through data members */
|
|
|
2030 |
mem = DEREF_member ( nspace_ctype_first ( ns ) ) ;
|
|
|
2031 |
mem = next_data_member ( mem, 0 ) ;
|
|
|
2032 |
while ( !IS_NULL_member ( mem ) ) {
|
|
|
2033 |
IDENTIFIER mid = DEREF_id ( member_id ( mem ) ) ;
|
|
|
2034 |
TYPE s = DEREF_type ( id_member_type ( mid ) ) ;
|
|
|
2035 |
ts = enc_member ( ts, mid ) ;
|
|
|
2036 |
ts = enc_null_exp ( ts, s ) ;
|
|
|
2037 |
no_mems++ ;
|
|
|
2038 |
if ( ci & cinfo_union ) break ;
|
|
|
2039 |
mem = DEREF_member ( member_next ( mem ) ) ;
|
|
|
2040 |
mem = next_data_member ( mem, 0 ) ;
|
|
|
2041 |
}
|
|
|
2042 |
|
|
|
2043 |
/* Scan through virtual function tables */
|
|
|
2044 |
#if LANGUAGE_CPP
|
|
|
2045 |
if ( ci & cinfo_polymorphic ) {
|
|
|
2046 |
VIRTUAL vt = DEREF_virt ( ctype_virt ( ct ) ) ;
|
|
|
2047 |
while ( !IS_NULL_virt ( vt ) ) {
|
|
|
2048 |
OFFSET off = DEREF_off ( virt_table_off ( vt ) ) ;
|
|
|
2049 |
if ( IS_NULL_off ( off ) ) {
|
|
|
2050 |
ulong m = DEREF_ulong ( virt_table_tok ( vt ) ) ;
|
|
|
2051 |
ts = enc_exp_token ( ts, m ) ;
|
|
|
2052 |
size_dummy_vtab = DEREF_ulong ( virt_no ( vt ) ) ;
|
|
|
2053 |
ts = enc_null_exp ( ts, ptr_dummy_vtab ) ;
|
|
|
2054 |
no_mems++ ;
|
|
|
2055 |
}
|
|
|
2056 |
vt = DEREF_virt ( virt_next ( vt ) ) ;
|
|
|
2057 |
}
|
|
|
2058 |
}
|
|
|
2059 |
#endif
|
|
|
2060 |
|
|
|
2061 |
/* Scan through virtual bases */
|
|
|
2062 |
if ( virt ) {
|
|
|
2063 |
while ( !IS_NULL_list ( bv ) ) {
|
|
|
2064 |
GRAPH gs = DEREF_graph ( HEAD_list ( bv ) ) ;
|
|
|
2065 |
CLASS_TYPE cs = DEREF_ctype ( graph_head ( gs ) ) ;
|
|
|
2066 |
CLASS_INFO cj = DEREF_cinfo ( ctype_info ( cs ) ) ;
|
|
|
2067 |
if ( !( cj & cinfo_empty ) ) {
|
|
|
2068 |
ulong m = DEREF_ulong ( graph_real_off ( gs ) ) ;
|
|
|
2069 |
ts = enc_exp_token ( ts, m ) ;
|
|
|
2070 |
ts = enc_null_class_aux ( ts, cs, 0 ) ;
|
|
|
2071 |
no_mems++ ;
|
|
|
2072 |
}
|
|
|
2073 |
bv = TAIL_list ( bv ) ;
|
|
|
2074 |
}
|
|
|
2075 |
} else {
|
|
|
2076 |
if ( IS_NULL_list ( bv ) ) virt = 1 ;
|
|
|
2077 |
}
|
|
|
2078 |
|
|
|
2079 |
/* Encode complete construct */
|
|
|
2080 |
if ( no_mems ) {
|
|
|
2081 |
ENC_make_compound ( bs ) ;
|
|
|
2082 |
if ( virt ) {
|
|
|
2083 |
ENC_shape_offset ( bs ) ;
|
|
|
2084 |
bs = enc_ctype ( bs, ct ) ;
|
|
|
2085 |
} else {
|
|
|
2086 |
ulong m = DEREF_ulong ( graph_core_off ( gr ) ) ;
|
|
|
2087 |
if ( m == LINK_NONE ) {
|
|
|
2088 |
ENC_shape_offset ( bs ) ;
|
|
|
2089 |
bs = enc_ctype ( bs, ct ) ;
|
|
|
2090 |
} else {
|
|
|
2091 |
bs = enc_exp_token ( bs, m ) ;
|
|
|
2092 |
}
|
|
|
2093 |
}
|
|
|
2094 |
ENC_LIST ( bs, no_mems + no_mems ) ;
|
|
|
2095 |
bs = join_bitstreams ( bs, ts ) ;
|
|
|
2096 |
} else {
|
|
|
2097 |
ENC_make_value ( bs ) ;
|
|
|
2098 |
bs = enc_ctype ( bs, ct ) ;
|
|
|
2099 |
end_bitstream ( ts, 0 ) ;
|
|
|
2100 |
}
|
|
|
2101 |
}
|
|
|
2102 |
return ( bs ) ;
|
|
|
2103 |
}
|
|
|
2104 |
|
|
|
2105 |
|
|
|
2106 |
/*
|
|
|
2107 |
ENCODE A NULL CLASS OBJECT
|
|
|
2108 |
|
|
|
2109 |
This routine adds the default null value for the class type ct to the
|
|
|
2110 |
bitstream bs. This is represented by a token which is defined the
|
|
|
2111 |
first time the routine is called.
|
|
|
2112 |
*/
|
|
|
2113 |
|
|
|
2114 |
BITSTREAM *enc_null_class
|
|
|
2115 |
PROTO_N ( ( bs, ct ) )
|
|
|
2116 |
PROTO_T ( BITSTREAM *bs X CLASS_TYPE ct )
|
|
|
2117 |
{
|
|
|
2118 |
ulong n = DEREF_ulong ( ctype_null_exp ( ct ) ) ;
|
|
|
2119 |
if ( n == LINK_NONE ) {
|
|
|
2120 |
/* Define token for null value */
|
|
|
2121 |
BITSTREAM *ts ;
|
|
|
2122 |
string s = NULL ;
|
|
|
2123 |
IGNORE compile_class ( ct ) ;
|
|
|
2124 |
if ( output_all ) s = mangle_typeid ( "~cpp.null.", ct ) ;
|
|
|
2125 |
n = capsule_no ( s, VAR_token ) ;
|
|
|
2126 |
COPY_ulong ( ctype_null_exp ( ct ), n ) ;
|
|
|
2127 |
ts = enc_tokdef_start ( n, "E", NIL ( ulong ), 1 ) ;
|
|
|
2128 |
ts = enc_null_class_aux ( ts, ct, 1 ) ;
|
|
|
2129 |
enc_tokdef_end ( n, ts ) ;
|
|
|
2130 |
}
|
|
|
2131 |
bs = enc_exp_token ( bs, n ) ;
|
|
|
2132 |
return ( bs ) ;
|
|
|
2133 |
}
|
|
|
2134 |
|
|
|
2135 |
|
|
|
2136 |
/*
|
|
|
2137 |
CONSTRUCTOR INITIALISER ROUTINES
|
|
|
2138 |
|
|
|
2139 |
The constructor initialiser routines are only included in the C++
|
|
|
2140 |
producer.
|
|
|
2141 |
*/
|
|
|
2142 |
|
|
|
2143 |
#if LANGUAGE_CPP
|
|
|
2144 |
|
|
|
2145 |
|
|
|
2146 |
/*
|
|
|
2147 |
ENCODE A CONSTRUCTOR INITIALISER
|
|
|
2148 |
|
|
|
2149 |
This routine performs a construct initialisation using a at offset
|
|
|
2150 |
off from the tag m. virt controls how m is accessed. Note that a
|
|
|
2151 |
may be a dummy expression to indicate that m is initialised from
|
|
|
2152 |
the corresponding offset from the second argument in a copy
|
|
|
2153 |
constructor or assignment operator (see init_empty_base).
|
|
|
2154 |
*/
|
|
|
2155 |
|
|
|
2156 |
static BITSTREAM *enc_ctor_exp
|
|
|
2157 |
PROTO_N ( ( bs, a, off, m, virt, seq ) )
|
|
|
2158 |
PROTO_T ( BITSTREAM *bs X EXP a X OFFSET off X ulong m X
|
|
|
2159 |
int virt X unsigned seq )
|
|
|
2160 |
{
|
|
|
2161 |
if ( !IS_NULL_exp ( a ) ) {
|
|
|
2162 |
int context = 0 ;
|
|
|
2163 |
EXP d = NULL_exp ;
|
|
|
2164 |
TYPE s = DEREF_type ( exp_type ( a ) ) ;
|
|
|
2165 |
if ( IS_exp_paren ( a ) ) {
|
|
|
2166 |
/* Used to mark destructors - see destr_init */
|
|
|
2167 |
if ( seq > 1 ) {
|
|
|
2168 |
context = 5 ;
|
|
|
2169 |
d = a ;
|
|
|
2170 |
}
|
|
|
2171 |
a = DEREF_exp ( exp_paren_arg ( a ) ) ;
|
|
|
2172 |
}
|
|
|
2173 |
if ( IS_NULL_exp ( a ) ) {
|
|
|
2174 |
/* EMPTY */
|
|
|
2175 |
} else if ( IS_exp_value ( a ) ) {
|
|
|
2176 |
/* Copy assignment */
|
|
|
2177 |
int bf = 0 ;
|
|
|
2178 |
TYPE t = DEREF_type ( exp_type ( a ) ) ;
|
|
|
2179 |
bs = enc_assign_op ( bs, t, &bf ) ;
|
|
|
2180 |
if ( bf ) {
|
|
|
2181 |
/* Bitfield assignment */
|
|
|
2182 |
OFFSET off1 = off ;
|
|
|
2183 |
OFFSET off2 = decons_bitf_off ( &off1 ) ;
|
|
|
2184 |
bs = enc_dummy_exp ( bs, t, m, off1, 0, virt ) ;
|
|
|
2185 |
bs = enc_offset ( bs, off2 ) ;
|
|
|
2186 |
} else {
|
|
|
2187 |
/* Non-bitfield assignment */
|
|
|
2188 |
bs = enc_dummy_exp ( bs, t, m, off, 0, virt ) ;
|
|
|
2189 |
}
|
|
|
2190 |
last_conts [ DUMMY_copy ] = 1 ;
|
|
|
2191 |
bs = enc_dummy_exp ( bs, t, LINK_NONE, off, DUMMY_copy, 1 ) ;
|
|
|
2192 |
last_conts [ DUMMY_copy ] = 0 ;
|
|
|
2193 |
seq-- ;
|
|
|
2194 |
} else {
|
|
|
2195 |
/* Constructor initialiser */
|
|
|
2196 |
bs = enc_init_tag ( bs, m, off, 0, s, a, d, context ) ;
|
|
|
2197 |
if ( !IS_NULL_exp ( d ) ) {
|
|
|
2198 |
d = NULL_exp ;
|
|
|
2199 |
seq-- ;
|
|
|
2200 |
}
|
|
|
2201 |
seq-- ;
|
|
|
2202 |
}
|
|
|
2203 |
if ( !IS_NULL_exp ( d ) ) {
|
|
|
2204 |
/* Increase constructor count */
|
|
|
2205 |
bs = enc_destr_count ( bs, s, 1 ) ;
|
|
|
2206 |
seq-- ;
|
|
|
2207 |
}
|
|
|
2208 |
}
|
|
|
2209 |
while ( seq ) {
|
|
|
2210 |
ENC_make_top ( bs ) ;
|
|
|
2211 |
seq-- ;
|
|
|
2212 |
}
|
|
|
2213 |
return ( bs ) ;
|
|
|
2214 |
}
|
|
|
2215 |
|
|
|
2216 |
|
|
|
2217 |
/*
|
|
|
2218 |
INITIALISE VIRTUAL BASE POINTERS
|
|
|
2219 |
|
|
|
2220 |
This routine adds a list of virtual base pointer initialisations
|
|
|
2221 |
for an object with tag number m and class ct to the bitstream bs.
|
|
|
2222 |
*/
|
|
|
2223 |
|
|
|
2224 |
static BITSTREAM *enc_virt_init
|
|
|
2225 |
PROTO_N ( ( bs, ct, m ) )
|
|
|
2226 |
PROTO_T ( BITSTREAM *bs X CLASS_TYPE ct X ulong m )
|
|
|
2227 |
{
|
|
|
2228 |
LIST ( GRAPH ) bv = DEREF_list ( ctype_vbase ( ct ) ) ;
|
|
|
2229 |
while ( !IS_NULL_list ( bv ) ) {
|
|
|
2230 |
GRAPH gr = DEREF_graph ( HEAD_list ( bv ) ) ;
|
|
|
2231 |
ulong tv = DEREF_ulong ( graph_real_off ( gr ) ) ;
|
|
|
2232 |
while ( !IS_NULL_graph ( gr ) ) {
|
|
|
2233 |
ulong tp = compile_base ( gr, 1 ) ;
|
|
|
2234 |
ENC_assign ( bs ) ;
|
|
|
2235 |
ENC_add_to_ptr ( bs ) ;
|
|
|
2236 |
ENC_obtain_tag ( bs ) ;
|
|
|
2237 |
ENC_make_tag ( bs, m ) ;
|
|
|
2238 |
bs = enc_exp_token ( bs, tp ) ;
|
|
|
2239 |
ENC_add_to_ptr ( bs ) ;
|
|
|
2240 |
ENC_obtain_tag ( bs ) ;
|
|
|
2241 |
ENC_make_tag ( bs, m ) ;
|
|
|
2242 |
bs = enc_exp_token ( bs, tv ) ;
|
|
|
2243 |
gr = DEREF_graph ( graph_equal ( gr ) ) ;
|
|
|
2244 |
}
|
|
|
2245 |
bv = TAIL_list ( bv ) ;
|
|
|
2246 |
}
|
|
|
2247 |
return ( bs ) ;
|
|
|
2248 |
}
|
|
|
2249 |
|
|
|
2250 |
|
|
|
2251 |
/*
|
|
|
2252 |
INITIALISE VIRTUAL FUNCTION TABLES
|
|
|
2253 |
|
|
|
2254 |
This routine adds a list of virtual function table initialisations
|
|
|
2255 |
for an object with tag number m and class ct to the bitstream bs.
|
|
|
2256 |
*/
|
|
|
2257 |
|
|
|
2258 |
static BITSTREAM *enc_vtab_init
|
|
|
2259 |
PROTO_N ( ( bs, ct, m, virt ) )
|
|
|
2260 |
PROTO_T ( BITSTREAM *bs X CLASS_TYPE ct X ulong m X int virt )
|
|
|
2261 |
{
|
|
|
2262 |
VIRTUAL vt = DEREF_virt ( ctype_virt ( ct ) ) ;
|
|
|
2263 |
while ( !IS_NULL_virt ( vt ) ) {
|
|
|
2264 |
OFFSET off = DEREF_off ( virt_table_off ( vt ) ) ;
|
|
|
2265 |
ulong tv = DEREF_ulong ( virt_table_tok ( vt ) ) ;
|
|
|
2266 |
ulong tt = DEREF_ulong ( virt_table_tbl ( vt ) ) ;
|
|
|
2267 |
record_usage ( tt, VAR_tag, USAGE_USE ) ;
|
|
|
2268 |
ENC_assign ( bs ) ;
|
|
|
2269 |
ENC_add_to_ptr ( bs ) ;
|
|
|
2270 |
if ( is_zero_offset ( off ) ) {
|
|
|
2271 |
ENC_obtain_tag ( bs ) ;
|
|
|
2272 |
ENC_make_tag ( bs, m ) ;
|
|
|
2273 |
} else {
|
|
|
2274 |
TYPE t = ptr_dummy_class ;
|
|
|
2275 |
bs = enc_dummy_exp ( bs, t, m, off, 0, virt ) ;
|
|
|
2276 |
}
|
|
|
2277 |
bs = enc_exp_token ( bs, tv ) ;
|
|
|
2278 |
tt = link_no ( bs, tt, VAR_tag ) ;
|
|
|
2279 |
ENC_obtain_tag ( bs ) ;
|
|
|
2280 |
ENC_make_tag ( bs, tt ) ;
|
|
|
2281 |
vt = DEREF_virt ( virt_next ( vt ) ) ;
|
|
|
2282 |
}
|
|
|
2283 |
return ( bs ) ;
|
|
|
2284 |
}
|
|
|
2285 |
|
|
|
2286 |
|
|
|
2287 |
/*
|
|
|
2288 |
DELETE AN OBJECT
|
|
|
2289 |
|
|
|
2290 |
This routine adds the conditional deletion for an object with tag
|
|
|
2291 |
number m and class ct to the bitstream bs.
|
|
|
2292 |
*/
|
|
|
2293 |
|
|
|
2294 |
static BITSTREAM *enc_delete_obj
|
|
|
2295 |
PROTO_N ( ( bs, ct, m ) )
|
|
|
2296 |
PROTO_T ( BITSTREAM *bs X CLASS_TYPE ct X ulong m )
|
|
|
2297 |
{
|
|
|
2298 |
IDENTIFIER cid = DEREF_id ( ctype_name ( ct ) ) ;
|
|
|
2299 |
TYPE t = DEREF_type ( id_class_name_etc_defn ( cid ) ) ;
|
|
|
2300 |
IDENTIFIER fid = find_allocator ( t, lex_delete, 0, NULL_id ) ;
|
|
|
2301 |
if ( IS_NULL_id ( fid ) ) {
|
|
|
2302 |
/* This shouldn't happen */
|
|
|
2303 |
ENC_make_top ( bs ) ;
|
|
|
2304 |
} else {
|
|
|
2305 |
ulong d ;
|
|
|
2306 |
BITSTREAM *ts ;
|
|
|
2307 |
TYPE fn = DEREF_type ( id_function_etc_type ( fid ) ) ;
|
|
|
2308 |
LIST ( TYPE ) ptypes = DEREF_list ( type_func_ptypes ( fn ) ) ;
|
|
|
2309 |
unsigned npids = LENGTH_list ( ptypes ) ;
|
|
|
2310 |
|
|
|
2311 |
/* Mark the function as to be compiled */
|
|
|
2312 |
IGNORE capsule_id ( fid, VAR_tag ) ;
|
|
|
2313 |
CONS_id ( fid, pending_funcs, pending_funcs ) ;
|
|
|
2314 |
|
|
|
2315 |
/* Encode the function call */
|
|
|
2316 |
ENC_apply_proc ( bs ) ;
|
|
|
2317 |
ENC_top ( bs ) ;
|
|
|
2318 |
ENC_obtain_tag ( bs ) ;
|
|
|
2319 |
d = unit_no ( bs, fid, VAR_tag, 0 ) ;
|
|
|
2320 |
ENC_make_tag ( bs, d ) ;
|
|
|
2321 |
if ( npids > 2 ) npids = 2 ;
|
|
|
2322 |
ENC_LIST_SMALL ( bs, npids ) ;
|
|
|
2323 |
bs = enc_special ( bs, TOK_to_ptr_void ) ;
|
|
|
2324 |
ts = start_bitstream ( NIL ( FILE ), bs->link ) ;
|
|
|
2325 |
ts = enc_al_ctype ( ts, ct ) ;
|
|
|
2326 |
ENC_obtain_tag ( ts ) ;
|
|
|
2327 |
ENC_make_tag ( ts, m ) ;
|
|
|
2328 |
bs = enc_bitstream ( bs, ts ) ;
|
|
|
2329 |
if ( npids == 2 ) {
|
|
|
2330 |
/* Allow for second argument */
|
|
|
2331 |
TYPE s ;
|
|
|
2332 |
TYPE c = type_char ;
|
|
|
2333 |
ptypes = TAIL_list ( ptypes ) ;
|
|
|
2334 |
s = DEREF_type ( HEAD_list ( ptypes ) ) ;
|
|
|
2335 |
if ( !IS_type_integer ( s ) ) s = type_size_t ;
|
|
|
2336 |
ENC_offset_div ( bs ) ;
|
|
|
2337 |
bs = enc_variety ( bs, s ) ;
|
|
|
2338 |
bs = enc_shape_offset ( bs, t ) ;
|
|
|
2339 |
bs = enc_shape_offset ( bs, c ) ;
|
|
|
2340 |
}
|
|
|
2341 |
ENC_OFF ( bs ) ;
|
|
|
2342 |
}
|
|
|
2343 |
return ( bs ) ;
|
|
|
2344 |
}
|
|
|
2345 |
|
|
|
2346 |
|
|
|
2347 |
/*
|
|
|
2348 |
ENCODE A LIST OF CONSTRUCTOR INITIALISERS
|
|
|
2349 |
|
|
|
2350 |
This routine adds the list of constructor initialisers given by e
|
|
|
2351 |
to the bitstream bs.
|
|
|
2352 |
*/
|
|
|
2353 |
|
|
|
2354 |
BITSTREAM *enc_ctor_init
|
|
|
2355 |
PROTO_N ( ( bs, e ) )
|
|
|
2356 |
PROTO_T ( BITSTREAM *bs X EXP e )
|
|
|
2357 |
{
|
|
|
2358 |
ulong n, m ;
|
|
|
2359 |
CLASS_TYPE ct = last_class ;
|
|
|
2360 |
int kind = DEREF_int ( exp_initialiser_kind ( e ) ) ;
|
|
|
2361 |
LIST ( EXP ) p = DEREF_list ( exp_initialiser_args ( e ) ) ;
|
|
|
2362 |
LIST ( OFFSET ) q = DEREF_list ( exp_initialiser_offs ( e ) ) ;
|
|
|
2363 |
|
|
|
2364 |
/* Find number of items */
|
|
|
2365 |
unsigned np = LENGTH_list ( p ) ;
|
|
|
2366 |
unsigned nv = DEREF_unsigned ( exp_initialiser_virt ( e ) ) ;
|
|
|
2367 |
unsigned nb = DEREF_unsigned ( exp_initialiser_base ( e ) ) ;
|
|
|
2368 |
unsigned no = np - nv ;
|
|
|
2369 |
|
|
|
2370 |
/* Compile the class */
|
|
|
2371 |
IGNORE compile_class ( ct ) ;
|
|
|
2372 |
|
|
|
2373 |
/* Find the 'this' pointer */
|
|
|
2374 |
n = last_params [ DUMMY_this ] ;
|
|
|
2375 |
m = unit_no ( bs, NULL_id, VAR_tag, 1 ) ;
|
|
|
2376 |
ENC_identify ( bs ) ;
|
|
|
2377 |
bs = enc_access ( bs, crt_func_access ) ;
|
|
|
2378 |
ENC_make_tag ( bs, m ) ;
|
|
|
2379 |
ENC_contents ( bs ) ;
|
|
|
2380 |
ENC_pointer ( bs ) ;
|
|
|
2381 |
bs = enc_al_ctype ( bs, ct ) ;
|
|
|
2382 |
ENC_obtain_tag ( bs ) ;
|
|
|
2383 |
ENC_make_tag ( bs, n ) ;
|
|
|
2384 |
|
|
|
2385 |
if ( kind == DEFAULT_DESTR ) {
|
|
|
2386 |
/* Deal with destructors */
|
|
|
2387 |
int context = 0 ;
|
|
|
2388 |
unsigned ns = no + 1 ;
|
|
|
2389 |
ulong m2 = last_params [ DUMMY_extra ] ;
|
|
|
2390 |
if ( last_params [ DUMMY_count ] != LINK_NONE ) {
|
|
|
2391 |
context = 5 ;
|
|
|
2392 |
ns-- ;
|
|
|
2393 |
}
|
|
|
2394 |
if ( nv ) ns++ ;
|
|
|
2395 |
if ( ns > 1 ) {
|
|
|
2396 |
ENC_SEQUENCE ( bs, ns - 1 ) ;
|
|
|
2397 |
} else {
|
|
|
2398 |
if ( ns == 0 ) ENC_make_top ( bs ) ;
|
|
|
2399 |
}
|
|
|
2400 |
|
|
|
2401 |
/* Destroy members and direct bases */
|
|
|
2402 |
while ( no ) {
|
|
|
2403 |
EXP a = DEREF_exp ( HEAD_list ( p ) ) ;
|
|
|
2404 |
if ( IS_NULL_exp ( a ) ) {
|
|
|
2405 |
ENC_make_top ( bs ) ;
|
|
|
2406 |
} else {
|
|
|
2407 |
TYPE s = DEREF_type ( exp_type ( a ) ) ;
|
|
|
2408 |
OFFSET off = DEREF_off ( HEAD_list ( q ) ) ;
|
|
|
2409 |
bs = enc_term_local ( bs, m, off, 0, s, a, context ) ;
|
|
|
2410 |
}
|
|
|
2411 |
q = TAIL_list ( q ) ;
|
|
|
2412 |
p = TAIL_list ( p ) ;
|
|
|
2413 |
no-- ;
|
|
|
2414 |
}
|
|
|
2415 |
|
|
|
2416 |
/* Conditionally destroy virtual bases */
|
|
|
2417 |
if ( nv ) {
|
|
|
2418 |
int mask = 0 ;
|
|
|
2419 |
if ( context == 0 ) mask = EXTRA_DESTR ;
|
|
|
2420 |
bs = enc_flag_test ( bs, m2, nv, mask, ntest_not_eq ) ;
|
|
|
2421 |
while ( !IS_NULL_list ( p ) ) {
|
|
|
2422 |
EXP a = DEREF_exp ( HEAD_list ( p ) ) ;
|
|
|
2423 |
if ( IS_NULL_exp ( a ) ) {
|
|
|
2424 |
ENC_make_top ( bs ) ;
|
|
|
2425 |
} else {
|
|
|
2426 |
TYPE s = DEREF_type ( exp_type ( a ) ) ;
|
|
|
2427 |
OFFSET off = DEREF_off ( HEAD_list ( q ) ) ;
|
|
|
2428 |
bs = enc_term_local ( bs, m, off, 0, s, a, context ) ;
|
|
|
2429 |
}
|
|
|
2430 |
q = TAIL_list ( q ) ;
|
|
|
2431 |
p = TAIL_list ( p ) ;
|
|
|
2432 |
}
|
|
|
2433 |
ENC_make_top ( bs ) ;
|
|
|
2434 |
}
|
|
|
2435 |
|
|
|
2436 |
/* Conditionally call 'operator delete' */
|
|
|
2437 |
if ( context == 0 ) {
|
|
|
2438 |
ns = 1 ;
|
|
|
2439 |
bs = enc_flag_test ( bs, m2, ns, EXTRA_DELETE, ntest_not_eq ) ;
|
|
|
2440 |
bs = enc_delete_obj ( bs, ct, m ) ;
|
|
|
2441 |
ENC_make_top ( bs ) ;
|
|
|
2442 |
}
|
|
|
2443 |
|
|
|
2444 |
} else {
|
|
|
2445 |
/* Deal with constructors */
|
|
|
2446 |
int virt = 1 ;
|
|
|
2447 |
unsigned ns, nu ;
|
|
|
2448 |
unsigned ni = 0 ;
|
|
|
2449 |
unsigned nt = 0 ;
|
|
|
2450 |
unsigned ne = 1 ;
|
|
|
2451 |
|
|
|
2452 |
/* Allow for copy constructors */
|
|
|
2453 |
if ( kind == DEFAULT_COPY || kind == DEFAULT_ASSIGN ) {
|
|
|
2454 |
ulong n1 = last_params [ DUMMY_second ] ;
|
|
|
2455 |
ulong m1 = unit_no ( bs, NULL_id, VAR_tag, 1 ) ;
|
|
|
2456 |
ENC_identify ( bs ) ;
|
|
|
2457 |
bs = enc_access ( bs, crt_func_access ) ;
|
|
|
2458 |
ENC_make_tag ( bs, m1 ) ;
|
|
|
2459 |
ENC_contents ( bs ) ;
|
|
|
2460 |
ENC_pointer ( bs ) ;
|
|
|
2461 |
bs = enc_al_ctype ( bs, ct ) ;
|
|
|
2462 |
ENC_obtain_tag ( bs ) ;
|
|
|
2463 |
ENC_make_tag ( bs, n1 ) ;
|
|
|
2464 |
last_params [ DUMMY_copy ] = m1 ;
|
|
|
2465 |
}
|
|
|
2466 |
|
|
|
2467 |
/* Count number of items */
|
|
|
2468 |
if ( kind != DEFAULT_ASSIGN ) {
|
|
|
2469 |
VIRTUAL vt = DEREF_virt ( ctype_virt ( ct ) ) ;
|
|
|
2470 |
if ( kind != DEFAULT_PRELUDE ) {
|
|
|
2471 |
LIST ( GRAPH ) bv = DEREF_list ( ctype_vbase ( ct ) ) ;
|
|
|
2472 |
while ( !IS_NULL_list ( bv ) ) {
|
|
|
2473 |
/* Virtual base pointers */
|
|
|
2474 |
GRAPH gr = DEREF_graph ( HEAD_list ( bv ) ) ;
|
|
|
2475 |
while ( !IS_NULL_graph ( gr ) ) {
|
|
|
2476 |
ni++ ;
|
|
|
2477 |
gr = DEREF_graph ( graph_equal ( gr ) ) ;
|
|
|
2478 |
}
|
|
|
2479 |
bv = TAIL_list ( bv ) ;
|
|
|
2480 |
}
|
|
|
2481 |
}
|
|
|
2482 |
if ( !IS_NULL_virt ( vt ) ) {
|
|
|
2483 |
/* Virtual function tables */
|
|
|
2484 |
IDENTIFIER cid = DEREF_id ( ctype_name ( ct ) ) ;
|
|
|
2485 |
compile_virtual ( ct, !has_linkage ( cid ) ) ;
|
|
|
2486 |
while ( !IS_NULL_virt ( vt ) ) {
|
|
|
2487 |
nt++ ;
|
|
|
2488 |
vt = DEREF_virt ( virt_next ( vt ) ) ;
|
|
|
2489 |
}
|
|
|
2490 |
}
|
|
|
2491 |
virt = 0 ;
|
|
|
2492 |
}
|
|
|
2493 |
if ( last_params [ DUMMY_count ] != LINK_NONE ) ne = 2 ;
|
|
|
2494 |
ns = ne * no + nt ;
|
|
|
2495 |
nu = ne * nv + ni ;
|
|
|
2496 |
if ( nu ) ns++ ;
|
|
|
2497 |
if ( ns > 1 ) {
|
|
|
2498 |
ENC_SEQUENCE ( bs, ns - 1 ) ;
|
|
|
2499 |
} else {
|
|
|
2500 |
if ( ns == 0 ) ENC_make_top ( bs ) ;
|
|
|
2501 |
}
|
|
|
2502 |
|
|
|
2503 |
/* Conditionally initialise virtual bases */
|
|
|
2504 |
if ( nu ) {
|
|
|
2505 |
int dv = 0 ;
|
|
|
2506 |
ulong m2 = last_params [ DUMMY_extra ] ;
|
|
|
2507 |
bs = enc_flag_test ( bs, m2, nu, 0, ntest_not_eq ) ;
|
|
|
2508 |
if ( ni ) {
|
|
|
2509 |
/* Initialise virtual base pointers */
|
|
|
2510 |
bs = enc_virt_init ( bs, ct, m ) ;
|
|
|
2511 |
}
|
|
|
2512 |
while ( nv ) {
|
|
|
2513 |
/* Virtual base initialisers */
|
|
|
2514 |
EXP a = DEREF_exp ( HEAD_list ( p ) ) ;
|
|
|
2515 |
OFFSET off = DEREF_off ( HEAD_list ( q ) ) ;
|
|
|
2516 |
bs = enc_ctor_exp ( bs, a, off, m, virt, ne ) ;
|
|
|
2517 |
if ( !IS_NULL_exp ( a ) && IS_exp_paren ( a ) ) dv++ ;
|
|
|
2518 |
q = TAIL_list ( q ) ;
|
|
|
2519 |
p = TAIL_list ( p ) ;
|
|
|
2520 |
nv-- ;
|
|
|
2521 |
}
|
|
|
2522 |
if ( ne == 1 || dv == 0 ) {
|
|
|
2523 |
ENC_make_top ( bs ) ;
|
|
|
2524 |
} else {
|
|
|
2525 |
bs = enc_destr_count ( bs, NULL_type, dv ) ;
|
|
|
2526 |
}
|
|
|
2527 |
}
|
|
|
2528 |
|
|
|
2529 |
/* Initialise direct bases */
|
|
|
2530 |
while ( nb ) {
|
|
|
2531 |
EXP a = DEREF_exp ( HEAD_list ( p ) ) ;
|
|
|
2532 |
OFFSET off = DEREF_off ( HEAD_list ( q ) ) ;
|
|
|
2533 |
bs = enc_ctor_exp ( bs, a, off, m, virt, ne ) ;
|
|
|
2534 |
q = TAIL_list ( q ) ;
|
|
|
2535 |
p = TAIL_list ( p ) ;
|
|
|
2536 |
nb-- ;
|
|
|
2537 |
}
|
|
|
2538 |
|
|
|
2539 |
/* Initialise virtual function tables */
|
|
|
2540 |
if ( nt ) bs = enc_vtab_init ( bs, ct, m, 1 ) ;
|
|
|
2541 |
|
|
|
2542 |
/* Initialise members */
|
|
|
2543 |
while ( !IS_NULL_list ( p ) ) {
|
|
|
2544 |
EXP a = DEREF_exp ( HEAD_list ( p ) ) ;
|
|
|
2545 |
OFFSET off = DEREF_off ( HEAD_list ( q ) ) ;
|
|
|
2546 |
bs = enc_ctor_exp ( bs, a, off, m, virt, ne ) ;
|
|
|
2547 |
q = TAIL_list ( q ) ;
|
|
|
2548 |
p = TAIL_list ( p ) ;
|
|
|
2549 |
}
|
|
|
2550 |
last_params [ DUMMY_copy ] = LINK_NONE ;
|
|
|
2551 |
}
|
|
|
2552 |
return ( bs ) ;
|
|
|
2553 |
}
|
|
|
2554 |
|
|
|
2555 |
|
|
|
2556 |
#endif /* LANGUAGE_CPP */
|
|
|
2557 |
#endif /* TDF_OUTPUT */
|