Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997, 1998
7 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
7 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
7 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "version.h"
63
#include "c_types.h"
64
#include "ctype_ops.h"
65
#include "exp_ops.h"
66
#include "etype_ops.h"
67
#include "graph_ops.h"
68
#include "id_ops.h"
69
#include "nat_ops.h"
70
#include "off_ops.h"
71
#include "str_ops.h"
72
#include "type_ops.h"
73
#include "virt_ops.h"
74
#include "error.h"
75
#include "tdf.h"
76
#include "assign.h"
77
#include "basetype.h"
78
#include "capsule.h"
79
#include "check.h"
80
#include "class.h"
81
#include "compile.h"
82
#include "constant.h"
83
#include "convert.h"
84
#include "derive.h"
85
#include "destroy.h"
86
#include "diag.h"
87
#include "encode.h"
88
#include "exp.h"
89
#include "expression.h"
90
#include "function.h"
91
#include "identifier.h"
92
#include "init.h"
93
#include "literal.h"
94
#include "member.h"
95
#include "redeclare.h"
96
#include "shape.h"
97
#include "statement.h"
98
#include "stmt.h"
99
#include "struct.h"
100
#include "syntax.h"
101
#include "tok.h"
102
#include "throw.h"
103
#include "ustring.h"
104
#include "virtual.h"
105
#if TDF_OUTPUT
106
 
107
 
108
/*
109
    ENCODE A SMALL TDF INTEGER CONSTANT
110
 
111
    This routine adds the small integer n to the bitstream bs as a TDF
112
    SIGNED_NAT.
113
*/
114
 
7 7u83 115
BITSTREAM *
116
enc_make_snat(BITSTREAM *bs, int n)
2 7u83 117
{
7 7u83 118
	ENC_make_signed_nat(bs);
119
	if (n >= 0) {
120
		ENC_OFF(bs);
121
	} else {
122
		ENC_ON(bs);
123
		n = -n;
124
	}
125
	ENC_INT(bs, n);
126
	return (bs);
2 7u83 127
}
128
 
129
 
130
/*
131
    ENCODE A SMALL TDF INTEGER
132
 
133
    This routine adds the small integer n of type t to the bitstream bs
134
    as a TDF EXP.
135
*/
136
 
7 7u83 137
BITSTREAM *
138
enc_make_int(BITSTREAM *bs, TYPE t, int n)
2 7u83 139
{
7 7u83 140
	ENC_make_int(bs);
141
	bs = enc_variety(bs, t);
142
	bs = enc_make_snat(bs, n);
143
	return (bs);
2 7u83 144
}
145
 
146
 
147
/*
148
    ENCODE A NULL TDF EXPRESSION
149
 
150
    This routine adds a null TDF EXP with shape corresponding to the type
151
    t to the bitstream bs.
152
*/
153
 
7 7u83 154
BITSTREAM *
155
enc_null_exp(BITSTREAM *bs, TYPE t)
2 7u83 156
{
7 7u83 157
	if (IS_NULL_type(t)) {
158
		/* This shouldn't happen */
159
		t = type_sint;
2 7u83 160
	}
7 7u83 161
	switch (TAG_type(t)) {
162
	case type_integer_tag:
163
	case type_enumerate_tag: {
164
		/* Integral types */
165
		bs = enc_make_int(bs, t, 0);
166
		break;
2 7u83 167
	}
7 7u83 168
	case type_floating_tag: {
169
		/* Floating types */
170
		bs = enc_float_int(bs, 0, t);
171
		break;
2 7u83 172
	}
7 7u83 173
	case type_top_tag:
174
	case type_bottom_tag: {
175
		/* Top type */
176
		ENC_make_top(bs);
177
		break;
178
	}
179
	case type_ptr_tag:
180
	case type_ref_tag: {
181
		/* Pointer types */
182
		TYPE s = DEREF_type(type_ptr_etc_sub(t));
183
		switch (TAG_type(s)) {
184
		case type_top_tag:
185
		case type_bottom_tag: {
186
			/* Generic pointer */
187
			bs = enc_special(bs, TOK_null_pv);
188
			break;
2 7u83 189
		}
7 7u83 190
		case type_func_tag: {
191
			/* Function pointer */
192
			ENC_make_null_proc(bs);
193
			break;
2 7u83 194
		}
7 7u83 195
		default: {
196
			/* Normal pointer */
197
			ENC_make_null_ptr(bs);
198
			bs = enc_alignment(bs, s);
199
			break;
2 7u83 200
		}
7 7u83 201
		}
202
		break;
2 7u83 203
	}
7 7u83 204
	case type_ptr_mem_tag: {
205
		/* Pointer to member types */
206
		TYPE s = DEREF_type(type_ptr_mem_sub(t));
207
		if (IS_type_func(s)) {
208
			if (in_static_init) {
209
				bs = enc_special(bs, TOK_pmf_null);
210
			} else {
211
				bs = enc_special(bs, TOK_pmf_null2);
212
			}
2 7u83 213
		} else {
7 7u83 214
			bs = enc_special(bs, TOK_pm_null);
2 7u83 215
		}
7 7u83 216
		break;
2 7u83 217
	}
7 7u83 218
	case type_array_tag: {
219
		/* Array types */
220
		NAT n = DEREF_nat(type_array_size(t));
221
		TYPE s = DEREF_type(type_array_sub(t));
222
		ENC_n_copies(bs);
223
		bs = enc_nat(bs, n, 1);
224
		bs = enc_null_exp(bs, s);
225
		break;
2 7u83 226
	}
7 7u83 227
	case type_bitfield_tag: {
228
		/* Bitfield types */
229
		TYPE s = find_bitfield_type(t);
230
		ENC_change_int_to_bitfield(bs);
231
		bs = enc_bfvar(bs, t);
232
		bs = enc_null_exp(bs, s);
233
		break;
2 7u83 234
	}
7 7u83 235
	case type_compound_tag: {
236
		/* Compound types */
237
		CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
238
		TYPE s = DEREF_type(ctype_form(ct));
239
		if (is_tokenised_class(s)) {
240
			ENC_make_value(bs);
241
			bs = enc_shape(bs, s);
242
		} else {
243
			bs = enc_null_class(bs, ct);
244
		}
245
		break;
2 7u83 246
	}
7 7u83 247
	default: {
248
		/* Other types */
249
		ENC_make_value(bs);
250
		bs = enc_shape(bs, t);
251
		break;
2 7u83 252
	}
7 7u83 253
	}
254
	return (bs);
2 7u83 255
}
256
 
257
 
258
/*
259
    CHECK ANONYMOUS UNION MEMBER EXPRESSION
260
 
261
    This routine checks whether the identifier expression a arises from a
262
    member of an anonymous union.  The routine also marks any external
263
    variables.
264
*/
265
 
7 7u83 266
static int
267
is_anon_exp(EXP a)
2 7u83 268
{
7 7u83 269
	IDENTIFIER id = DEREF_id(exp_identifier_id(a));
270
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
271
	if (!(ds & dspec_auto)) {
272
		/* Mark external variables */
273
		IGNORE capsule_id(id, VAR_tag);
274
	}
275
	if (ds & dspec_reserve) {
276
		/* Check for anonymous union members */
277
		return (is_anon_member(id));
278
	}
279
	return (0);
2 7u83 280
}
281
 
282
 
283
/*
284
    CREATE AN IDENTITY DECLARATION
285
 
286
    This routine adds the start of an identity declaration for the
287
    expression a to the bitstream bs.  The identity body will consist
288
    of a sequence of seq + 1 expressions.  The identity tag number is
289
    returned via pn.
290
*/
291
 
7 7u83 292
static BITSTREAM *
293
make_identity(BITSTREAM *bs, EXP a, ulong *pn, int cnt, int seq)
2 7u83 294
{
7 7u83 295
	ulong n;
296
	if (IS_exp_identifier(a)) {
297
		/* No identity required in this case */
298
		IDENTIFIER id = DEREF_id(exp_identifier_id(a));
299
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
300
		if ((ds & dspec_auto) && !is_anon_exp(a)) {
301
			n = unit_no(bs, id, VAR_tag, 0);
302
			if (seq) {
303
				ENC_SEQUENCE(bs, seq);
304
			}
305
			*pn = n;
306
			return (bs);
307
		}
2 7u83 308
	}
7 7u83 309
	/* Declare new identity */
310
	n = unit_no(bs, NULL_id, VAR_tag, 1);
311
	ENC_identify(bs);
312
	bs = enc_access(bs, crt_func_access);
313
	ENC_make_tag(bs, n);
314
	if (cnt) {
315
		bs = enc_exp(bs, a);
316
	} else {
317
		TYPE t = DEREF_type(exp_type(a));
318
		bs = enc_addr_exp(bs, t, a);
319
	}
320
	if (seq) {
321
		ENC_SEQUENCE(bs, seq);
322
	}
323
	*pn = n;
324
	return (bs);
2 7u83 325
}
326
 
327
 
328
/*
329
    CREATE A POINTER TO MEMBER FUNCTION TAG
330
 
331
    This routine adds the start of an identity or variable declaration
332
    for the pointer to member function or similar expression a to the
333
    bitstream bs.  If var is true then a variable declaration is forced.
334
    The tag number is returned via pn.
335
*/
336
 
7 7u83 337
static BITSTREAM *
338
make_ptr_mem_func(BITSTREAM *bs, EXP a, ulong *pn, int var)
2 7u83 339
{
7 7u83 340
	if (IS_exp_contents(a) && !var) {
341
		EXP b = DEREF_exp(exp_contents_ptr(a));
342
		bs = make_identity(bs, b, pn, 0, 0);
343
	} else {
344
		ulong n = unit_no(bs, NULL_id, VAR_tag, 1);
345
		ENC_variable(bs);
346
		bs = enc_access(bs, crt_func_access);
347
		ENC_make_tag(bs, n);
348
		bs = enc_exp(bs, a);
349
		*pn = n;
350
	}
351
	return (bs);
2 7u83 352
}
353
 
354
 
355
/*
356
    ENCODE AN ASSIGNMENT OPERATOR
357
 
358
    This routine encodes an assignment operator for an expression of
359
    type t.  bf is set to true for bitfields.
360
*/
361
 
7 7u83 362
BITSTREAM *
363
enc_assign_op(BITSTREAM *bs, TYPE t, int *bf)
2 7u83 364
{
7 7u83 365
	CV_SPEC cv = DEREF_cv(type_qual(t));
366
	if (IS_type_bitfield(t)) {
367
		if (cv & cv_volatile) {
368
			ENC_bitfield_assign_with_mode(bs);
369
			ENC_volatile(bs);
370
		} else {
371
			ENC_bitfield_assign(bs);
372
		}
373
		*bf = 1;
2 7u83 374
	} else {
7 7u83 375
		if (cv & cv_volatile) {
376
			ENC_assign_with_mode(bs);
377
			ENC_volatile(bs);
378
		} else {
379
			ENC_assign(bs);
380
		}
2 7u83 381
	}
7 7u83 382
	return (bs);
2 7u83 383
}
384
 
385
 
386
/*
387
    ENCODE THE ADDRESS OF A TDF EXPRESSION
388
 
389
    This routine adds the address of the expression e to the bitstream
390
    bs as a TDF EXP.
391
*/
392
 
7 7u83 393
BITSTREAM *
394
enc_addr_exp(BITSTREAM *bs, TYPE t, EXP e)
2 7u83 395
{
7 7u83 396
	ulong n;
397
	int anon = 0;
398
	TYPE s = DEREF_type(exp_type(e));
399
	switch (TAG_exp(e)) {
2 7u83 400
 
7 7u83 401
	case exp_identifier_tag: {
402
		/* Find tag corresponding to identifier */
403
		IDENTIFIER id = DEREF_id(exp_identifier_id(e));
404
		anon = is_anon_exp(e);
405
		n = unit_no(bs, id, VAR_tag, 0);
406
		break;
2 7u83 407
	}
408
 
7 7u83 409
	case exp_string_lit_tag: {
410
		/* Introduce tag for string literal */
411
		CV_SPEC qual = cv_none;
412
		STRING str = DEREF_str(exp_string_lit_str(e));
413
		if (IS_type_ptr(t)) {
414
			t = DEREF_type(type_ptr_sub(t));
415
			qual = DEREF_cv(type_qual(t));
2 7u83 416
		}
7 7u83 417
		if ((qual & cv_const) && output_shared) {
418
			/* Share const strings */
419
			n = DEREF_ulong(str_simple_tok(str));
420
			if (n == LINK_NONE) {
421
				n = make_tagdef(NULL_id, s, e, NULL_exp, 1);
422
				COPY_ulong(str_simple_tok(str), n);
423
			}
424
		} else {
425
			/* Don't share non-const strings */
426
			n = make_tagdef(NULL_id, s, e, NULL_exp, 1);
427
		}
428
		n = link_no(bs, n, VAR_tag);
429
		break;
2 7u83 430
	}
431
 
7 7u83 432
	case exp_indir_tag: {
433
		/* Indirections are simple */
434
		EXP a = DEREF_exp(exp_indir_ptr(e));
435
		bs = enc_exp(bs, a);
436
		return (bs);
2 7u83 437
	}
438
 
7 7u83 439
	case exp_assign_tag: {
440
		/* Introduce identity for assignment */
441
		EXP a = DEREF_exp(exp_assign_ref(e));
442
		EXP b = DEREF_exp(exp_assign_arg(e));
443
		bs = make_identity(bs, a, &n, 0, 1);
444
		bs = enc_init_tag(bs, n, NULL_off, 0, s, b, NULL_exp, 0);
445
		break;
2 7u83 446
	}
447
 
7 7u83 448
	case exp_init_tag: {
449
		/* Introduce identity for initialisation */
450
		int context = 1;
451
		unsigned seq = 1;
452
		IDENTIFIER id = DEREF_id(exp_init_id(e));
453
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
454
		EXP a = DEREF_exp(exp_init_arg(e));
455
		EXP d = DEREF_exp(id_variable_etc_term(id));
456
		if (!IS_NULL_exp(d)) {
457
			while (IS_exp_nof(d)) {
458
				d = DEREF_exp(exp_nof_pad(d));
459
			}
460
			seq++;
2 7u83 461
		}
7 7u83 462
		ENC_SEQ_SMALL(bs, seq);
463
		if (!(ds & dspec_auto)) {
464
			/* Allow for external variables */
465
			if (capsule_id(id, VAR_tag)) {
466
				make_term_global(s, &d);
467
			}
468
			context = 2;
2 7u83 469
		}
7 7u83 470
		n = unit_no(bs, id, VAR_tag, 0);
471
		bs = enc_init_tag(bs, n, NULL_off, 0, s, a, d, context);
472
		break;
2 7u83 473
	}
474
 
7 7u83 475
	case exp_preinc_tag: {
476
		/* Pre-increment expressions */
477
		EXP a = DEREF_exp(exp_preinc_ref(e));
478
		EXP b = DEREF_exp(exp_preinc_op(e));
479
		EXP a1 = DEREF_exp(exp_dummy_value(a));
480
		OFFSET off = DEREF_off(exp_dummy_off(a));
481
		COPY_exp(exp_dummy_value(a), NULL_exp);
482
		bs = make_identity(bs, a1, &n, 0, 1);
483
		COPY_ulong(exp_dummy_no(a), n);
484
		s = DEREF_type(exp_type(a));
485
		bs = enc_init_tag(bs, n, off, 0, s, b, NULL_exp, 0);
486
		COPY_exp(exp_dummy_value(a), a1);
487
		break;
2 7u83 488
	}
489
 
7 7u83 490
	case exp_cast_tag: {
491
		/* Cast expressions */
492
		EXP a = DEREF_exp(exp_cast_arg(e));
493
		bs = enc_addr_exp(bs, t, a);
494
		return (bs);
2 7u83 495
	}
496
 
7 7u83 497
	case exp_decl_stmt_tag: {
498
		/* Variable declarations */
499
		IDENTIFIER id = DEREF_id(exp_decl_stmt_id(e));
500
		EXP a = DEREF_exp(exp_decl_stmt_body(e));
501
		bs = enc_variable(bs, id, 1, NIL(EXP), NULL_exp);
502
		ENC_SEQ_SMALL(bs, 1);
503
		bs = enc_exp(bs, a);
504
		n = unit_no(bs, id, VAR_tag, 0);
505
		break;
2 7u83 506
	}
507
 
7 7u83 508
	case exp_comma_tag:
509
	case exp_if_stmt_tag:
510
	case exp_hash_if_tag: {
511
		/* Statement-like expressions */
512
		bs = enc_stmt_exp(bs, e, s, 2);
513
		return (bs);
2 7u83 514
	}
515
 
7 7u83 516
	case exp_rtti_tag:
517
	case exp_rtti_type_tag:
518
	case exp_thrown_tag:
519
	case exp_dummy_tag: {
520
		/* lvalue expressions */
521
		bs = enc_exp(bs, e);
522
		return (bs);
2 7u83 523
	}
524
 
7 7u83 525
	case exp_token_tag: {
526
		/* Tokenised expressions */
527
		CV_SPEC qual = DEREF_cv(type_qual(s));
528
		if (qual & cv_lvalue) {
529
			bs = enc_exp(bs, e);
530
			return (bs);
531
		}
532
		n = make_tagdef(NULL_id, s, e, NULL_exp, 1);
533
		n = link_no(bs, n, VAR_tag);
534
		break;
2 7u83 535
	}
536
 
7 7u83 537
	default: {
538
		/* Create temporary variable */
539
		CV_SPEC qual = DEREF_cv(type_qual(s));
540
		if (qual & cv_lvalue) {
541
			bs = enc_exp(bs, e);
542
			return (bs);
543
		}
544
		n = unit_no(bs, NULL_id, VAR_tag, 1);
545
		ENC_variable(bs);
546
		bs = enc_access(bs, dspec_none);
547
		ENC_make_tag(bs, n);
548
		bs = enc_exp(bs, e);
549
		break;
2 7u83 550
	}
7 7u83 551
	}
2 7u83 552
 
7 7u83 553
	/* Encode an obtain_tag expression */
554
	if (anon) {
555
		ENC_add_to_ptr(bs);
556
	}
557
	if (IS_type_ref(s)) {
558
		int bf = 0;
559
		bs = enc_cont_op(bs, s, &bf);
560
		bs = enc_shape(bs, s);
561
		ASSERT(bf == 0);
562
	}
563
	ENC_obtain_tag(bs);
564
	ENC_make_tag(bs, n);
565
	if (anon) {
566
		/* Allow for differing identifier types */
567
		ENC_offset_zero(bs);
568
		bs = enc_alignment(bs, s);
569
	}
570
	return (bs);
2 7u83 571
}
572
 
573
 
574
/*
575
    ENCODE A CONTENTS OPERATOR
576
 
577
    This routine encodes a contents operator for an expression of type t.
578
    bf is set to true for bitfields.
579
*/
580
 
7 7u83 581
BITSTREAM *
582
enc_cont_op(BITSTREAM *bs, TYPE t, int *bf)
2 7u83 583
{
7 7u83 584
	CV_SPEC cv = DEREF_cv(type_qual(t));
585
	if (IS_type_bitfield(t)) {
586
		if (cv & cv_volatile) {
587
			ENC_bitfield_contents_with_mode(bs);
588
			ENC_volatile(bs);
589
		} else {
590
			ENC_bitfield_contents(bs);
591
		}
592
		*bf = 1;
2 7u83 593
	} else {
7 7u83 594
		if (cv & cv_volatile) {
595
			ENC_contents_with_mode(bs);
596
			ENC_volatile(bs);
597
		} else {
598
			ENC_contents(bs);
599
		}
2 7u83 600
	}
7 7u83 601
	return (bs);
2 7u83 602
}
603
 
604
 
605
/*
606
    ENCODE THE CONTENTS OF A TDF EXPRESSION
607
 
608
    This routine adds the contents of the expression e of type t to the
609
    bitstream bs as a TDF EXP.
610
*/
611
 
7 7u83 612
BITSTREAM *
613
enc_cont_exp(BITSTREAM *bs, TYPE t, EXP e)
2 7u83 614
{
7 7u83 615
	ulong n;
616
	int bf = 0;
617
	OFFSET off = NULL_off;
618
	TYPE s = DEREF_type(exp_type(e));
2 7u83 619
 
7 7u83 620
	switch (TAG_exp(e)) {
2 7u83 621
 
7 7u83 622
	case exp_assign_tag: {
623
		/* Assignment (can't be bitfield) */
624
		EXP a = DEREF_exp(exp_assign_ref(e));
625
		EXP b = DEREF_exp(exp_assign_arg(e));
626
		CV_SPEC cv = DEREF_cv(type_qual(s));
627
		if (!(cv & cv_lvalue)) {
628
			if ((cv & cv_volatile) && !is_init_complex(b)) {
629
				/* Introduce identity for right hand side */
630
				bs = make_identity(bs, b, &n, 1, 1);
631
				bs = enc_assign_op(bs, s, &bf);
632
				bs = enc_exp(bs, a);
633
				ENC_obtain_tag(bs);
634
				ENC_make_tag(bs, n);
635
				ENC_obtain_tag(bs);
636
				ENC_make_tag(bs, n);
637
				return (bs);
638
			}
2 7u83 639
		}
7 7u83 640
		/* Introduce identity for left hand side */
641
		bs = make_identity(bs, a, &n, 0, 1);
642
		bs = enc_init_tag(bs, n, NULL_off, 0, t, b, NULL_exp, 0);
643
		break;
2 7u83 644
	}
645
 
7 7u83 646
	case exp_init_tag: {
647
		/* Introduce identity for initialisation */
648
		int context = 1;
649
		unsigned seq = 1;
650
		IDENTIFIER id = DEREF_id(exp_init_id(e));
651
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
652
		EXP a = DEREF_exp(exp_init_arg(e));
653
		EXP d = DEREF_exp(id_variable_etc_term(id));
654
		if (!IS_NULL_exp(d)) {
655
			while (IS_exp_nof(d)) {
656
				d = DEREF_exp(exp_nof_pad(d));
657
			}
658
			seq++;
2 7u83 659
		}
7 7u83 660
		ENC_SEQ_SMALL(bs, seq);
661
		if (!(ds & dspec_auto)) {
662
			/* Allow for external variables */
663
			if (capsule_id(id, VAR_tag)) {
664
				make_term_global(t, &d);
665
			}
666
			context = 2;
2 7u83 667
		}
7 7u83 668
		n = unit_no(bs, id, VAR_tag, 0);
669
		bs = enc_init_tag(bs, n, NULL_off, 0, t, a, d, context);
670
		break;
2 7u83 671
	}
672
 
7 7u83 673
	case exp_preinc_tag: {
674
		/* Pre-increment expressions */
675
		ulong m = LINK_NONE;
676
		CV_SPEC cv = DEREF_cv(type_qual(s));
677
		EXP a = DEREF_exp(exp_preinc_ref(e));
678
		EXP b = DEREF_exp(exp_preinc_op(e));
679
		EXP a1 = DEREF_exp(exp_dummy_value(a));
680
		COPY_exp(exp_dummy_value(a), NULL_exp);
681
		bs = make_identity(bs, a1, &n, 0, 0);
682
		COPY_ulong(exp_dummy_no(a), n);
683
		if (!(cv & cv_lvalue) || !(cv & cv_volatile)) {
684
			/* Introduce identity for right hand side */
685
			bs = make_identity(bs, b, &m, 1, 0);
686
		}
687
		ENC_SEQ_SMALL(bs, 1);
688
		s = DEREF_type(exp_type(a));
689
		bs = enc_assign_op(bs, s, &bf);
690
		ENC_obtain_tag(bs);
691
		ENC_make_tag(bs, n);
692
		if (bf) {
693
			off = DEREF_off(exp_dummy_off(a));
694
			bs = enc_offset(bs, off);
695
		}
696
		COPY_exp(exp_dummy_value(a), a1);
697
		if (m == LINK_NONE) {
698
			bs = enc_exp(bs, b);
699
		} else {
700
			ENC_obtain_tag(bs);
701
			ENC_make_tag(bs, m);
702
		}
703
		if (bf && !IS_type_bitfield(t)) {
704
			/* Promotion conversion (see make_preinc_exp) */
705
			ENC_change_bitfield_to_int(bs);
706
			bs = enc_variety(bs, t);
707
			t = s;
708
		}
709
		if (m == LINK_NONE) {
710
			break;
711
		}
712
		ENC_obtain_tag(bs);
713
		ENC_make_tag(bs, m);
714
		return (bs);
2 7u83 715
	}
716
 
7 7u83 717
	case exp_decl_stmt_tag: {
718
		/* Variable declarations */
719
		IDENTIFIER id = DEREF_id(exp_decl_stmt_id(e));
720
		EXP a = DEREF_exp(exp_decl_stmt_body(e));
721
		bs = enc_variable(bs, id, 1, NIL(EXP), NULL_exp);
722
		ENC_SEQ_SMALL(bs, 1);
723
		bs = enc_exp(bs, a);
724
		n = unit_no(bs, id, VAR_tag, 0);
725
		break;
2 7u83 726
	}
727
 
7 7u83 728
	case exp_comma_tag:
729
	case exp_if_stmt_tag:
730
	case exp_hash_if_tag: {
731
		/* Statement-like expressions */
732
		bs = enc_stmt_exp(bs, e, t, 3);
733
		return (bs);
2 7u83 734
	}
735
 
7 7u83 736
	case exp_dummy_tag: {
737
		/* Dummy expressions */
738
		EXP a = DEREF_exp(exp_dummy_value(e));
739
		if (IS_NULL_exp(a)) {
740
			int cnt = DEREF_int(exp_dummy_cont(e));
741
			int virt = DEREF_int(exp_dummy_virt(e));
742
			n = DEREF_ulong(exp_dummy_no(e));
743
			bs = enc_cont_op(bs, s, &bf);
744
			off = DEREF_off(exp_dummy_off(e));
745
			if (bf) {
746
				OFFSET off1 = decons_bitf_off(&off);
747
				bs = enc_bfvar(bs, t);
748
				bs = enc_dummy_exp(bs, t, n, off, cnt, virt);
749
				bs = enc_offset(bs, off1);
750
			} else {
751
				bs = enc_shape(bs, t);
752
				bs = enc_dummy_exp(bs, t, n, off, cnt, virt);
753
			}
754
			return (bs);
2 7u83 755
		}
7 7u83 756
		n = LINK_NONE;
757
		break;
2 7u83 758
	}
759
 
7 7u83 760
	default: {
761
		/* This is the easy case */
762
		n = LINK_NONE;
763
		break;
2 7u83 764
	}
7 7u83 765
	}
2 7u83 766
 
7 7u83 767
	/* Encode a contents expression */
768
	bs = enc_cont_op(bs, s, &bf);
769
	if (bf) {
770
		if (IS_NULL_off(off)) {
771
			/* Find bitfield offset */
772
			off = decons_bitf_exp(&e);
773
		}
774
		bs = enc_bfvar(bs, t);
775
		if (n == LINK_NONE) {
776
			bs = enc_addr_exp(bs, t, e);
777
		} else {
778
			ENC_obtain_tag(bs);
779
			ENC_make_tag(bs, n);
780
		}
781
		bs = enc_offset(bs, off);
2 7u83 782
	} else {
7 7u83 783
		bs = enc_shape(bs, t);
784
		if (n == LINK_NONE) {
785
			bs = enc_exp(bs, e);
786
		} else {
787
			ENC_obtain_tag(bs);
788
			ENC_make_tag(bs, n);
789
		}
2 7u83 790
	}
7 7u83 791
	return (bs);
2 7u83 792
}
793
 
794
 
795
/*
796
    ENCODE A LIST OF TDF EXPS
797
 
798
    This routines adds the expressions p to the bitstream bs as a list
799
    of TDF EXPs.
800
*/
801
 
7 7u83 802
BITSTREAM *
803
enc_exp_list(BITSTREAM *bs, LIST(EXP)p)
2 7u83 804
{
7 7u83 805
	unsigned n = LENGTH_list(p);
806
	ENC_LIST(bs, n);
807
	while (!IS_NULL_list(p)) {
808
		EXP e = DEREF_exp(HEAD_list(p));
809
		bs = enc_exp(bs, e);
810
		p = TAIL_list(p);
811
	}
812
	return (bs);
2 7u83 813
}
814
 
815
 
816
/*
817
    ENCODE A TDF NTEST
818
 
819
    This routine adds the comparison operator tst to the bitstream bs as
820
    a TDF NTEST.  The macro ENC_NTEST exploits the correlation between
821
    the internal representation of NTESTs and the TDF encoding.
822
*/
823
 
7 7u83 824
BITSTREAM *
825
enc_ntest(BITSTREAM *bs, NTEST tst)
2 7u83 826
{
7 7u83 827
	ENC_NTEST(bs, tst);
828
	return (bs);
2 7u83 829
}
830
 
831
 
832
/*
833
    ENCODE A COMPARISON
834
 
835
    This routine adds a comparison expression to the bitstream bs for
836
    comparing a with b using test tst.  lab gives the destination label
837
    number.
838
*/
839
 
7 7u83 840
BITSTREAM *
841
enc_compare(BITSTREAM *bs, EXP a, EXP b, NTEST tst, ulong lab, ulong nlab)
2 7u83 842
{
7 7u83 843
	/* Find the test */
844
	TYPE t = DEREF_type(exp_type(a));
845
	unsigned tag = TAG_type(t);
846
	if (lab == LINK_NONE) {
847
		if (tst > ntest_not) {
848
			tst -= ntest_not;
849
		}
850
		tst = ntest_negate - tst;
851
		lab = nlab;
852
	}
2 7u83 853
 
7 7u83 854
	/* Encode the comparison operation */
855
	switch (tag) {
2 7u83 856
 
7 7u83 857
	case type_floating_tag: {
858
		/* Floating point comparisons */
859
		ENC_floating_test(bs);
860
		ENC_OFF(bs);
861
		ENC_impossible(bs);
862
		break;
2 7u83 863
	}
864
 
7 7u83 865
	case type_ptr_tag:
866
	case type_ref_tag: {
867
		/* Pointer comparisons */
868
		TYPE s = DEREF_type(type_ptr_etc_sub(t));
869
		switch (TAG_type(s)) {
870
		case type_top_tag:
871
		case type_bottom_tag: {
872
			/* 'void *' comparisons */
873
			int spec;
874
			BITSTREAM *ts;
875
			if (IS_NULL_exp(b) || IS_exp_null(b)) {
876
				spec = TOK_pv_test;
877
				b = NULL_exp;
878
			} else {
879
				spec = TOK_pv_compare;
880
			}
881
			bs = enc_special(bs, spec);
882
			ts = start_bitstream(NIL(FILE), bs->link);
883
			ts = enc_exp(ts, a);
884
			if (!IS_NULL_exp(b)) {
885
				ts = enc_exp(ts, b);
886
			}
887
			ENC_make_label(ts, lab);
888
			ts = enc_ntest(ts, tst);
889
			bs = enc_bitstream(bs, ts);
890
			return (bs);
2 7u83 891
		}
7 7u83 892
		case type_func_tag: {
893
			/* Function pointers */
894
			ENC_proc_test(bs);
895
			break;
2 7u83 896
		}
7 7u83 897
		default: {
898
			/* Object pointers */
899
			ENC_pointer_test(bs);
900
			break;
2 7u83 901
		}
7 7u83 902
		}
903
		ENC_OFF(bs);
904
		break;
2 7u83 905
	}
906
 
7 7u83 907
	case type_ptr_mem_tag: {
908
		/* Pointer to member comparisons */
909
		int spec;
910
		BITSTREAM *ts;
911
		TYPE s = DEREF_type(type_ptr_mem_sub(t));
912
		if (IS_type_func(s)) {
913
			/* Pointer to member functions */
914
			ulong n = LINK_NONE;
915
			ulong m = LINK_NONE;
916
			bs = make_ptr_mem_func(bs, a, &n, 0);
917
			if (IS_NULL_exp(b) || IS_exp_null(b)) {
918
				spec = TOK_pmf_test;
919
				b = NULL_exp;
920
			} else {
921
				bs = make_ptr_mem_func(bs, b, &m, 0);
922
				spec = TOK_pmf_compare;
923
			}
924
			bs = enc_special(bs, spec);
925
			ts = start_bitstream(NIL(FILE), bs->link);
926
			ENC_obtain_tag(ts);
927
			ENC_make_tag(ts, n);
928
			if (!IS_NULL_exp(b)) {
929
				ENC_obtain_tag(ts);
930
				ENC_make_tag(ts, m);
931
			}
932
			ENC_make_label(ts, lab);
933
			ts = enc_ntest(ts, tst);
934
			bs = enc_bitstream(bs, ts);
2 7u83 935
		} else {
7 7u83 936
			/* Pointer to data members */
937
			if (IS_NULL_exp(b) || IS_exp_null(b)) {
938
				spec = TOK_pm_test;
939
				b = NULL_exp;
940
			} else {
941
				spec = TOK_pm_compare;
942
			}
943
			bs = enc_special(bs, spec);
944
			ts = start_bitstream(NIL(FILE), bs->link);
945
			ts = enc_exp(ts, a);
946
			if (!IS_NULL_exp(b))ts = enc_exp(ts, b);
947
			ENC_make_label(ts, lab);
948
			ts = enc_ntest(ts, tst);
949
			bs = enc_bitstream(bs, ts);
2 7u83 950
		}
7 7u83 951
		return (bs);
2 7u83 952
	}
953
 
7 7u83 954
	default: {
955
		/* Integer comparisons */
956
		ENC_integer_test(bs);
957
		ENC_OFF(bs);
958
		break;
2 7u83 959
	}
7 7u83 960
	}
2 7u83 961
 
7 7u83 962
	/* Encode the comparison arguments */
963
	bs = enc_ntest(bs, tst);
964
	ENC_make_label(bs, lab);
965
	bs = enc_exp(bs, a);
966
	if (IS_NULL_exp(b)) {
967
		bs = enc_null_exp(bs, t);
968
	} else {
969
		bs = enc_exp(bs, b);
970
	}
971
	return (bs);
2 7u83 972
}
973
 
974
 
975
/*
976
    SIMPLIFY A CONDITION
977
 
978
    This routine simplifies the condition e by removing any double
979
    negations.  sw is set to 1 if the result has the form 'a || b' or
980
    '!( a && b )'.
981
*/
982
 
7 7u83 983
EXP
984
simplify_cond(EXP e, int *sw)
2 7u83 985
{
7 7u83 986
	EXP a = e;
987
	unsigned tag = TAG_exp(a);
988
	if (tag == exp_location_tag) {
989
		/* Can have location markers */
990
		EXP b;
991
		a = DEREF_exp(exp_location_arg(e));
992
		b = simplify_cond(a, sw);
993
		if (!EQ_exp(b, a)) {
994
			LOCATION loc;
995
			TYPE t = DEREF_type(exp_type(e));
996
			DEREF_loc(exp_location_end(e), loc);
997
			MAKE_exp_location(t, loc, b, e);
998
		}
999
		return (e);
2 7u83 1000
	}
7 7u83 1001
	while (tag == exp_not_tag) {
1002
		EXP b = DEREF_exp(exp_not_arg(a));
1003
		tag = TAG_exp(b);
1004
		if (tag != exp_not_tag) {
1005
			if (tag == exp_log_and_tag) {
1006
				*sw = 1;
1007
			}
1008
			return (a);
1009
		}
1010
		a = DEREF_exp(exp_not_arg(b));
1011
		tag = TAG_exp(a);
2 7u83 1012
	}
7 7u83 1013
	if (tag == exp_log_or_tag) {
1014
		*sw = 1;
1015
	}
1016
	return (a);
2 7u83 1017
}
1018
 
1019
 
1020
/*
1021
    ENCODE A CONDITION
1022
 
1023
    This routine adds the expression e as a conditional jump to the label
1024
    lab if true or label nlab if false to the bitstream bs.  Either label
1025
    may be LINK_NONE.
1026
*/
1027
 
7 7u83 1028
BITSTREAM *
1029
enc_condition(BITSTREAM *bs, EXP e, ulong lab, ulong nlab)
2 7u83 1030
{
7 7u83 1031
	switch (TAG_exp(e)) {
2 7u83 1032
 
7 7u83 1033
	case exp_int_lit_tag: {
1034
		/* Constant conditions */
1035
		NAT n = DEREF_nat(exp_int_lit_nat(e));
1036
		if (IS_nat_small(n)) {
1037
			unsigned v = DEREF_unsigned(nat_small_value(n));
1038
			if (v == BOOL_FALSE) {
1039
				nlab = lab;
1040
			}
1041
			if (nlab == LINK_NONE) {
1042
				ENC_make_top(bs);
1043
			} else {
1044
				ENC_goto(bs);
1045
				ENC_make_label(bs, nlab);
1046
			}
1047
			break;
2 7u83 1048
		}
7 7u83 1049
		if (IS_nat_calc(n)) {
1050
			EXP a = DEREF_exp(nat_calc_value(n));
1051
			bs = enc_condition(bs, a, lab, nlab);
1052
			break;
1053
		}
1054
		goto default_lab;
2 7u83 1055
	}
1056
 
7 7u83 1057
	case exp_not_tag: {
1058
		/* Negated conditions */
1059
		EXP a = DEREF_exp(exp_not_arg(e));
1060
		bs = enc_condition(bs, a, nlab, lab);
1061
		break;
2 7u83 1062
	}
1063
 
7 7u83 1064
	case exp_log_and_tag: {
1065
		/* Logical and conditions */
1066
		EXP a = DEREF_exp(exp_log_and_arg1(e));
1067
		EXP b = DEREF_exp(exp_log_and_arg2(e));
1068
		if (lab == LINK_NONE) {
1069
			/* '!( a && b )' equals '!a || !b' */
1070
			ulong mlab = unit_no(bs, NULL_id, VAR_label, 1);
1071
			ENC_conditional(bs);
1072
			ENC_make_label(bs, mlab);
1073
			ENC_SEQ_SMALL(bs, 1);
1074
			bs = enc_condition(bs, a, mlab, LINK_NONE);
1075
			bs = enc_condition(bs, b, LINK_NONE, nlab);
1076
			ENC_make_top(bs);
1077
		} else {
1078
			/* Encode 'a && b' */
1079
			ENC_SEQ_SMALL(bs, 1);
1080
			bs = enc_condition(bs, a, lab, nlab);
1081
			bs = enc_condition(bs, b, lab, nlab);
1082
		}
1083
		break;
2 7u83 1084
	}
1085
 
7 7u83 1086
	case exp_log_or_tag: {
1087
		/* Logical or conditions */
1088
		EXP a = DEREF_exp(exp_log_or_arg1(e));
1089
		EXP b = DEREF_exp(exp_log_or_arg2(e));
1090
		if (nlab == LINK_NONE) {
1091
			/* Encode 'a || b' */
1092
			ulong mlab = unit_no(bs, NULL_id, VAR_label, 1);
1093
			ENC_conditional(bs);
1094
			ENC_make_label(bs, mlab);
1095
			ENC_SEQ_SMALL(bs, 1);
1096
			bs = enc_condition(bs, a, LINK_NONE, mlab);
1097
			bs = enc_condition(bs, b, lab, LINK_NONE);
1098
			ENC_make_top(bs);
1099
		} else {
1100
			/* '!( a || b )' equals '!a && !b' */
1101
			ENC_SEQ_SMALL(bs, 1);
1102
			bs = enc_condition(bs, a, lab, nlab);
1103
			bs = enc_condition(bs, b, lab, nlab);
1104
		}
1105
		break;
2 7u83 1106
	}
1107
 
7 7u83 1108
	case exp_test_tag: {
1109
		/* Test conditions */
1110
		NTEST tst = DEREF_ntest(exp_test_tst(e));
1111
		EXP a = DEREF_exp(exp_test_arg(e));
1112
		bs = enc_compare(bs, a, NULL_exp, tst, lab, nlab);
1113
		break;
2 7u83 1114
	}
1115
 
7 7u83 1116
	case exp_compare_tag: {
1117
		/* Comparison conditions */
1118
		NTEST tst = DEREF_ntest(exp_compare_tst(e));
1119
		EXP a = DEREF_exp(exp_compare_arg1(e));
1120
		EXP b = DEREF_exp(exp_compare_arg2(e));
1121
		bs = enc_compare(bs, a, b, tst, lab, nlab);
1122
		break;
2 7u83 1123
	}
1124
 
7 7u83 1125
	case exp_comma_tag: {
1126
		/* Comma conditions */
1127
		EXP a;
1128
		LIST(EXP)p = DEREF_list(exp_comma_args(e));
1129
		bs = enc_stmt_exp(bs, e, type_void, -1);
1130
		p = END_list(p);
1131
		a = DEREF_exp(HEAD_list(p));
1132
		bs = enc_condition(bs, a, lab, nlab);
1133
		break;
2 7u83 1134
	}
1135
 
7 7u83 1136
	case exp_location_tag: {
1137
		/* Location marker */
1138
		PTR(LOCATION)loc = crt_enc_loc;
1139
		EXP a = DEREF_exp(exp_location_arg(e));
1140
		BITSTREAM *ts = enc_diag_begin(&bs);
1141
		ts = enc_condition(ts, a, lab, nlab);
1142
		crt_enc_loc = exp_location_end(e);
1143
		bs = enc_diag_end(bs, ts, a, 2);
1144
		crt_enc_loc = loc;
1145
		break;
2 7u83 1146
	}
1147
 
7 7u83 1148
	default:
1149
default_lab: {
1150
		     /* Other conditions */
1151
		     NTEST tst = ntest_not_eq;
1152
		     bs = enc_compare(bs, e, NULL_exp, tst, lab, nlab);
1153
		     break;
1154
	     }
2 7u83 1155
	}
7 7u83 1156
	return (bs);
2 7u83 1157
}
1158
 
1159
 
1160
/*
1161
    ENCODE A LOGICAL EXPRESSION
1162
 
1163
    This routine adds the logical expression e of type t to the bitstream
1164
    bs.  The code added is equivalent to '( e ? 1 : 0 )'.
1165
*/
1166
 
7 7u83 1167
static BITSTREAM *
1168
enc_logical(BITSTREAM *bs, EXP e, TYPE t)
2 7u83 1169
{
7 7u83 1170
	int sw = 0;
1171
	ulong nlab = LINK_NONE;
1172
	ulong n = unit_no(bs, NULL_id, VAR_tag, 1);
1173
	ulong lab = unit_no(bs, NULL_id, VAR_label, 1);
1174
	e = simplify_cond(e, &sw);
2 7u83 1175
 
7 7u83 1176
	/* Introduce variable for boolean value */
1177
	ENC_variable(bs);
1178
	bs = enc_access(bs, dspec_none);
1179
	ENC_make_tag(bs, n);
1180
	bs = enc_make_int(bs, t, sw);
1181
	ENC_SEQ_SMALL(bs, 1);
1182
	ENC_conditional(bs);
1183
	ENC_make_label(bs, lab);
1184
	ENC_SEQ_SMALL(bs, 1);
2 7u83 1185
 
7 7u83 1186
	/* Conditionally assign to boolean variable */
1187
	if (sw) {
1188
		nlab = lab;
1189
		lab = LINK_NONE;
1190
	}
1191
	bs = enc_condition(bs, e, lab, nlab);
1192
	ENC_assign(bs);
1193
	ENC_obtain_tag(bs);
1194
	ENC_make_tag(bs, n);
1195
	bs = enc_make_int(bs, t, !sw);
1196
	ENC_make_top(bs);
2 7u83 1197
 
7 7u83 1198
	/* Return the contents of the boolean */
1199
	ENC_contents(bs);
1200
	bs = enc_shape(bs, t);
1201
	ENC_obtain_tag(bs);
1202
	ENC_make_tag(bs, n);
1203
	return (bs);
2 7u83 1204
}
1205
 
1206
 
1207
/*
1208
    CHECK FOR CONSTANT POINTER TO MEMBERS
1209
 
1210
    This routine checks whether the expression e consists of a cast of the
1211
    address of a member of some class.  If so it returns the corresponding
1212
    member identifier.
1213
*/
1214
 
7 7u83 1215
static IDENTIFIER
1216
is_const_ptr_mem(EXP e, int rev)
2 7u83 1217
{
7 7u83 1218
	if (!IS_NULL_exp(e)) {
1219
		unsigned tag = TAG_exp(e);
1220
		if (tag == exp_address_mem_tag) {
1221
			/* Allow for addresses of members */
1222
			EXP a = DEREF_exp(exp_address_mem_arg(e));
1223
			IDENTIFIER id = DEREF_id(exp_member_id(a));
1224
			return (id);
1225
		} else if (tag == exp_base_cast_tag) {
1226
			/* Allow for base casts */
1227
			EXP a = DEREF_exp(exp_base_cast_arg(e));
1228
			unsigned conv = DEREF_unsigned(exp_base_cast_conv(e));
1229
			if (rev || !(conv & CONV_REVERSE)) {
1230
				IDENTIFIER id = is_const_ptr_mem(a, rev);
1231
				return (id);
1232
			}
1233
		} else if (tag == exp_dummy_tag) {
1234
			/* Allow for dummy expressions */
1235
			EXP a = DEREF_exp(exp_dummy_value(e));
1236
			IDENTIFIER id = is_const_ptr_mem(a, rev);
1237
			return (id);
1238
		}
2 7u83 1239
	}
7 7u83 1240
	return (NULL_id);
2 7u83 1241
}
1242
 
1243
 
1244
/*
1245
    ENCODE A POINTER TO MEMBER
1246
 
1247
    This routine adds the address of the member id plus the base class
1248
    offset gr, converted to type t, to the bitstream bs.
1249
*/
1250
 
7 7u83 1251
static BITSTREAM *
1252
enc_ptr_mem(BITSTREAM *bs, TYPE t, IDENTIFIER id, GRAPH gr)
2 7u83 1253
{
7 7u83 1254
	BITSTREAM *ts = start_bitstream(NIL(FILE), bs->link);
1255
	if (IS_id_mem_func(id)) {
1256
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
1257
		CLASS_TYPE ct = DEREF_ctype(type_ptr_mem_of(t));
1258
		ASSERT(!(ds & dspec_inherit));
1259
		if (ds & dspec_virtual) {
1260
			/* Virtual member function */
1261
			ulong m;
1262
			ulong tok;
1263
			VIRTUAL vt;
1264
			OFFSET off;
1265
			IGNORE compile_class(ct);
1266
			vt = DEREF_virt(ctype_virt(ct));
1267
			off = DEREF_off(virt_table_off(vt));
1268
			tok = DEREF_ulong(virt_table_tok(vt));
1269
			if (!IS_NULL_graph(gr)) {
1270
				/* Allow for overriding virtual functions */
1271
				GRAPH gs = NULL_graph;
1272
				VIRTUAL at = find_overrider(ct, id, gr, &gs);
1273
				if (!IS_NULL_virt(at)) {
1274
					id = DEREF_id(virt_func(at));
1275
				}
1276
			}
1277
			m = virtual_no(id, vt);
1278
			bs = enc_special(bs, TOK_pmf_vmake);
1279
			ts = enc_make_snat(ts,(int)m);
1280
			if (!is_zero_offset(off)) {
1281
				ENC_offset_add(ts);
1282
				ts = enc_offset(ts, off);
1283
			}
1284
			tok = link_no(ts, tok, VAR_token);
1285
			ENC_exp_apply_token(ts);
1286
			ENC_make_tok(ts, tok);
1287
			ENC_LEN_SMALL(ts, 0);
1288
			ENC_offset_zero(ts);
1289
			ts = enc_al_ctype(ts, ct);
1290
			ENC_offset_zero(ts);
1291
			ts = enc_al_ctype(ts, ct);
1292
		} else {
1293
			/* Member function */
1294
			bs = enc_special(bs, TOK_pmf_make);
1295
			ts = enc_member(ts, id);
1296
			if (IS_NULL_graph(gr)) {
1297
				ENC_offset_zero(ts);
1298
				ts = enc_al_ctype(ts, ct);
1299
			} else {
1300
				ts = enc_base(ts, gr, 0);
1301
			}
1302
			ENC_offset_zero(ts);
1303
			ts = enc_al_ctype(ts, ct);
2 7u83 1304
		}
1305
	} else {
7 7u83 1306
		/* Data member */
1307
		bs = enc_special(bs, TOK_pm_make);
1308
		if (!IS_NULL_graph(gr)) {
1309
			DECL_SPEC acc = DEREF_dspec(graph_access(gr));
1310
			if (!(acc & dspec_ignore)) {
1311
				ENC_offset_add(ts);
1312
				ts = enc_base(ts, gr, 0);
1313
			}
1314
		}
1315
		ts = enc_member(ts, id);
2 7u83 1316
	}
7 7u83 1317
	bs = enc_bitstream(bs, ts);
1318
	return (bs);
2 7u83 1319
}
1320
 
1321
 
1322
/*
1323
    ENCODE A CAST EXPRESSION
1324
 
1325
    This routine adds a TDF EXP to the bitstream bs representing a cast
1326
    of the expression e to the type t.  conv represents the conversion
1327
    type (see cast.c).
1328
*/
1329
 
7 7u83 1330
static BITSTREAM *
1331
enc_cast_exp(BITSTREAM *bs, TYPE t, EXP e, unsigned conv)
2 7u83 1332
{
7 7u83 1333
	BITSTREAM *ts;
1334
	switch (conv) {
2 7u83 1335
 
7 7u83 1336
	case CONV_EXACT:
1337
	case CONV_FUNC:
1338
	case CONV_STRING:
1339
	case CONV_PTR_PTR_ALIGN:
1340
	case CONV_PTR_MEM_PTR_MEM: {
1341
		/* Trivial conversions */
1342
		bs = enc_exp(bs, e);
1343
		break;
2 7u83 1344
	}
1345
 
7 7u83 1346
	case CONV_QUAL: {
1347
		/* Qualification conversions */
1348
		if (IS_exp_address(e)) {
1349
			EXP a = DEREF_exp(exp_address_arg(e));
1350
			bs = enc_addr_exp(bs, t, a);
1351
		} else {
1352
			bs = enc_exp(bs, e);
1353
		}
1354
		break;
2 7u83 1355
	}
1356
 
7 7u83 1357
	case CONV_ELLIPSIS: {
1358
		/* Discarded expression */
1359
		if (overflow_exp(e)) {
1360
			bs = enc_stmt_exp(bs, e, t, 0);
1361
		} else {
1362
			bs = enc_null_exp(bs, t);
1363
		}
1364
		break;
2 7u83 1365
	}
1366
 
7 7u83 1367
	case CONV_INT_INT:
1368
	case CONV_ENUM: {
1369
		/* Integer to integer conversion */
1370
		TYPE u = DEREF_type(exp_type(e));
1371
		switch (TAG_exp(e)) {
1372
		case exp_char_lit_tag: {
1373
			STRING s = DEREF_str(exp_char_lit_str(e));
1374
			bs = enc_char(bs, s, t, u);
1375
			break;
2 7u83 1376
		}
7 7u83 1377
		case exp_cast_tag: {
1378
			conv = DEREF_unsigned(exp_cast_conv(e));
1379
			if (conv == CONV_BITFIELD) {
1380
				/* Elide following bitfield conversion */
1381
				e = DEREF_exp(exp_cast_arg(e));
1382
				ENC_change_bitfield_to_int(bs);
1383
				bs = enc_variety(bs, t);
1384
				bs = enc_exp(bs, e);
1385
				break;
1386
			}
1387
			goto int_int_label;
2 7u83 1388
		}
7 7u83 1389
		case exp_not_tag:
1390
		case exp_log_and_tag:
1391
		case exp_log_or_tag:
1392
		case exp_test_tag:
1393
		case exp_compare_tag: {
1394
			/* Logical expressions */
1395
			bs = enc_logical(bs, e, t);
1396
			break;
2 7u83 1397
		}
1398
		default :
7 7u83 1399
int_int_label: {
1400
		       if (!eq_type_rep(u, t, 0)) {
1401
			       ENC_change_variety(bs);
1402
			       bs = enc_error_treatment(bs, t);
1403
			       bs = enc_variety(bs, t);
1404
		       }
1405
		       bs = enc_exp(bs, e);
1406
		       break;
1407
	       }
2 7u83 1408
		}
7 7u83 1409
		break;
2 7u83 1410
	}
1411
 
7 7u83 1412
	case CONV_BITFIELD: {
1413
		/* Bitfield to integer conversion */
1414
		ENC_change_bitfield_to_int(bs);
1415
		bs = enc_variety(bs, t);
1416
		bs = enc_exp(bs, e);
1417
		break;
2 7u83 1418
	}
1419
 
7 7u83 1420
	case CONV_BITFIELD | CONV_REVERSE: {
1421
		/* Integer to bitfield conversion */
1422
		if (IS_exp_cast(e)) {
1423
			conv = DEREF_unsigned(exp_cast_conv(e));
1424
			if (conv == CONV_INT_INT) {
1425
				/* Elide following integer conversion */
1426
				e = DEREF_exp(exp_cast_arg(e));
1427
			}
2 7u83 1428
		}
7 7u83 1429
		ENC_change_int_to_bitfield(bs);
1430
		bs = enc_bfvar(bs, t);
1431
		bs = enc_exp(bs, e);
1432
		break;
2 7u83 1433
	}
1434
 
7 7u83 1435
	case CONV_INT_FLT: {
1436
		/* Integer to float conversion */
1437
		if (IS_exp_int_lit(e)) {
1438
			NAT n = DEREF_nat(exp_int_lit_nat(e));
1439
			unsigned long v = get_nat_value(n);
1440
			if (v < SMALL_FLOAT_CONST) {
1441
				/* Small floating point constants */
1442
				bs = enc_float_int(bs,(int)v, t);
1443
				break;
1444
			}
2 7u83 1445
		}
7 7u83 1446
		ENC_float_int(bs);
1447
		ENC_impossible(bs);
1448
		bs = enc_flvar(bs, t);
1449
		bs = enc_exp(bs, e);
1450
		break;
2 7u83 1451
	}
1452
 
7 7u83 1453
	case CONV_FLT_INT: {
1454
		/* Float to integer conversion */
1455
		ENC_round_with_mode(bs);
1456
		ENC_impossible(bs);
1457
		ENC_RMODE(bs, crt_round_mode);
1458
		bs = enc_variety(bs, t);
1459
		bs = enc_exp(bs, e);
1460
		break;
2 7u83 1461
	}
1462
 
7 7u83 1463
	case CONV_FLT_FLT: {
1464
		/* Float to float conversion */
1465
		ENC_change_floating_variety(bs);
1466
		ENC_impossible(bs);
1467
		bs = enc_flvar(bs, t);
1468
		bs = enc_exp(bs, e);
1469
		break;
2 7u83 1470
	}
1471
 
7 7u83 1472
	case CONV_PTR_VOID:
2 7u83 1473
	case CONV_PTR_VOID | CONV_REVERSE :
7 7u83 1474
pointer_void_label: {
1475
			    /* Object pointer and 'void *' conversions */
1476
			    if (conv & CONV_REVERSE) {
1477
				    bs = enc_special(bs, TOK_from_ptr_void);
1478
			    } else {
1479
				    bs = enc_special(bs, TOK_to_ptr_void);
1480
				    t = DEREF_type(exp_type(e));
1481
			    }
1482
			    ts = start_bitstream(NIL(FILE), bs->link);
1483
			    t = DEREF_type(type_ptr_etc_sub(t));
1484
			    ts = enc_alignment(ts, t);
1485
			    ts = enc_exp(ts, e);
1486
			    bs = enc_bitstream(bs, ts);
1487
			    break;
1488
		    }
2 7u83 1489
 
7 7u83 1490
	case CONV_PTR_PTR:
1491
	case CONV_PTR_BASE:
2 7u83 1492
	case CONV_PTR_PTR | CONV_REVERSE :
7 7u83 1493
	case CONV_PTR_BASE | CONV_REVERSE: {
1494
		/* Pointer to pointer conversion */
1495
		TYPE s = DEREF_type(exp_type(e));
1496
		TYPE ps = DEREF_type(type_ptr_etc_sub(s));
1497
		TYPE pt = DEREF_type(type_ptr_etc_sub(t));
1498
		switch (TAG_type(pt)) {
1499
		case type_top_tag:
1500
		case type_bottom_tag: {
1501
			switch (TAG_type(ps)) {
1502
			case type_top_tag:
1503
			case type_bottom_tag: {
1504
				/* 'void *' to 'void *' */
1505
				bs = enc_exp(bs, e);
1506
				break;
2 7u83 1507
			}
7 7u83 1508
			case type_func_tag: {
1509
				/* Function to 'void *' */
1510
				bs = enc_special(bs, TOK_f_to_pv);
1511
				ts = start_bitstream(NIL(FILE), bs->link);
1512
				ts = enc_exp(ts, e);
1513
				bs = enc_bitstream(bs, ts);
1514
				break;
2 7u83 1515
			}
7 7u83 1516
			default: {
1517
				/* Object pointer to 'void *' */
1518
				conv = CONV_PTR_VOID;
1519
				goto pointer_void_label;
2 7u83 1520
			}
7 7u83 1521
			}
1522
			break;
2 7u83 1523
		}
7 7u83 1524
		case type_func_tag: {
1525
			switch (TAG_type(ps)) {
1526
			case type_top_tag:
1527
			case type_bottom_tag: {
1528
				/* 'void *' to function */
1529
				bs = enc_special(bs, TOK_pv_to_f);
1530
				ts = start_bitstream(NIL(FILE), bs->link);
1531
				ts = enc_exp(ts, e);
1532
				bs = enc_bitstream(bs, ts);
1533
				break;
2 7u83 1534
			}
7 7u83 1535
			case type_func_tag: {
1536
				/* Function to function */
1537
				bs = enc_exp(bs, e);
1538
				break;
2 7u83 1539
			}
7 7u83 1540
			default: {
1541
				/* Object pointer to function */
1542
				BITSTREAM *us;
1543
				bs = enc_special(bs, TOK_pv_to_f);
1544
				ts = start_bitstream(NIL(FILE), bs->link);
1545
				ts = enc_special(ts, TOK_to_ptr_void);
1546
				us = start_bitstream(NIL(FILE), ts->link);
1547
				us = enc_alignment(us, ps);
1548
				us = enc_exp(us, e);
1549
				ts = enc_bitstream(ts, us);
1550
				bs = enc_bitstream(bs, ts);
1551
				break;
2 7u83 1552
			}
7 7u83 1553
			}
1554
			break;
2 7u83 1555
		}
7 7u83 1556
		default: {
1557
			switch (TAG_type(ps)) {
1558
			case type_top_tag:
1559
			case type_bottom_tag: {
1560
				/* 'void *' to object pointer */
1561
				conv = (CONV_PTR_VOID | CONV_REVERSE);
1562
				goto pointer_void_label;
2 7u83 1563
			}
7 7u83 1564
			case type_func_tag: {
1565
				/* Function to object pointer */
1566
				BITSTREAM *us;
1567
				bs = enc_special(bs, TOK_from_ptr_void);
1568
				ts = start_bitstream(NIL(FILE), bs->link);
1569
				ts = enc_alignment(ts, pt);
1570
				ts = enc_special(ts, TOK_f_to_pv);
1571
				us = start_bitstream(NIL(FILE), ts->link);
1572
				us = enc_exp(us, e);
1573
				ts = enc_bitstream(ts, us);
1574
				bs = enc_bitstream(bs, ts);
1575
				break;
2 7u83 1576
			}
7 7u83 1577
			default: {
1578
				/* Object pointer to object pointer */
1579
				if (conv & CONV_REVERSE) {
1580
					/* Force conversion in these cases */
1581
					/* EMPTY */
1582
				} else {
1583
					if (eq_type_rep(ps, pt, 1)) {
1584
						bs = enc_exp(bs, e);
1585
						break;
1586
					}
2 7u83 1587
				}
7 7u83 1588
				bs = enc_special(bs, TOK_ptr_to_ptr);
1589
				ts = start_bitstream(NIL(FILE), bs->link);
1590
				ts = enc_alignment(ts, ps);
1591
				ts = enc_alignment(ts, pt);
1592
				ts = enc_exp(ts, e);
1593
				bs = enc_bitstream(bs, ts);
1594
				break;
2 7u83 1595
			}
7 7u83 1596
			}
1597
			break;
2 7u83 1598
		}
7 7u83 1599
		}
1600
		break;
2 7u83 1601
	}
1602
 
7 7u83 1603
	case CONV_INT_PTR: {
1604
		/* Integer to pointer conversion */
1605
		TYPE s = DEREF_type(exp_type(e));
1606
		TYPE pt = DEREF_type(type_ptr_etc_sub(t));
1607
		switch (TAG_type(pt)) {
1608
		case type_top_tag:
1609
		case type_bottom_tag: {
1610
			/* Integer to 'void *' */
1611
			bs = enc_special(bs, TOK_i_to_pv);
1612
			ts = start_bitstream(NIL(FILE), bs->link);
1613
			ts = enc_variety(ts, s);
1614
			ts = enc_exp(ts, e);
1615
			bs = enc_bitstream(bs, ts);
1616
			break;
2 7u83 1617
		}
7 7u83 1618
		case type_func_tag: {
1619
			/* Integer to function */
1620
			BITSTREAM *us;
1621
			bs = enc_special(bs, TOK_pv_to_f);
1622
			ts = start_bitstream(NIL(FILE), bs->link);
1623
			ts = enc_special(ts, TOK_i_to_pv);
1624
			us = start_bitstream(NIL(FILE), ts->link);
1625
			us = enc_variety(us, s);
1626
			us = enc_exp(us, e);
1627
			ts = enc_bitstream(ts, us);
1628
			bs = enc_bitstream(bs, ts);
1629
			break;
2 7u83 1630
		}
7 7u83 1631
		default: {
1632
			/* Integer to object pointer */
1633
			bs = enc_special(bs, TOK_i_to_p);
1634
			ts = start_bitstream(NIL(FILE), bs->link);
1635
			ts = enc_variety(ts, s);
1636
			ts = enc_alignment(ts, pt);
1637
			ts = enc_exp(ts, e);
1638
			bs = enc_bitstream(bs, ts);
1639
			break;
2 7u83 1640
		}
7 7u83 1641
		}
1642
		break;
2 7u83 1643
	}
1644
 
7 7u83 1645
	case CONV_PTR_INT: {
1646
		/* Pointer to integer conversion */
1647
		TYPE s = DEREF_type(exp_type(e));
1648
		TYPE ps = DEREF_type(type_ptr_etc_sub(s));
1649
		switch (TAG_type(ps)) {
1650
		case type_top_tag:
1651
		case type_bottom_tag: {
1652
			/* 'void *' to integer */
1653
			bs = enc_special(bs, TOK_pv_to_i);
1654
			ts = start_bitstream(NIL(FILE), bs->link);
1655
			ts = enc_variety(ts, t);
1656
			ts = enc_exp(ts, e);
1657
			bs = enc_bitstream(bs, ts);
1658
			break;
2 7u83 1659
		}
7 7u83 1660
		case type_func_tag: {
1661
			/* Function to integer */
1662
			BITSTREAM *us;
1663
			bs = enc_special(bs, TOK_pv_to_i);
1664
			ts = start_bitstream(NIL(FILE), bs->link);
1665
			ts = enc_variety(ts, t);
1666
			ts = enc_special(ts, TOK_f_to_pv);
1667
			us = start_bitstream(NIL(FILE), ts->link);
1668
			us = enc_exp(us, e);
1669
			ts = enc_bitstream(ts, us);
1670
			bs = enc_bitstream(bs, ts);
1671
			break;
2 7u83 1672
		}
7 7u83 1673
		default: {
1674
			/* Object pointer to integer */
1675
			bs = enc_special(bs, TOK_p_to_i);
1676
			ts = start_bitstream(NIL(FILE), bs->link);
1677
			ts = enc_alignment(ts, ps);
1678
			ts = enc_variety(ts, t);
1679
			ts = enc_exp(ts, e);
1680
			bs = enc_bitstream(bs, ts);
1681
			break;
2 7u83 1682
		}
7 7u83 1683
		}
1684
		break;
2 7u83 1685
	}
1686
 
7 7u83 1687
	case CONV_NULL: {
1688
		/* Null pointer conversion */
1689
		bs = enc_null_exp(bs, t);
1690
		break;
2 7u83 1691
	}
1692
 
7 7u83 1693
	case CONV_PTR_MEM_FUNC: {
1694
		/* Pointer to member function to function conversion */
1695
		IDENTIFIER fn = is_const_ptr_mem(e, 1);
1696
		if (!IS_NULL_id(fn)) {
1697
			/* Constant function */
1698
			ulong n = unit_no(bs, fn, VAR_tag, 0);
1699
			ENC_obtain_tag(bs);
1700
			ENC_make_tag(bs, n);
1701
		} else {
1702
			/* Non-constant function */
1703
			ulong n = LINK_NONE;
1704
			bs = make_ptr_mem_func(bs, e, &n, 0);
1705
			bs = enc_special(bs, TOK_pmf_func);
1706
			ts = start_bitstream(NIL(FILE), bs->link);
1707
			ENC_obtain_tag(ts);
1708
			ENC_make_tag(ts, n);
1709
			bs = enc_bitstream(bs, ts);
1710
		}
1711
		break;
2 7u83 1712
	}
1713
 
7 7u83 1714
	default: {
1715
		/* Other conversions */
1716
		TYPE s = DEREF_type(exp_type(e));
1717
		if (eq_type_rep(s, t, 0)) {
1718
			bs = enc_exp(bs, e);
1719
		} else {
1720
			ENC_component(bs);
1721
			bs = enc_shape(bs, t);
1722
			ENC_make_compound(bs);
1723
			ENC_offset_max(bs);
1724
			ENC_shape_offset(bs);
1725
			bs = enc_shape(bs, s);
1726
			ENC_shape_offset(bs);
1727
			bs = enc_shape(bs, t);
1728
			ENC_LIST_SMALL(bs, 2);
1729
			ENC_offset_zero(bs);
1730
			bs = enc_alignment(bs, s);
1731
			bs = enc_exp(bs, e);
1732
			ENC_offset_zero(bs);
1733
			bs = enc_alignment(bs, t);
1734
		}
1735
		break;
2 7u83 1736
	}
7 7u83 1737
	}
1738
	return (bs);
2 7u83 1739
}
1740
 
1741
 
1742
/*
1743
    ENCODE A BASE CLASS CONVERSION
1744
 
1745
    This routine adds the base class conversion of e using the base
1746
    offset off to the bitstream bs.  conv represents the conversion type.
1747
*/
1748
 
7 7u83 1749
static BITSTREAM *
1750
enc_base_cast_exp(BITSTREAM *bs, EXP e, OFFSET off, unsigned conv)
2 7u83 1751
{
7 7u83 1752
	if (is_zero_offset(off)) {
1753
		/* Single inheritance */
1754
		bs = enc_exp(bs, e);
1755
	} else {
1756
		/* Multiple inheritance */
1757
		int ctok;
1758
		ulong lab;
1759
		BITSTREAM *ts;
1760
		int non_null = 0;
1761
		ulong n = LINK_NONE;
1762
		TYPE s = DEREF_type(exp_type(e));
1763
		EXP a = DEREF_exp(exp_dummy_value(e));
2 7u83 1764
 
7 7u83 1765
		/* Check for pointers to member functions */
1766
		if (IS_type_ptr_mem(s)) {
1767
			TYPE ps = DEREF_type(type_ptr_mem_sub(s));
1768
			if (IS_type_func(ps)) {
1769
				VIRTUAL vt;
1770
				CLASS_TYPE ct = DEREF_ctype(type_ptr_mem_of(s));
1771
				IGNORE compile_class(ct);
1772
				vt = DEREF_virt(ctype_virt(ct));
1773
				bs = make_ptr_mem_func(bs, a, &n, 1);
1774
				ENC_SEQ_SMALL(bs, 1);
1775
				if (conv & CONV_REVERSE) {
1776
					bs = enc_special(bs, TOK_pmf_uncast);
1777
				} else {
1778
					bs = enc_special(bs, TOK_pmf_cast);
1779
				}
1780
				ts = start_bitstream(NIL(FILE), bs->link);
1781
				ENC_obtain_tag(ts);
1782
				ENC_make_tag(ts, n);
1783
				ts = enc_offset(ts, off);
1784
				ENC_make_int(ts);
1785
				ts = enc_variety(ts, type_sint);
1786
				ENC_make_signed_nat(ts);
1787
				ENC_OFF(ts);
1788
				if (IS_NULL_virt(vt)) {
1789
					ENC_INT(ts, 0);
1790
					ENC_offset_zero(ts);
1791
					ENC_alignment(ts);
1792
					ts = enc_special(ts, TOK_vtab_diag);
1793
				} else {
1794
					ulong vs = 0;
1795
					OFFSET voff =
1796
					    DEREF_off(virt_table_off(vt));
1797
					ulong tok =
1798
					    DEREF_ulong(virt_table_tok(vt));
1799
					if (IS_off_base(off)) {
1800
						GRAPH gs = DEREF_graph(off_base_graph(off));
1801
						vs = virtual_start(gs);
1802
					} else if (IS_off_deriv(off)) {
1803
						GRAPH gs = DEREF_graph(off_deriv_graph(off));
1804
						vs = virtual_start(gs);
1805
					}
1806
					ENC_INT(ts, vs);
1807
					if (!is_zero_offset(voff)) {
1808
						ENC_offset_add(ts);
1809
						ts = enc_offset(ts, voff);
1810
					}
1811
					tok = link_no(ts, tok, VAR_token);
1812
					ENC_exp_apply_token(ts);
1813
					ENC_make_tok(ts, tok);
1814
					ENC_LEN_SMALL(ts, 0);
1815
				}
1816
				bs = enc_bitstream(bs, ts);
1817
				ENC_contents(bs);
1818
				bs = enc_special(bs, TOK_pmf_type);
1819
				ENC_obtain_tag(bs);
1820
				ENC_make_tag(bs, n);
1821
				return (bs);
1822
			}
2 7u83 1823
		}
7 7u83 1824
 
1825
		/* Check for null pointers */
1826
		switch (TAG_exp(a)) {
1827
		case exp_address_tag:
1828
		case exp_address_mem_tag: {
1829
			/* These can't be null */
1830
			non_null = 1;
1831
			break;
2 7u83 1832
		}
7 7u83 1833
		}
1834
		if (!non_null) {
1835
			/* Set up dummy variable */
1836
			COPY_exp(exp_dummy_value(e), NULL_exp);
1837
			n = unit_no(bs, NULL_id, VAR_tag, 1);
1838
			COPY_ulong(exp_dummy_no(e), n);
2 7u83 1839
 
7 7u83 1840
			/* Introduce variable */
1841
			ENC_variable(bs);
1842
			bs = enc_access(bs, dspec_none);
1843
			ENC_make_tag(bs, n);
1844
			bs = enc_exp(bs, a);
1845
			ENC_SEQ_SMALL(bs, 1);
2 7u83 1846
 
7 7u83 1847
			/* Check for null pointer */
1848
			ENC_conditional(bs);
1849
			lab = unit_no(bs, NULL_id, VAR_label, 1);
1850
			ENC_make_label(bs, lab);
1851
			bs = enc_compare(bs, e, NULL_exp, ntest_eq, lab,
1852
					 LINK_NONE);
2 7u83 1853
 
7 7u83 1854
			/* Assign to variable */
1855
			ENC_assign(bs);
1856
			ENC_obtain_tag(bs);
1857
			ENC_make_tag(bs, n);
1858
		}
2 7u83 1859
 
7 7u83 1860
		/* Add base class offset */
1861
		ctok = TOK_pm_uncast;
1862
		switch (conv) {
1863
		case CONV_PTR_MEM_BASE: {
1864
			/* Pointer to data member conversions */
1865
			ctok = TOK_pm_cast;
1866
			goto ptr_mem_label;
1867
		}
1868
ptr_mem_label:
1869
		case CONV_PTR_MEM_BASE | CONV_REVERSE: {
1870
			/* Pointer to data member conversions */
1871
			bs = enc_special(bs, ctok);
1872
			ts = start_bitstream(NIL(FILE), bs->link);
1873
			ts = enc_exp(ts, e);
1874
			ts = enc_offset(ts, off);
1875
			bs = enc_bitstream(bs, ts);
1876
			break;
1877
		}
1878
		default: {
1879
			/* Pointer conversions */
1880
			if (conv & CONV_REVERSE) {
1881
				TYPE ps = DEREF_type(type_ptr_etc_sub(s));
1882
				bs = enc_special(bs, TOK_down_cast);
1883
				ts = start_bitstream(NIL(FILE), bs->link);
1884
				ts = enc_alignment(ts, ps);
1885
				ts = enc_exp(ts, e);
1886
				ts = enc_offset(ts, off);
1887
				bs = enc_bitstream(bs, ts);
1888
			} else {
1889
				bs = enc_add_ptr(bs, e, LINK_NONE, off, 1);
1890
			}
1891
			break;
1892
		}
1893
		}
2 7u83 1894
 
7 7u83 1895
		/* Return variable contents */
1896
		if (!non_null) {
1897
			bs = enc_exp(bs, e);
1898
			COPY_exp(exp_dummy_value(e), a);
2 7u83 1899
		}
1900
	}
7 7u83 1901
	return (bs);
2 7u83 1902
}
1903
 
1904
 
1905
/*
1906
    ENCODE A TDF ERROR TREATMENT
1907
 
1908
    This routine adds an error treatment corresponding to arithmetic
1909
    operations on the arithmetic type t to the bitstream bs.
1910
*/
1911
 
7 7u83 1912
BITSTREAM *
1913
enc_error_treatment(BITSTREAM *bs, TYPE t)
2 7u83 1914
{
7 7u83 1915
	if (IS_type_floating(t) || check_int_type(t, btype_signed)) {
1916
		ENC_impossible(bs);
1917
	} else {
1918
		ENC_wrap(bs);
1919
	}
1920
	return (bs);
2 7u83 1921
}
1922
 
1923
 
1924
/*
1925
    ENCODE A LIST OF VIRTUAL FUNCTION ARGUMENTS
1926
 
1927
    This routine adds the list of virtual function arguments p to the
1928
    bitstream bs.  m is a tag number giving a pointer into the virtual
1929
    function table and j gives the number of the argument corresponding
1930
    to the object pointer.
1931
*/
1932
 
7 7u83 1933
static BITSTREAM *
1934
enc_virt_args(BITSTREAM *bs, LIST(EXP)p, ulong m, unsigned j)
2 7u83 1935
{
7 7u83 1936
	unsigned i;
1937
	unsigned n = LENGTH_list(p);
1938
	ENC_LIST(bs, n);
1939
	for (i = 0; i < n; i++) {
1940
		EXP e = DEREF_exp(HEAD_list(p));
1941
		if (i == j) {
1942
			TYPE t;
1943
			BITSTREAM *ts;
1944
			ENC_add_to_ptr(bs);
1945
			bs = enc_exp(bs, e);
1946
			bs = enc_special(bs, TOK_pmf_delta);
1947
			ts = start_bitstream(NIL(FILE), bs->link);
1948
			t = DEREF_type(exp_type(e));
1949
			if (IS_type_ptr_etc(t)) {
1950
				t = DEREF_type(type_ptr_etc_sub(t));
1951
			}
1952
			ts = enc_alignment(ts, t);
1953
			ENC_obtain_tag(ts);
1954
			ENC_make_tag(ts, m);
1955
			bs = enc_bitstream(bs, ts);
1956
		} else {
1957
			bs = enc_exp(bs, e);
1958
		}
1959
		p = TAIL_list(p);
2 7u83 1960
	}
7 7u83 1961
	return (bs);
2 7u83 1962
}
1963
 
1964
 
1965
/*
1966
    ENCODE A NAMED FUNCTION CALL
1967
 
1968
    This routine outputs an apply_proc construct for the identifier
1969
    function call given by e to the bitstream bs.  t gives the return
1970
    type.
1971
*/
1972
 
7 7u83 1973
static BITSTREAM *
1974
enc_func_id_call(BITSTREAM *bs, TYPE t, EXP e)
2 7u83 1975
{
7 7u83 1976
	IDENTIFIER id = DEREF_id(exp_func_id_id(e));
1977
	LIST(EXP)args = DEREF_list(exp_func_id_args(e));
1978
	EXP virt = DEREF_exp(exp_func_id_virt(e));
2 7u83 1979
 
7 7u83 1980
	/* Check for static member functions */
1981
	unsigned tag = TAG_id(id);
1982
	if (tag == id_stat_mem_func_tag) {
1983
		EXP a = DEREF_exp(HEAD_list(args));
1984
		if (!IS_NULL_exp(a)) {
1985
			ENC_SEQ_SMALL(bs, 1);
1986
			bs = enc_exp(bs, a);
1987
		}
1988
		args = TAIL_list(args);
2 7u83 1989
	}
1990
 
7 7u83 1991
	/* Output the procedure application */
1992
	if (tag == id_token_tag) {
1993
		/* Function token */
1994
		ulong n;
1995
		IGNORE enc_tokdef(id, 0);
1996
		ENC_exp_apply_token(bs);
1997
		n = unit_no(bs, id, VAR_token, 0);
1998
		ENC_make_tok(bs, n);
1999
		if (IS_NULL_list(args)) {
2000
			ENC_LEN_SMALL(bs, 0);
2001
		} else {
2002
			BITSTREAM *ts = start_bitstream(NIL(FILE), bs->link);
2003
			while (!IS_NULL_list(args)) {
2004
				EXP a = DEREF_exp(HEAD_list(args));
2005
				ts = enc_exp(ts, a);
2006
				args = TAIL_list(args);
2007
			}
2008
			bs = enc_bitstream(bs, ts);
2009
		}
2 7u83 2010
 
7 7u83 2011
	} else if (!IS_NULL_exp(virt)) {
2012
		/* Virtual function */
2013
		EXP a;
2014
		ulong tok;
2015
		VIRTUAL vt;
2016
		unsigned i;
2017
		OFFSET off;
2018
		BITSTREAM *ts;
2019
		ulong n, m, p;
2 7u83 2020
 
7 7u83 2021
		/* Find class information */
2022
		CLASS_TYPE ct = parent_class(id);
2023
		IGNORE compile_class(ct);
2024
		vt = DEREF_virt(ctype_virt(ct));
2025
		off = DEREF_off(virt_table_off(vt));
2026
		tok = DEREF_ulong(virt_table_tok(vt));
2027
		m = virtual_no(id, vt);
2 7u83 2028
 
7 7u83 2029
		/* Introduce variable for argument */
2030
		a = DEREF_exp(exp_dummy_value(virt));
2031
		bs = make_ptr_mem_func(bs, a, &n, 0);
2032
		COPY_exp(exp_dummy_value(virt), NULL_exp);
2033
		COPY_ulong(exp_dummy_no(virt), n);
2 7u83 2034
 
7 7u83 2035
		/* Find pointer to member function */
2036
		p = unit_no(bs, NULL_id, VAR_tag, 1);
2037
		ENC_identify(bs);
2038
		bs = enc_access(bs, dspec_none);
2039
		ENC_make_tag(bs, p);
2040
		bs = enc_special(bs, TOK_vtab_func);
2041
		ts = start_bitstream(NIL(FILE), bs->link);
2042
		ENC_add_to_ptr(ts);
2043
		ts = enc_add_ptr(ts, virt, LINK_NONE, off, 0);
2044
		tok = link_no(ts, tok, VAR_token);
2045
		ENC_exp_apply_token(ts);
2046
		ENC_make_tok(ts, tok);
2047
		ENC_LEN_SMALL(ts, 0);
2048
		ts = enc_make_snat(ts,(int)m);
2049
		bs = enc_bitstream(bs, ts);
2 7u83 2050
 
7 7u83 2051
		/* Encode function call */
2052
		ENC_apply_proc(bs);
2053
		bs = enc_shape(bs, t);
2054
		bs = enc_special(bs, TOK_pmf_func);
2055
		ts = start_bitstream(NIL(FILE), bs->link);
2056
		ENC_obtain_tag(ts);
2057
		ENC_make_tag(ts, p);
2058
		bs = enc_bitstream(bs, ts);
2059
		i = DEREF_unsigned(exp_func_id_extra(e));
2060
		bs = enc_virt_args(bs, args, p, i);
2061
		ENC_OFF(bs);
2062
		COPY_exp(exp_dummy_value(virt), a);
2 7u83 2063
 
7 7u83 2064
	} else {
2065
		/* Simple function */
2066
		ulong n;
2067
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
2068
		if ((ds & dspec_inline) && !(ds & dspec_temp)) {
2069
			/* Check for function inlining */
2070
			if (output_inline) {
2071
				EXP a = check_inline(id, args, t);
2072
				if (!IS_NULL_exp(a)) {
2073
					COPY_dspec(id_storage(id),
2074
						   (ds | dspec_temp));
2075
					bs = enc_exp(bs, a);
2076
					free_exp(a, 1);
2077
					COPY_dspec(id_storage(id), ds);
2078
					return (bs);
2079
				}
2080
			}
2 7u83 2081
		}
7 7u83 2082
		ENC_apply_proc(bs);
2083
		bs = enc_shape(bs, t);
2084
		IGNORE capsule_id(id, VAR_tag);
2085
		n = unit_no(bs, id, VAR_tag, 0);
2086
		ENC_obtain_tag(bs);
2087
		ENC_make_tag(bs, n);
2088
		bs = enc_exp_list(bs, args);
2089
		ENC_OFF(bs);
2 7u83 2090
	}
7 7u83 2091
	return (bs);
2 7u83 2092
}
2093
 
2094
 
2095
/*
2096
    ENCODE A FUNCTION CALL
2097
 
2098
    This routine outputs an apply_proc construct for the expression
2099
    function call given by e to the bitstream bs.  t gives the return
2100
    type.
2101
*/
2102
 
7 7u83 2103
static BITSTREAM *
2104
enc_func_call(BITSTREAM *bs, TYPE t, EXP e)
2 7u83 2105
{
7 7u83 2106
	EXP a = DEREF_exp(exp_func_fn(e));
2107
	LIST(EXP)args = DEREF_list(exp_func_args(e));
2108
	if (IS_exp_call(a)) {
2109
		/* Pointer to member function call */
2110
		EXP b;
2111
		EXP b1;
2112
		TYPE s;
2113
		ulong n;
2114
		unsigned i;
2115
		BITSTREAM *ts;
2116
		CLASS_TYPE ct;
2117
		ulong m = LINK_NONE;
2 7u83 2118
 
7 7u83 2119
		/* Decompose pointer to member */
2120
		b = DEREF_exp(exp_call_arg(a));
2121
		b1 = DEREF_exp(exp_dummy_value(b));
2122
		a = DEREF_exp(exp_call_ptr(a));
2123
		s = DEREF_type(exp_type(a));
2124
		ct = DEREF_ctype(type_ptr_mem_of(s));
2 7u83 2125
 
7 7u83 2126
		/* Introduce variable for argument */
2127
		bs = make_ptr_mem_func(bs, b1, &m, 0);
2128
		COPY_exp(exp_dummy_value(b), NULL_exp);
2129
		COPY_ulong(exp_dummy_no(b), m);
2130
		IGNORE compile_class(ct);
2 7u83 2131
 
7 7u83 2132
		/* Allow for virtual functions */
2133
		bs = make_ptr_mem_func(bs, a, &n, 1);
2134
		ENC_SEQ_SMALL(bs, 1);
2135
		bs = enc_special(bs, TOK_pmf_virt);
2136
		ts = start_bitstream(NIL(FILE), bs->link);
2137
		ENC_obtain_tag(ts);
2138
		ENC_make_tag(ts, n);
2139
		ts = enc_exp(ts, b);
2140
		ts = enc_al_ctype(ts, ct);
2141
		bs = enc_bitstream(bs, ts);
2 7u83 2142
 
7 7u83 2143
		/* Encode call */
2144
		ENC_apply_proc(bs);
2145
		bs = enc_shape(bs, t);
2146
		bs = enc_special(bs, TOK_pmf_func);
2147
		ts = start_bitstream(NIL(FILE), bs->link);
2148
		ENC_obtain_tag(ts);
2149
		ENC_make_tag(ts, n);
2150
		bs = enc_bitstream(bs, ts);
2151
		i = DEREF_unsigned(exp_func_extra(e));
2152
		bs = enc_virt_args(bs, args, n, i);
2153
		ENC_OFF(bs);
2154
		COPY_exp(exp_dummy_value(b), b1);
2155
	} else {
2156
		/* Simple function call */
2157
		ENC_apply_proc(bs);
2158
		bs = enc_shape(bs, t);
2159
		bs = enc_exp(bs, a);
2160
		bs = enc_exp_list(bs, args);
2161
		ENC_OFF(bs);
2162
	}
2163
	return (bs);
2 7u83 2164
}
2165
 
2166
 
2167
/*
2168
    ENCODE A DUMMY EXPRESSION
2169
 
2170
    This routine adds the dummy expression given by the tag n plus the
2171
    offset off to the bitstream bs.  cnt gives the expression type.
2172
*/
2173
 
7 7u83 2174
BITSTREAM *
2175
enc_dummy_exp(BITSTREAM *bs, TYPE t, ulong n, OFFSET off, int cnt, int virt)
2 7u83 2176
{
7 7u83 2177
	int bf = 0;
2178
	OFFSET off1 = NULL_off;
2179
	if (cnt > 2) {
2180
		/* Special tag */
2181
		n = last_params[cnt];
2182
		cnt = last_conts[cnt];
2183
	}
2184
	if (n == LINK_NONE) {
2185
		/* This shouldn't happen */
2186
		n = capsule_no(NULL_string, VAR_tag);
2187
	}
2188
	if (n & LINK_EXTERN) {
2189
		/* Allow for global tags */
2190
		n = link_no(bs, n, VAR_tag);
2191
	}
2192
	if (cnt == 1) {
2193
		/* Contents */
2194
		bs = enc_cont_op(bs, t, &bf);
2195
		if (bf) {
2196
			off1 = decons_bitf_off(&off);
2197
			bs = enc_bfvar(bs, t);
2198
		} else {
2199
			bs = enc_shape(bs, t);
2200
		}
2201
	} else if (cnt == 2) {
2202
		/* Contents of pointer */
2203
		ENC_contents(bs);
2204
		ENC_pointer(bs);
2205
		bs = enc_alignment(bs, t);
2206
	}
2207
	if (is_zero_offset(off)) {
2208
		/* Zero offset */
2209
		ENC_obtain_tag(bs);
2210
		ENC_make_tag(bs, n);
2211
	} else if (virt) {
2212
		/* Virtual base offset */
2213
		EXP e;
2214
		MAKE_exp_dummy(t, NULL_exp, n, NULL_off, 0, e);
2215
		bs = enc_add_ptr(bs, e, LINK_NONE, off, 1);
2216
		free_exp(e, 1);
2 7u83 2217
	} else {
7 7u83 2218
		/* Non-virtual base offset */
2219
		ENC_add_to_ptr(bs);
2220
		ENC_obtain_tag(bs);
2221
		ENC_make_tag(bs, n);
2222
		bs = enc_offset(bs, off);
2 7u83 2223
	}
7 7u83 2224
	if (bf) {
2225
		/* End of bitfield contents */
2226
		bs = enc_offset(bs, off1);
2227
	}
2228
	return (bs);
2 7u83 2229
}
2230
 
2231
 
2232
/*
2233
    ENCODE AN ASSIGNMENT EXPRESSION
2234
 
2235
    This routine adds the assignment or initialisation expression 'a = b'
2236
    to the bitstream bs.
2237
*/
2238
 
7 7u83 2239
static BITSTREAM *
2240
enc_assign_exp(BITSTREAM *bs, EXP a, EXP b)
2 7u83 2241
{
7 7u83 2242
	TYPE s = DEREF_type(exp_type(a));
2243
	if (IS_exp_dummy(a)) {
2244
		/* Check for dummy expressions */
2245
		EXP c = DEREF_exp(exp_dummy_value(a));
2246
		if (IS_NULL_exp(c)) {
2247
			ulong n = DEREF_ulong(exp_dummy_no(a));
2248
			OFFSET off = DEREF_off(exp_dummy_off(a));
2249
			int cnt = DEREF_int(exp_dummy_cont(a));
2250
			bs = enc_init_tag(bs, n, off, cnt, s, b, NULL_exp, 0);
2251
			return (bs);
2252
		}
2 7u83 2253
	}
7 7u83 2254
	if (is_init_complex(b)) {
2255
		/* Introduce identity for complex assignment */
2256
		ulong n;
2257
		bs = make_identity(bs, a, &n, 0, 0);
2258
		bs = enc_init_tag(bs, n, NULL_off, 0, s, b, NULL_exp, 0);
2 7u83 2259
	} else {
7 7u83 2260
		/* Simple assignment */
2261
		int bf = 0;
2262
		bs = enc_assign_op(bs, s, &bf);
2263
		if (bf) {
2264
			/* Bitfield assignment */
2265
			OFFSET off = decons_bitf_exp(&a);
2266
			bs = enc_addr_exp(bs, s, a);
2267
			bs = enc_offset(bs, off);
2268
		} else {
2269
			/* Non-bitfield assignment */
2270
			bs = enc_addr_exp(bs, s, a);
2271
		}
2272
		bs = enc_exp(bs, b);
2 7u83 2273
	}
7 7u83 2274
	return (bs);
2 7u83 2275
}
2276
 
2277
 
2278
/*
2279
    ENCODE A TDF EXP
2280
 
2281
    This routine adds the expression e to the bitstream bs as a TDF EXP.
2282
*/
2283
 
7 7u83 2284
BITSTREAM *
2285
enc_exp(BITSTREAM *bs, EXP e)
2 7u83 2286
{
7 7u83 2287
	TYPE t;
2288
	if (IS_NULL_exp(e)) {
2289
		/* Deal with null expressions */
2290
		ENC_make_top(bs);
2291
		return (bs);
2292
	}
2 7u83 2293
 
7 7u83 2294
	/* Examine expression cases */
2295
	t = DEREF_type(exp_type(e));
2296
	ASSERT(ORDER_exp == 88);
2297
	switch (TAG_exp(e)) {
2 7u83 2298
 
7 7u83 2299
	case exp_identifier_tag: {
2300
		/* Identifier lvalue expressions */
2301
		bs = enc_addr_exp(bs, t, e);
2302
		break;
2 7u83 2303
	}
2304
 
7 7u83 2305
	case exp_int_lit_tag: {
2306
		/* Integer literals */
2307
		NAT n = DEREF_nat(exp_int_lit_nat(e));
2308
		unsigned etag = DEREF_unsigned(exp_int_lit_etag(e));
2309
		bs = enc_int_lit(bs, n, t, etag);
2310
		break;
2 7u83 2311
	}
2312
 
7 7u83 2313
	case exp_float_lit_tag: {
2314
		/* Floating literals */
2315
		FLOAT f = DEREF_flt(exp_float_lit_flt(e));
2316
		bs = enc_float(bs, f, t);
2317
		break;
2 7u83 2318
	}
2319
 
7 7u83 2320
	case exp_char_lit_tag: {
2321
		/* Character literals */
2322
		STRING s = DEREF_str(exp_char_lit_str(e));
2323
		bs = enc_char(bs, s, t, t);
2324
		break;
2 7u83 2325
	}
2326
 
7 7u83 2327
	case exp_string_lit_tag: {
2328
		/* String literals */
2329
		STRING s = DEREF_str(exp_string_lit_str(e));
2330
		bs = enc_string(bs, s, t);
2331
		break;
2 7u83 2332
	}
2333
 
7 7u83 2334
	case exp_value_tag: {
2335
		/* Undefined values */
2336
		if (IS_type_top(t)) {
2337
			ENC_make_top(bs);
2338
		} else {
2339
			ENC_make_value(bs);
2340
			bs = enc_shape(bs, t);
2341
		}
2342
		break;
2 7u83 2343
	}
2344
 
7 7u83 2345
	case exp_null_tag:
2346
	case exp_zero_tag: {
2347
		/* Null expressions */
2348
		bs = enc_null_exp(bs, t);
2349
		break;
2 7u83 2350
	}
2351
 
7 7u83 2352
	case exp_paren_tag:
2353
	case exp_copy_tag: {
2354
		/* Parenthesised expressions */
2355
		EXP a = DEREF_exp(exp_paren_etc_arg(e));
2356
		bs = enc_exp(bs, a);
2357
		break;
2 7u83 2358
	}
2359
 
7 7u83 2360
	case exp_assign_tag: {
2361
		/* Assignment expressions */
2362
		EXP a = DEREF_exp(exp_assign_ref(e));
2363
		EXP b = DEREF_exp(exp_assign_arg(e));
2364
		bs = enc_assign_exp(bs, a, b);
2365
		break;
2 7u83 2366
	}
2367
 
7 7u83 2368
	case exp_init_tag: {
2369
		/* Initialisation expressions */
2370
		ulong n;
2371
		int context = 1;
2372
		IDENTIFIER id = DEREF_id(exp_init_id(e));
2373
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
2374
		EXP a = DEREF_exp(exp_init_arg(e));
2375
		EXP d = DEREF_exp(id_variable_etc_term(id));
2376
		if (!IS_NULL_exp(d)) {
2377
			while (IS_exp_nof(d)) {
2378
				d = DEREF_exp(exp_nof_pad(d));
2379
			}
2380
			ENC_SEQ_SMALL(bs, 1);
2 7u83 2381
		}
7 7u83 2382
		if (!(ds & dspec_auto)) {
2383
			/* Allow for external variables */
2384
			if (capsule_id(id, VAR_tag)) {
2385
				make_term_global(t, &d);
2386
			}
2387
			context = 2;
2 7u83 2388
		}
7 7u83 2389
		n = unit_no(bs, id, VAR_tag, 0);
2390
		bs = enc_init_tag(bs, n, NULL_off, 0, t, a, d, context);
2391
		break;
2 7u83 2392
	}
2393
 
7 7u83 2394
	case exp_preinc_tag: {
2395
		/* Pre-increment expressions */
2396
		int bf = 0;
2397
		ulong n = LINK_NONE;
2398
		EXP a = DEREF_exp(exp_preinc_ref(e));
2399
		EXP b = DEREF_exp(exp_preinc_op(e));
2400
		EXP a1 = DEREF_exp(exp_dummy_value(a));
2401
		TYPE s = DEREF_type(exp_type(a));
2402
		int op = DEREF_int(exp_preinc_becomes(e));
2 7u83 2403
 
7 7u83 2404
		/* Declare identity for complex operations */
2405
		if (op != lex_assign) {
2406
			COPY_exp(exp_dummy_value(a), NULL_exp);
2407
			bs = make_identity(bs, a1, &n, 0, 0);
2408
			COPY_ulong(exp_dummy_no(a), n);
2409
		}
2 7u83 2410
 
7 7u83 2411
		/* Encode the result */
2412
		bs = enc_assign_op(bs, s, &bf);
2413
		if (n == LINK_NONE) {
2414
			bs = enc_exp(bs, a1);
2415
		} else {
2416
			ENC_obtain_tag(bs);
2417
			ENC_make_tag(bs, n);
2418
		}
2419
		if (bf) {
2420
			OFFSET off = DEREF_off(exp_dummy_off(a));
2421
			bs = enc_offset(bs, off);
2422
		}
2423
		bs = enc_exp(bs, b);
2424
		COPY_exp(exp_dummy_value(a), a1);
2425
		break;
2 7u83 2426
	}
2427
 
7 7u83 2428
	case exp_postinc_tag: {
2429
		/* Post-increment expressions */
2430
		ulong n;
2431
		int bf = 0;
2432
		EXP a = DEREF_exp(exp_postinc_ref(e));
2433
		EXP b = DEREF_exp(exp_postinc_value(e));
2434
		EXP c = DEREF_exp(exp_postinc_op(e));
2435
		EXP a1 = DEREF_exp(exp_dummy_value(a));
2436
		EXP b1 = NULL_exp;
2437
		TYPE s = DEREF_type(exp_type(a));
2 7u83 2438
 
7 7u83 2439
		/* Declare outer identity */
2440
		COPY_exp(exp_dummy_value(a), NULL_exp);
2441
		bs = make_identity(bs, a1, &n, 0, 0);
2442
		COPY_ulong(exp_dummy_no(a), n);
2 7u83 2443
 
7 7u83 2444
		/* Declare inner identity if necessary */
2445
		if (!IS_NULL_exp(b)) {
2446
			ulong m;
2447
			b1 = DEREF_exp(exp_dummy_value(b));
2448
			COPY_exp(exp_dummy_value(b), NULL_exp);
2449
			bs = make_identity(bs, b1, &m, 1, 1);
2450
			COPY_ulong(exp_dummy_no(b), m);
2451
		}
2 7u83 2452
 
7 7u83 2453
		/* Encode the result */
2454
		bs = enc_assign_op(bs, s, &bf);
2455
		ENC_obtain_tag(bs);
2456
		ENC_make_tag(bs, n);
2457
		if (bf) {
2458
			OFFSET off = DEREF_off(exp_dummy_off(a));
2459
			bs = enc_offset(bs, off);
2460
		}
2461
		bs = enc_exp(bs, c);
2462
		if (!IS_NULL_exp(b)) {
2463
			bs = enc_exp(bs, b);
2464
			COPY_exp(exp_dummy_value(b), b1);
2465
		}
2466
		COPY_exp(exp_dummy_value(a), a1);
2467
		break;
2 7u83 2468
	}
2469
 
7 7u83 2470
	case exp_indir_tag: {
2471
		/* Indirection expressions */
2472
		EXP a = DEREF_exp(exp_indir_ptr(e));
2473
		bs = enc_exp(bs, a);
2474
		break;
2 7u83 2475
	}
2476
 
7 7u83 2477
	case exp_contents_tag: {
2478
		/* Contents expressions */
2479
		EXP a = DEREF_exp(exp_contents_ptr(e));
2480
		bs = enc_cont_exp(bs, t, a);
2481
		break;
2 7u83 2482
	}
2483
 
7 7u83 2484
	case exp_address_tag: {
2485
		/* Address expressions */
2486
		EXP a = DEREF_exp(exp_address_arg(e));
2487
		bs = enc_addr_exp(bs, t, a);
2488
		break;
2 7u83 2489
	}
2490
 
7 7u83 2491
	case exp_address_mem_tag: {
2492
		/* Member address expressions */
2493
		EXP a = DEREF_exp(exp_address_mem_arg(e));
2494
		IDENTIFIER id = DEREF_id(exp_member_id(a));
2495
		bs = enc_ptr_mem(bs, t, id, NULL_graph);
2496
		break;
2 7u83 2497
	}
2498
 
7 7u83 2499
	case exp_func_tag: {
2500
		/* Function applications */
2501
		bs = enc_func_call(bs, t, e);
2502
		break;
2 7u83 2503
	}
2504
 
7 7u83 2505
	case exp_func_id_tag: {
2506
		/* Function identifier applications */
2507
		bs = enc_func_id_call(bs, t, e);
2508
		break;
2 7u83 2509
	}
2510
 
7 7u83 2511
	case exp_negate_tag: {
2512
		/* Negation expressions */
2513
		if (IS_type_floating(t)) {
2514
			ENC_floating_negate(bs);
2515
		} else {
2516
			ENC_negate(bs);
2517
		}
2518
		goto unary_err_label;
2 7u83 2519
	}
2520
 
7 7u83 2521
	case exp_compl_tag: {
2522
		/* Complement expressions */
2523
		ENC_not(bs);
2524
		goto unary_label;
2 7u83 2525
	}
2526
 
7 7u83 2527
	case exp_abs_tag: {
2528
		/* Absolute expressions */
2529
		if (IS_type_floating(t)) {
2530
			ENC_floating_abs(bs);
2531
		} else {
2532
			ENC_abs(bs);
2533
		}
2534
		goto unary_err_label;
2 7u83 2535
	}
2536
 
7 7u83 2537
unary_err_label: {
2538
			 /* Unary operands with error treatment */
2539
			 bs = enc_error_treatment(bs, t);
2540
			 goto unary_label;
2541
		 }
2 7u83 2542
 
7 7u83 2543
unary_label: {
2544
		     /* Unary operands */
2545
		     EXP a = DEREF_exp(exp_negate_etc_arg(e));
2546
		     bs = enc_exp(bs, a);
2547
		     break;
2548
	     }
2549
 
2550
	case exp_plus_tag: {
2551
		/* Addition expressions */
2552
		unsigned tag = TAG_type(t);
2553
		if (tag == type_floating_tag) {
2554
			ENC_floating_plus(bs);
2555
			ENC_impossible(bs);
2556
			ENC_LIST_SMALL(bs, 2);
2557
		} else {
2558
			if (tag == type_enumerate_tag) {
2559
				/* Special case for enumerators */
2560
				t = promote_type(t);
2561
			}
2562
			ENC_plus(bs);
2563
			bs = enc_error_treatment(bs, t);
2564
		}
2565
		goto binary_label;
2 7u83 2566
	}
2567
 
7 7u83 2568
	case exp_minus_tag: {
2569
		/* Subtraction expressions */
2570
		if (IS_type_floating(t)) {
2571
			ENC_floating_minus(bs);
2572
		} else {
2573
			ENC_minus(bs);
2 7u83 2574
		}
7 7u83 2575
		goto binary_err_label;
2 7u83 2576
	}
2577
 
7 7u83 2578
	case exp_mult_tag: {
2579
		/* Multiplication expressions */
2580
		if (IS_type_floating(t)) {
2581
			ENC_floating_mult(bs);
2582
			ENC_impossible(bs);
2583
			ENC_LIST_SMALL(bs, 2);
2584
		} else {
2585
			ENC_mult(bs);
2586
			bs = enc_error_treatment(bs, t);
2587
		}
2588
		goto binary_label;
2 7u83 2589
	}
2590
 
7 7u83 2591
	case exp_div_tag: {
2592
		/* Division expressions */
2593
		if (IS_type_floating(t)) {
2594
			ENC_floating_div(bs);
2595
		} else {
2596
			int div_mode = division_mode;
2597
			if (div_mode == 3) {
2598
				/* Tokenised division */
2599
				bs = enc_special(bs, TOK_div);
2600
				goto division_label;
2601
			}
2602
			switch (div_mode) {
2603
			case 0:
2604
				ENC_div0(bs);
2605
				break;
2606
			case 1:
2607
				ENC_div1(bs);
2608
				break;
2609
			case 2:
2610
				ENC_div2(bs);
2611
				break;
2612
			}
2613
			ENC_impossible(bs);
2614
		}
2615
		goto binary_err_label;
2 7u83 2616
	}
2617
 
7 7u83 2618
	case exp_rem_tag: {
2619
		/* Remainder expressions */
2620
		int div_mode = division_mode;
2621
		if (div_mode == 3) {
2622
			/* Tokenised division */
2623
			bs = enc_special(bs, TOK_rem);
2624
			goto division_label;
2 7u83 2625
		}
7 7u83 2626
		switch (div_mode) {
2627
		case 0:
2628
			ENC_rem0(bs);
2629
			break;
2630
		case 1:
2631
			ENC_rem1(bs);
2632
			break;
2633
		case 2:
2634
			ENC_rem2(bs);
2635
			break;
2 7u83 2636
		}
7 7u83 2637
		ENC_impossible(bs);
2638
		goto binary_err_label;
2 7u83 2639
	}
2640
 
7 7u83 2641
division_label: {
2642
			/* Division operands */
2643
			EXP a = DEREF_exp(exp_plus_etc_arg1(e));
2644
			EXP b = DEREF_exp(exp_plus_etc_arg2(e));
2645
			BITSTREAM *ts = start_bitstream(NIL(FILE), bs->link);
2646
			ts = enc_exp(ts, a);
2647
			ts = enc_exp(ts, b);
2648
			bs = enc_bitstream(bs, ts);
2649
			break;
2650
		}
2 7u83 2651
 
7 7u83 2652
	case exp_and_tag: {
2653
		/* Bitwise and expressions */
2654
		ENC_and(bs);
2655
		goto binary_label;
2 7u83 2656
	}
2657
 
7 7u83 2658
	case exp_or_tag: {
2659
		/* Bitwise or expressions */
2660
		ENC_or(bs);
2661
		goto binary_label;
2 7u83 2662
	}
2663
 
7 7u83 2664
	case exp_xor_tag: {
2665
		/* Bitwise xor expressions */
2666
		ENC_xor(bs);
2667
		goto binary_label;
2 7u83 2668
	}
2669
 
7 7u83 2670
	case exp_lshift_tag: {
2671
		/* Left shift expressions */
2672
		ENC_shift_left(bs);
2673
		goto binary_err_label;
2 7u83 2674
	}
2675
 
7 7u83 2676
	case exp_rshift_tag: {
2677
		/* Right shift expressions */
2678
		ENC_shift_right(bs);
2679
		goto binary_label;
2 7u83 2680
	}
2681
 
7 7u83 2682
	case exp_max_tag: {
2683
		/* Maximum expressions */
2684
		if (IS_type_floating(t)) {
2685
			ENC_floating_maximum(bs);
2686
#if (TDF_major >= 4)
2687
			ENC_impossible(bs);
2 7u83 2688
#endif
7 7u83 2689
		} else {
2690
			ENC_maximum(bs);
2691
		}
2692
		goto binary_label;
2 7u83 2693
	}
2694
 
7 7u83 2695
	case exp_min_tag: {
2696
		/* Minimum expressions */
2697
		if (IS_type_floating(t)) {
2698
			ENC_floating_minimum(bs);
2699
#if (TDF_major >= 4)
2700
			ENC_impossible(bs);
2 7u83 2701
#endif
7 7u83 2702
		} else {
2703
			ENC_minimum(bs);
2704
		}
2705
		goto binary_label;
2 7u83 2706
	}
2707
 
7 7u83 2708
binary_err_label: {
2709
			  /* Binary operands with error treatment */
2710
			  bs = enc_error_treatment(bs, t);
2711
			  goto binary_label;
2712
		  }
2 7u83 2713
 
7 7u83 2714
binary_label: {
2715
		      /* Binary operands */
2716
		      EXP a = DEREF_exp(exp_plus_etc_arg1(e));
2717
		      EXP b = DEREF_exp(exp_plus_etc_arg2(e));
2718
		      bs = enc_exp(bs, a);
2719
		      bs = enc_exp(bs, b);
2720
		      break;
2721
	      }
2 7u83 2722
 
7 7u83 2723
	case exp_cast_tag: {
2724
		/* Cast expressions */
2725
		EXP a = DEREF_exp(exp_cast_arg(e));
2726
		unsigned conv = DEREF_unsigned(exp_cast_conv(e));
2727
		bs = enc_cast_exp(bs, t, a, conv);
2728
		break;
2 7u83 2729
	}
2730
 
7 7u83 2731
	case exp_base_cast_tag: {
2732
		/* Base class cast expressions */
2733
		EXP a = DEREF_exp(exp_base_cast_arg(e));
2734
		OFFSET off = DEREF_off(exp_base_cast_off(e));
2735
		unsigned conv = DEREF_unsigned(exp_base_cast_conv(e));
2736
		if (conv == CONV_PTR_MEM_BASE) {
2737
			/* Check for constant pointer to members */
2738
			IDENTIFIER fn = is_const_ptr_mem(a, 0);
2739
			if (!IS_NULL_id(fn)) {
2740
				CLASS_TYPE cs = parent_class(fn);
2741
				CLASS_TYPE ct = DEREF_ctype(type_ptr_mem_of(t));
2742
				GRAPH gr = find_base_class(ct, cs, 0);
2743
				bs = enc_ptr_mem(bs, t, fn, gr);
2744
				break;
2745
			}
2 7u83 2746
		}
7 7u83 2747
		bs = enc_base_cast_exp(bs, a, off, conv);
2748
		break;
2 7u83 2749
	}
2750
 
7 7u83 2751
	case exp_add_ptr_tag: {
2752
		/* Pointer additions */
2753
		EXP a = DEREF_exp(exp_add_ptr_ptr(e));
2754
		OFFSET off = DEREF_off(exp_add_ptr_off(e));
2755
		int virt = DEREF_int(exp_add_ptr_virt(e));
2756
		bs = enc_add_ptr(bs, a, LINK_NONE, off, virt);
2757
		break;
2 7u83 2758
	}
2759
 
7 7u83 2760
	case exp_offset_size_tag: {
2761
		/* Size of offset */
2762
		OFFSET off = DEREF_off(exp_offset_size_off(e));
2763
		TYPE s = DEREF_type(exp_offset_size_step(e));
2764
		ENC_offset_div(bs);
2765
		bs = enc_variety(bs, t);
2766
		bs = enc_offset(bs, off);
2767
		bs = enc_shape_offset(bs, s);
2768
		break;
2 7u83 2769
	}
2770
 
7 7u83 2771
	case exp_constr_tag: {
2772
		/* Constructor calls */
2773
		EXP a = DEREF_exp(exp_constr_call(e));
2774
		bs = enc_exp(bs, a);
2775
		break;
2 7u83 2776
	}
2777
 
7 7u83 2778
	case exp_destr_tag: {
2779
		/* Destructor calls */
2780
		EXP a = DEREF_exp(exp_destr_call(e));
2781
		bs = enc_exp(bs, a);
2782
		break;
2 7u83 2783
	}
2784
 
7 7u83 2785
	case exp_rtti_no_tag: {
2786
		/* Link-time type information */
2787
		TYPE s = DEREF_type(exp_rtti_no_arg(e));
2788
		ENC_make_int(bs);
2789
		bs = enc_variety(bs, t);
2790
		bs = enc_arith(bs, s, 0);
2791
		break;
2 7u83 2792
	}
2793
 
7 7u83 2794
	case exp_dynamic_tag: {
2795
		/* Dynamic initialisers */
2796
		EXP a = DEREF_exp(exp_dynamic_arg(e));
2797
		bs = enc_exp(bs, a);
2798
		break;
2 7u83 2799
	}
2800
 
7 7u83 2801
	case exp_aggregate_tag: {
2802
		/* Aggregate initialisers */
2803
		unsigned tt = TAG_type(t);
2804
		if (tt == type_array_tag) {
2805
			bs = enc_init_array(bs, e, NULL_nat, t);
2806
		} else if (tt == type_compound_tag) {
2807
			CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
2808
			bs = enc_init_class(bs, e, ct);
2809
		}
2810
		break;
2 7u83 2811
	}
2812
 
7 7u83 2813
	case exp_nof_tag: {
2814
		/* Array initialisers */
2815
		int pad = 1;
2816
		EXP a = DEREF_exp(exp_nof_start(e));
2817
		NAT n = DEREF_nat(exp_nof_size(e));
2818
		EXP b = DEREF_exp(exp_nof_pad(e));
2819
		EXP c = DEREF_exp(exp_nof_end(e));
2820
		if (!IS_NULL_exp(c))ENC_concat_nof(bs);
2821
		if (!IS_NULL_exp(a)) {
2822
			/* Encode initial component */
2823
			if (IS_exp_aggregate(a) && is_zero_exp(b)) {
2824
				/* Deal with integral arrays */
2825
				bs = enc_init_array(bs, a, n, t);
2826
				break;
2827
			}
2828
			if (is_zero_nat(n)) {
2829
				pad = 0;
2830
			} else {
2831
				ENC_concat_nof(bs);
2832
			}
2833
			bs = enc_exp(bs, a);
2 7u83 2834
		}
7 7u83 2835
		if (pad) {
2836
			ENC_n_copies(bs);
2837
			bs = enc_nat(bs, n, 1);
2838
			if (IS_NULL_exp(b)) {
2839
				TYPE s = DEREF_type(type_array_sub(t));
2840
				bs = enc_null_exp(bs, s);
2841
			} else {
2842
				bs = enc_exp(bs, b);
2843
			}
2 7u83 2844
		}
7 7u83 2845
		if (!IS_NULL_exp(c)) {
2846
			bs = enc_exp(bs, c);
2 7u83 2847
		}
7 7u83 2848
		break;
2 7u83 2849
	}
2850
 
7 7u83 2851
	case exp_call_tag: {
2852
		/* Shouldn't happen */
2853
		EXP a = DEREF_exp(exp_call_ptr(e));
2854
		EXP b = DEREF_exp(exp_call_arg(e));
2855
		ENC_SEQ_SMALL(bs, 1);
2856
		bs = enc_exp(bs, a);
2857
		bs = enc_exp(bs, b);
2858
		break;
2 7u83 2859
	}
2860
 
7 7u83 2861
	case exp_not_tag:
2862
	case exp_log_and_tag:
2863
	case exp_log_or_tag:
2864
	case exp_test_tag:
2865
	case exp_compare_tag: {
2866
		/* Logical expressions */
2867
		bs = enc_logical(bs, e, t);
2868
		break;
2 7u83 2869
	}
2870
 
7 7u83 2871
	case exp_assembler_tag: {
2872
		/* Assembler expression */
2873
		bs = enc_asm(bs, e);
2874
		break;
2 7u83 2875
	}
2876
 
7 7u83 2877
	case exp_fail_tag: {
2878
		/* Install-time failure expression */
2879
		string s = DEREF_string(exp_fail_msg(e));
2880
		ENC_fail_installer(bs);
2881
		ENC_make_string(bs);
2882
		bs = enc_ustring(bs, s);
2883
		break;
2 7u83 2884
	}
2885
 
7 7u83 2886
	case exp_token_tag: {
2887
		/* Token applications */
2888
		IDENTIFIER tok = DEREF_id(exp_token_tok(e));
2889
		LIST(TOKEN)args = DEREF_list(exp_token_args(e));
2890
		bs = enc_token(bs, tok, args);
2891
		break;
2 7u83 2892
	}
2893
 
7 7u83 2894
	case exp_dummy_tag: {
2895
		/* Dummy identifier tag */
2896
		EXP a = DEREF_exp(exp_dummy_value(e));
2897
		if (IS_NULL_exp(a)) {
2898
			ulong n = DEREF_ulong(exp_dummy_no(e));
2899
			OFFSET off = DEREF_off(exp_dummy_off(e));
2900
			int cnt = DEREF_int(exp_dummy_cont(e));
2901
			int virt = DEREF_int(exp_dummy_virt(e));
2902
			bs = enc_dummy_exp(bs, t, n, off, cnt, virt);
2903
		} else {
2904
			bs = enc_exp(bs, a);
2905
		}
2906
		break;
2 7u83 2907
	}
2908
 
2909
#if LANGUAGE_CPP
7 7u83 2910
	case exp_alloc_tag: {
2911
		/* Allocator calls */
2912
		bs = enc_alloc(bs, e);
2913
		break;
2 7u83 2914
	}
2915
 
7 7u83 2916
	case exp_dealloc_tag: {
2917
		/* Deallocator calls */
2918
		bs = enc_dealloc(bs, e, LINK_NONE);
2919
		break;
2 7u83 2920
	}
2921
 
7 7u83 2922
	case exp_rtti_tag: {
2923
		/* Run-time type information */
2924
		if (IS_type_compound(t)) {
2925
			/* Make sure that 'type_info' is completed */
2926
			CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
2927
			IGNORE compile_class(ct);
2928
		}
2929
		bs = enc_rtti_exp(bs, e);
2930
		break;
2 7u83 2931
	}
2932
 
7 7u83 2933
	case exp_rtti_type_tag: {
2934
		/* Run-time type information */
2935
		TYPE s = DEREF_type(exp_rtti_type_arg(e));
2936
		int op = DEREF_int(exp_rtti_type_op(e));
2937
		if (IS_type_compound(t)) {
2938
			/* Make sure that 'type_info' is completed */
2939
			CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
2940
			IGNORE compile_class(ct);
2941
		}
2942
		bs = enc_rtti_type(bs, s, op);
2943
		break;
2 7u83 2944
	}
2945
 
7 7u83 2946
	case exp_dyn_cast_tag: {
2947
		/* Dynamic cast expressions */
2948
		bs = enc_dyn_cast(bs, e);
2949
		break;
2 7u83 2950
	}
2951
 
7 7u83 2952
	case exp_initialiser_tag: {
2953
		/* Constructor initialisers */
2954
		bs = enc_ctor_init(bs, e);
2955
		break;
2 7u83 2956
	}
2957
 
7 7u83 2958
	case exp_exception_tag: {
2959
		/* Throw expression */
2960
		EXP a = DEREF_exp(exp_exception_arg(e));
2961
		EXP b = DEREF_exp(exp_exception_size(e));
2962
		EXP d = DEREF_exp(exp_exception_destr(e));
2963
		bs = enc_throw(bs, a, b, d);
2964
		break;
2 7u83 2965
	}
2966
 
7 7u83 2967
	case exp_thrown_tag: {
2968
		/* Thrown expression */
2969
		int done = DEREF_int(exp_thrown_done(e));
2970
		if (done) {
2971
			bs = enc_special(bs, TOK_except_caught);
2972
		} else {
2973
			bs = enc_thrown(bs, t);
2974
		}
2975
		break;
2 7u83 2976
	}
2977
#endif
2978
 
7 7u83 2979
	case exp_comma_tag:
2980
	case exp_if_stmt_tag:
2981
	case exp_hash_if_tag:
2982
	case exp_location_tag: {
2983
		/* Statement-like expressions */
2984
		bs = enc_stmt_exp(bs, e, t, 1);
2985
		break;
2 7u83 2986
	}
2987
 
7 7u83 2988
	case exp_reach_tag:
2989
	case exp_unreach_tag:
2990
	case exp_sequence_tag:
2991
	case exp_solve_stmt_tag:
2992
	case exp_decl_stmt_tag:
2993
	case exp_while_stmt_tag:
2994
	case exp_do_stmt_tag:
2995
	case exp_switch_stmt_tag:
2996
	case exp_return_stmt_tag:
2997
	case exp_goto_stmt_tag:
2998
	case exp_label_stmt_tag:
2999
	case exp_try_block_tag:
3000
	case exp_handler_tag: {
3001
		/* Statements */
3002
		bs = enc_stmt(bs, e);
3003
		break;
2 7u83 3004
	}
3005
 
7 7u83 3006
	case exp_member_tag:
3007
	case exp_ambiguous_tag:
3008
	case exp_undeclared_tag:
3009
	case exp_set_tag:
3010
	case exp_unused_tag:
3011
	case exp_op_tag:
3012
	case exp_opn_tag:
3013
	case exp_uncompiled_tag:
3014
	default: {
3015
		/* Illegal expressions */
3016
		ENC_make_top(bs);
3017
		break;
2 7u83 3018
	}
7 7u83 3019
	}
3020
	return (bs);
2 7u83 3021
}
3022
 
3023
 
3024
#endif /* TDF_OUTPUT */