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 "hashid_ops.h"
67
#include "id_ops.h"
68
#include "nspace_ops.h"
69
#include "tok_ops.h"
70
#include "type_ops.h"
71
#include "virt_ops.h"
72
#include "error.h"
73
#include "catalog.h"
74
#include "tdf.h"
75
#include "basetype.h"
76
#include "buffer.h"
77
#include "capsule.h"
78
#include "check.h"
79
#include "class.h"
80
#include "compile.h"
81
#include "constant.h"
82
#include "construct.h"
83
#include "convert.h"
84
#include "copy.h"
85
#include "destroy.h"
86
#include "diag.h"
87
#include "encode.h"
88
#include "exception.h"
89
#include "exp.h"
90
#include "file.h"
91
#include "function.h"
92
#include "identifier.h"
93
#include "init.h"
94
#include "initialise.h"
95
#include "mangle.h"
96
#include "namespace.h"
97
#include "redeclare.h"
98
#include "shape.h"
99
#include "statement.h"
100
#include "stmt.h"
101
#include "struct.h"
102
#include "tok.h"
103
#include "token.h"
104
#include "throw.h"
105
#include "ustring.h"
106
#include "variable.h"
107
#include "xalloc.h"
108
 
109
 
110
/*
111
    LIST OF ALL PENDING FUNCTIONS
112
 
113
    This list contains all the inline and implicit functions and
114
    literal constants defined in the program.
115
*/
116
 
7 7u83 117
LIST(IDENTIFIER)pending_funcs = NULL_list(IDENTIFIER);
2 7u83 118
 
119
 
120
/*
121
    CHECK A MANGLED IDENTIFIER NAME
122
 
123
    This routine checks whether the identifier id is used but not defined
124
    because, although it has external linkage, its mangled name is empty.
125
*/
126
 
7 7u83 127
static void
128
check_mangled(IDENTIFIER id)
2 7u83 129
{
7 7u83 130
	IDENTIFIER lid = DEREF_id(id_alias(id));
131
	DECL_SPEC ds = DEREF_dspec(id_storage(lid));
132
	if (!(ds & dspec_done)) {
133
		if ((ds & dspec_extern) && !(ds & dspec_defn)) {
134
			if (ds & (dspec_used | dspec_called)) {
135
				/* Should have an external name */
136
				string s = mangle_name(lid, VAR_tag, 0);
137
				if (s == NULL && has_linkage(lid)) {
138
					LOCATION loc;
139
					DEREF_loc(id_loc(lid), loc);
140
					report(loc, ERR_basic_odr_undef(lid));
141
				}
142
			}
2 7u83 143
		}
7 7u83 144
		ds |= dspec_done;
145
		COPY_dspec(id_storage(lid), ds);
2 7u83 146
	}
7 7u83 147
	return;
2 7u83 148
}
149
 
150
 
151
/*
152
    START OF TDF OUTPUT ROUTINES
153
 
154
    The compiler can optionally be compiled with the TDF output routines
155
    disabled by defining the TDF_OUTPUT macro to be zero on the
156
    command-line.  The following routines are concerned with TDF output.
157
*/
158
 
159
#if TDF_OUTPUT
160
 
161
 
162
/*
163
    CURRENT FUNCTION ACCESS
164
 
165
    This variable is used to hold the declaration specifiers for the
166
    current function.
167
*/
168
 
7 7u83 169
DECL_SPEC crt_func_access = dspec_none;
2 7u83 170
 
171
 
172
/*
173
    ENCODE AN IDENTIFIER ACCESS
174
 
175
    This routine adds an optional TDF ACCESS corresponding to the
176
    declaration specifiers ds.
177
*/
178
 
7 7u83 179
BITSTREAM *
180
enc_access(BITSTREAM *bs, DECL_SPEC ds)
2 7u83 181
{
7 7u83 182
	if (ds & dspec_mutable) {
183
		ENC_ON(bs);
184
		if (output_bugs) {
185
			/* Needed for old installer bug */
186
			ENC_add_accesses(bs);
187
			ENC_visible(bs);
188
		}
189
		ENC_long_jump_access(bs);
190
	} else {
191
		ENC_OFF(bs);
2 7u83 192
	}
7 7u83 193
	return (bs);
2 7u83 194
}
195
 
196
 
197
/*
198
    ENCODE AN IDENTIFIER SIGNATURE
199
 
200
    This routine adds an optional identifier signature corresponding to id
201
    to the bitstream bs.  Note that these signatures were only introduced
202
    in TDF version 4.0.
203
*/
204
 
7 7u83 205
static BITSTREAM *
206
enc_signature(BITSTREAM *bs, IDENTIFIER id)
2 7u83 207
{
7 7u83 208
#if (TDF_major >= 4)
209
	ENC_OFF(bs);
2 7u83 210
#endif
7 7u83 211
	UNUSED(id);
212
	return (bs);
2 7u83 213
}
214
 
215
 
216
/*
217
    SHOULD A VARIABLE BE COMMON?
218
 
219
    This routine checks whether the local static variable id should be
220
    made a common tag.  It returns 2 if it should and 1 otherwise (see
221
    enc_tagdec).  The prefix to be used for mangling the name is returned
222
    via ps.
223
*/
224
 
7 7u83 225
static int
226
is_common_tag(IDENTIFIER id, string *ps)
2 7u83 227
{
7 7u83 228
	NAMESPACE ns = DEREF_nspace(id_parent(id));
229
	IDENTIFIER pid = DEREF_id(nspace_name(ns));
230
	if (!IS_NULL_id(pid) && IS_id_function_etc(pid)) {
231
		DECL_SPEC ds = DEREF_dspec(id_storage(pid));
232
		if ((ds & dspec_inline) && (ds & dspec_extern)) {
233
			string s = mangle_name(pid, VAR_tag, 1);
234
			if (s) {
235
				*ps = s;
236
				return (2);
237
			}
238
		}
2 7u83 239
	}
7 7u83 240
	return (1);
2 7u83 241
}
242
 
243
 
244
/*
245
    CREATE A STATIC TAG DEFINITION
246
 
247
    This routine adds the tag declaration for the static variable id to
248
    the bitstream bs.  If id has a constant initialiser and no destructor
249
    then this is mapped to a simple tag definition, otherwise the
250
    initialisation and termination need to be done dynamically.
251
*/
252
 
7 7u83 253
static BITSTREAM *
254
enc_static_var(BITSTREAM *bs, IDENTIFIER id)
2 7u83 255
{
7 7u83 256
	ulong n;
257
	int ext = 0;
258
	BITSTREAM *ts;
259
	string s = NULL;
260
	int i = in_static_init;
261
	int uc = unreached_code;
262
	int var = is_common_tag(id, &s);
263
	TYPE t = DEREF_type(id_variable_type(id));
264
	EXP a = DEREF_exp(id_variable_init(id));
265
	EXP b = DEREF_exp(id_variable_term(id));
2 7u83 266
 
7 7u83 267
	/* Encode the tag declaration */
268
	if (var == 2 || output_all) {
269
		ext = 1;
270
	}
271
	IGNORE capsule_id(id, VAR_tag);
272
	n = DEREF_ulong(id_no(id));
273
	if (ext) {
274
		/* Make up external name for variable */
275
		string sn = mangle_common(s, id);
276
		n = capsule_name(n, &sn, VAR_tag);
277
	}
278
	enc_tagdec(id, n, t, var);
2 7u83 279
 
7 7u83 280
	/* Encode the tag definition */
281
	ts = enc_tagdef_start(id, n, t, var);
282
	in_static_init = 1;
283
	unreached_code = 0;
284
	if (!IS_NULL_exp(a) && IS_exp_dynamic(a)) {
285
		/* Dynamic initialiser */
286
		ts = enc_null_exp(ts, t);
2 7u83 287
	} else {
7 7u83 288
		/* Static initialiser */
289
		if (var == 2) {
290
			ts = enc_null_exp(ts, t);
291
			if (is_null_exp(a)) {
292
				a = NULL_exp;
293
			}
294
		} else {
295
			ts = enc_exp(ts, a);
296
			a = NULL_exp;
297
		}
2 7u83 298
	}
7 7u83 299
	unreached_code = uc;
300
	in_static_init = i;
301
	enc_tagdef_end(ts);
2 7u83 302
 
7 7u83 303
	/* Encode dynamic components */
304
	if (!IS_NULL_exp(a) || !IS_NULL_exp(b)) {
305
		/* Declare flag */
306
		ulong m1;
307
		int dummy = 0;
308
		EXP b1 = NULL_exp;
309
		TYPE si = type_sint;
310
		ulong m = capsule_no(NULL_string, VAR_tag);
311
		if (ext) {
312
			/* Make up external name for flag */
313
			string sm = mangle_common(s, NULL_id);
314
			m = capsule_name(m, &sm, VAR_tag);
2 7u83 315
		}
7 7u83 316
		enc_tagdec(NULL_id, m, si, var);
317
		ts = enc_tagdef_start(NULL_id, m, si, var);
318
		in_static_init = 1;
319
		ts = enc_make_int(ts, si, 0);
320
		in_static_init = i;
321
		enc_tagdef_end(ts);
322
		if (!IS_NULL_exp(b)) {
323
			if (!output_term) {
324
				/* Set up terminator if necessary */
325
				b1 = b;
326
				b = NULL_exp;
327
				make_term_global(t, &b1);
328
				if (IS_NULL_exp(a)) {
329
					a = make_dummy_init(t);
330
					dummy = 1;
331
				}
332
			}
333
			term_no++;
334
		}
2 7u83 335
 
7 7u83 336
		/* Encode initialiser */
337
		ENC_SEQ_SMALL(bs, 1);
338
		m1 = link_no(bs, m, VAR_tag);
339
		if (!IS_NULL_exp(a)) {
340
			unsigned seq = 2;
341
			ulong n1 = link_no(bs, n, VAR_tag);
342
			if (!IS_NULL_exp(b1)) {
343
				seq = 3;
344
			}
345
			bs = enc_flag_test(bs, m1, seq, 0, ntest_eq);
346
			bs = enc_init_tag(bs, n1, NULL_off, 0, t, a, b1, 2);
347
			if (dummy) {
348
				free_exp(a, 1);
349
			}
350
		}
351
		ENC_assign(bs);
352
		ENC_obtain_tag(bs);
353
		ENC_make_tag(bs, m1);
354
		bs = enc_make_int(bs, si, 1);
355
		if (!IS_NULL_exp(a)) {
356
			ENC_make_top(bs);
357
		}
2 7u83 358
 
7 7u83 359
		/* Encode destructor */
360
		if (!IS_NULL_exp(b)) {
361
			ts = term_static_func;
362
			ts = enc_term_global(ts, n, t, b, m);
363
			term_static_func = ts;
364
		}
2 7u83 365
	}
7 7u83 366
	return (bs);
2 7u83 367
}
368
 
369
 
370
/*
371
    CREATE A LOCAL TAG DEFINITION
372
 
373
    This routine adds the start of a local tag declaration for the variable
374
    id to the bitstream bs.  The definition body has to be added later.
375
    Any destructor for id is returned via d.  var is 1 to indicate that
376
    id is a variable as opposed to an identity.  A value of 2 or more for
377
    var indicates that the variable should be just declared rather than
378
    defined.  This is only used for automatic variables.  e gives the
379
    corresponding declaration statement for use with diagnostics.
380
*/
381
 
7 7u83 382
BITSTREAM *
383
enc_variable(BITSTREAM *bs, IDENTIFIER id, int var, EXP *d, EXP e)
2 7u83 384
{
7 7u83 385
	/* Check for previous definition */
386
	IDENTIFIER lid = DEREF_id(id_alias(id));
387
	DECL_SPEC ds = DEREF_dspec(id_storage(lid));
388
	if (ds & dspec_done) {
389
		return (bs);
390
	}
391
	ds |= dspec_done;
2 7u83 392
 
7 7u83 393
	if (ds & dspec_auto) {
394
		/* Local variable definition */
395
		int dummy = 0;
396
		ulong n = unit_no(bs, id, VAR_tag, 1);
397
		EXP a = DEREF_exp(id_variable_init(id));
398
		EXP b = DEREF_exp(id_variable_term(id));
399
		EXP b1 = NULL_exp;
400
		TYPE t = DEREF_type(id_variable_type(id));
401
		COPY_dspec(id_storage(lid), ds);
402
		if (var) {
403
			if (!IS_NULL_exp(b)) {
404
				if (output_except || var == 4) {
405
					/* Set up terminator variable */
406
					bs = make_term_local(bs, t, &b, var);
407
					b1 = b;
408
					if (IS_NULL_exp(a) && var == 1) {
409
						a = make_dummy_init(t);
410
						dummy = 1;
411
					}
412
				}
413
			}
414
			ENC_variable(bs);
415
		} else {
416
			ENC_identify(bs);
2 7u83 417
		}
7 7u83 418
		bs = enc_access(bs, ds);
419
		ENC_make_tag(bs, n);
420
		if (IS_NULL_exp(a) || var >= 2) {
421
			ENC_make_value(bs);
422
			bs = enc_shape(bs, t);
423
		} else if (var) {
424
			bs = enc_init_local(bs, a, b1, n, t, e);
425
		} else {
426
			if (!IS_NULL_exp(e)) {
427
				BITSTREAM *ts = enc_diag_begin(&bs);
428
				ts = enc_addr_exp(ts, t, a);
429
				bs = enc_diag_end(bs, ts, e, 1);
430
			} else {
431
				bs = enc_addr_exp(bs, t, a);
432
			}
433
		}
434
		if (dummy) {
435
			free_exp(a, 1);
436
		}
437
		if (d)*d = b;
438
	} else if (!(ds & dspec_linkage)) {
439
		/* Static variable definition */
440
		if (IS_id_variable(id)) {
441
			COPY_dspec(id_storage(lid), ds);
442
			bs = enc_static_var(bs, id);
443
		}
2 7u83 444
	}
7 7u83 445
	return (bs);
2 7u83 446
}
447
 
448
 
449
/*
450
    ENCODE A FUNCTION DEFINITION
451
 
452
    This routine encodes the definition of the function id with body e
453
    to the bitstream bs.
454
*/
455
 
7 7u83 456
static BITSTREAM *
457
enc_func_defn(BITSTREAM *bs, IDENTIFIER id, EXP e)
2 7u83 458
{
7 7u83 459
	unsigned n;
460
	unsigned npids;
461
	int is_main = 0;
462
	EXP r = NULL_exp;
463
	unsigned seq = 0;
464
	unsigned rpids = 0;
465
	unsigned epids = 0;
466
	BITSTREAM *ts = NULL;
467
	int diag = output_diag;
468
	LIST(IDENTIFIER)qids;
469
	IDENTIFIER eid = NULL_id;
470
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
471
	TYPE fn = DEREF_type(id_function_etc_type(id));
472
	TYPE ret = DEREF_type(type_func_ret(fn));
473
	int ell = DEREF_int(type_func_ellipsis(fn));
474
	LIST(IDENTIFIER)pids = DEREF_list(type_func_pids(fn));
2 7u83 475
#if LANGUAGE_CPP
7 7u83 476
	EXP post = NULL_exp;
477
	int throws = output_except;
478
	LIST(TYPE)except = DEREF_list(type_func_except(fn));
2 7u83 479
#endif
480
 
7 7u83 481
	/* Check for main routine */
482
	if (ds & dspec_main) {
483
		HASHID nm = DEREF_hashid(id_name(id));
484
		if (IS_hashid_name(nm)) {
485
			ds &= ~dspec_friend;
486
			is_main = 1;
487
			seq++;
488
		}
2 7u83 489
	}
490
 
7 7u83 491
	/* Check exception specifier */
2 7u83 492
#if LANGUAGE_CPP
7 7u83 493
	if (throws) {
494
		if (output_partial) {
495
			post = except_postlude(id);
496
		}
497
		if (IS_NULL_exp(post)) {
498
			if (EQ_list(except, univ_type_set)) {
499
				throws = 0;
500
			} else if (ds & (dspec_friend | dspec_implicit)) {
501
				/* No exception specification required */
502
				throws = 0;
503
			}
504
		} else {
505
			ds |= dspec_mutable;
506
		}
2 7u83 507
	}
508
#endif
509
 
7 7u83 510
	/* Encode start of function */
511
	common_no = 0;
512
	crt_func_access = ds;
513
	clear_params();
514
	ENC_make_proc(bs);
515
	if (pass_complex_type(ret)) {
516
		ENC_top(bs);
517
		rpids = 1;
2 7u83 518
	} else {
7 7u83 519
		if (IS_type_top_etc(ret)) {
520
			last_params[DUMMY_return] = LINK_ZERO;
521
		} else if (is_main) {
522
			MAKE_exp_null(ret, r);
523
		} else {
524
			MAKE_exp_value(ret, r);
525
		}
526
		bs = enc_shape(bs, ret);
2 7u83 527
	}
7 7u83 528
	MAKE_exp_return_stmt(type_bottom, r, r);
2 7u83 529
 
7 7u83 530
	/* Encode 'this' parameter */
531
	if (IS_id_mem_func(id)) {
532
		CLASS_TYPE ct = parent_class(id);
533
		IDENTIFIER pid = this_param(id, 0);
534
		ASSERT(!IS_NULL_id(pid));
535
		CONS_id(pid, pids, pids);
536
		epids = extra_constr_args(id, ct);
537
		last_class = ct;
538
	}
2 7u83 539
 
7 7u83 540
	/* Encode number of parameters */
541
	npids = LENGTH_list(pids);
542
	ENC_LIST(bs, rpids + npids + epids);
543
	qids = pids;
2 7u83 544
 
7 7u83 545
	/* Encode function return parameter */
546
	if (rpids) {
547
		ulong pn = unit_no(bs, NULL_id, VAR_tag, 1);
548
		ENC_pointer(bs);
549
		bs = enc_alignment(bs, ret);
550
		bs = enc_access(bs, ds);
551
		ENC_make_tag(bs, pn);
552
		last_params[DUMMY_return] = pn;
553
	}
2 7u83 554
 
7 7u83 555
	/* Encode normal function parameters */
556
	n = 0;
557
	while (!IS_NULL_list(pids)) {
558
		IDENTIFIER pid = DEREF_id(HEAD_list(pids));
559
		DECL_SPEC pds = DEREF_dspec(id_storage(pid));
560
		TYPE pt = DEREF_type(id_parameter_type(pid));
561
		ulong pn = unit_no(bs, pid, VAR_tag, 1);
562
		if (n < DUMMY_params) {
563
			last_params[n] = pn;
564
			n++;
565
		}
566
		if (pass_complex_type(pt)) {
567
			/* Introduce identity for complex parameters */
568
			ulong pm = unit_no(bs, NULL_id, VAR_tag, 1);
569
			ENC_pointer(bs);
570
			bs = enc_alignment(bs, pt);
571
			if (ts == NULL) {
572
				ts = start_bitstream(NIL(FILE), bs->link);
573
			}
574
			ENC_identify(ts);
575
			ts = enc_access(ts, ds);
576
			ENC_make_tag(ts, pn);
577
			ENC_contents(ts);
578
			ENC_pointer(ts);
579
			ts = enc_alignment(ts, pt);
580
			ENC_obtain_tag(ts);
581
			ENC_make_tag(ts, pm);
582
			pn = pm;
583
		} else if (pds & dspec_virtual) {
584
			/* Introduce variable for weak parameter types */
585
			ulong pm = unit_no(bs, NULL_id, VAR_tag, 1);
586
			TYPE pu = arg_promote_type(pt, KILL_err);
587
			bs = enc_shape(bs, pu);
588
			if (ts == NULL) {
589
				ts = start_bitstream(NIL(FILE), bs->link);
590
			}
591
			ENC_variable(ts);
592
			ts = enc_access(ts, ds);
593
			ENC_make_tag(ts, pn);
594
			if (IS_type_integer(pt)) {
595
				ENC_change_variety(ts);
596
				ts = enc_error_treatment(ts, pt);
597
				ts = enc_variety(ts, pt);
598
			} else {
599
				ENC_change_floating_variety(ts);
600
				ENC_impossible(ts);
601
				ts = enc_flvar(ts, pt);
602
			}
603
			ENC_contents(ts);
604
			ts = enc_shape(ts, pu);
605
			ENC_obtain_tag(ts);
606
			ENC_make_tag(ts, pm);
607
			pn = pm;
608
		} else {
609
			/* Simple parameter */
610
			bs = enc_shape(bs, pt);
611
		}
612
		bs = enc_access(bs, ds);
613
		ENC_make_tag(bs, pn);
614
		pids = TAIL_list(pids);
2 7u83 615
	}
7 7u83 616
 
617
	/* Encode extra function parameters */
618
	while (epids) {
619
		ulong pn = unit_no(bs, NULL_id, VAR_tag, 1);
620
		bs = enc_shape(bs, type_sint);
621
		bs = enc_access(bs, ds);
622
		ENC_make_tag(bs, pn);
623
		last_params[DUMMY_extra] = pn;
624
		epids--;
625
	}
626
 
627
	/* Encode ellipsis parameter */
628
	if (ell & FUNC_ELLIPSIS) {
629
		ulong pn;
630
		eid = ellipsis_param(id);
631
		ASSERT(!IS_NULL_id(eid));
632
		pn = unit_no(bs, eid, VAR_tag, 1);
633
		ENC_ON(bs);
634
		ENC_make_tag(bs, pn);
635
		bs = enc_access(bs, ds);
636
		last_params[DUMMY_ellipsis] = pn;
2 7u83 637
	} else {
7 7u83 638
		ENC_OFF(bs);
2 7u83 639
	}
640
 
7 7u83 641
	/* Allow for reference parameters */
642
	if (ts) {
643
		bs = join_bitstreams(bs, ts);
644
	}
645
	ts = bs;
2 7u83 646
 
7 7u83 647
	/* Encode function body */
648
	seq += stmt_length(e);
649
	if (diag) {
650
		bs = start_bitstream(NIL(FILE), bs->link);
651
	}
2 7u83 652
#if LANGUAGE_CPP
7 7u83 653
	if (throws) {
654
		bs = enc_try_func(bs, post);
655
	}
2 7u83 656
#endif
7 7u83 657
	ENC_SEQUENCE(bs, seq);
658
	if (is_main) {
659
		bs = enc_special(bs, TOK_start);
660
	}
661
	bs = enc_compound_stmt(bs, e);
2 7u83 662
#if LANGUAGE_CPP
7 7u83 663
	if (throws) {
664
		bs = enc_catch_func(bs, except, post);
665
	}
2 7u83 666
#endif
7 7u83 667
	if (diag) {
668
		BITSTREAM *us = enc_diag_begin(&bs);
669
		us = enc_stmt(us, r);
670
		bs = enc_diag_end(bs, us, r, 1);
671
		bs = enc_diag_params(ts, qids, bs, e);
672
	} else {
673
		bs = enc_stmt(bs, r);
674
	}
675
	free_exp(r, 1);
2 7u83 676
 
7 7u83 677
	/* Clear parameter tag numbers */
678
	pids = qids;
679
	while (!IS_NULL_list(pids)) {
680
		IDENTIFIER pid = DEREF_id(HEAD_list(pids));
681
		clear_no(pid);
682
		pids = TAIL_list(pids);
683
	}
684
	if (!IS_NULL_id(eid)) {
685
		clear_no(eid);
686
	}
687
	crt_func_access = dspec_none;
688
	clear_params();
689
	return (bs);
2 7u83 690
}
691
 
692
 
693
/*
694
    ENCODE THE START OF A TAG DECLARATION
695
 
696
    This routine adds the start of a declaration of the tag with identifier
697
    id, capsule number n and type t in the tag declaration unit.  var
698
    is 0 if the tag is an identity, 1 for a variable and 2 for a common tag.
699
    The actual tag type has to be added (t is only used for access checks).
700
*/
701
 
7 7u83 702
BITSTREAM *
703
enc_tagdec_start(IDENTIFIER id, ulong n, TYPE t, int var)
2 7u83 704
{
7 7u83 705
	unsigned use = USAGE_DECL;
706
	BITSTREAM *bs = start_bitstream(NIL(FILE), tagdec_unit->link);
707
	ulong m = link_no(bs, n, VAR_tag);
708
	if (var == 0) {
709
		ENC_make_id_tagdec(bs);
710
	} else if (var == 1) {
711
		ENC_make_var_tagdec(bs);
712
	} else {
713
		ENC_common_tagdec(bs);
714
		use |= USAGE_COMMON;
715
	}
716
	ENC_INT(bs, m);
717
	bs = enc_access(bs, dspec_none);
718
	bs = enc_signature(bs, id);
719
	record_usage(n, VAR_tag, use);
720
	UNUSED(t);
721
	return (bs);
2 7u83 722
}
723
 
724
 
725
/*
726
    ENCODE THE END OF A TAG DECLARATION
727
 
728
    This routine ends the tag declaration started by enc_tagdec_start.
729
*/
730
 
7 7u83 731
void
732
enc_tagdec_end(BITSTREAM *bs)
2 7u83 733
{
7 7u83 734
	count_item(bs);
735
	tagdec_unit = join_bitstreams(tagdec_unit, bs);
736
	return;
2 7u83 737
}
738
 
739
 
740
/*
741
    ENCODE A TAG DECLARATION
742
 
743
    This routine adds a complete tag declaration to the tag declaration
744
    unit if it has not already been declared.
745
*/
746
 
7 7u83 747
void
748
enc_tagdec(IDENTIFIER id, ulong n, TYPE t, int var)
2 7u83 749
{
7 7u83 750
	unsigned u = find_usage(n, VAR_tag);
751
	if (!(u & USAGE_DECL)) {
752
		BITSTREAM *bs = enc_tagdec_start(id, n, t, var);
753
		bs = enc_shape(bs, t);
754
		enc_tagdec_end(bs);
755
	}
756
	return;
2 7u83 757
}
758
 
759
 
760
/*
761
    ENCODE THE START OF A TAG DEFINITION
762
 
763
    This routine adds a definition of the tag with identifier id, capsule
764
    number n and type t to the tag definition unit.  var is as in
765
    enc_tagdec_start.  The routine returns a bitstream to allow the actual
766
    definition to be added.
767
*/
768
 
7 7u83 769
BITSTREAM *
770
enc_tagdef_start(IDENTIFIER id, ulong n, TYPE t, int var)
2 7u83 771
{
7 7u83 772
	unsigned use = USAGE_DEFN;
773
	BITSTREAM *bs = start_bitstream(NIL(FILE), tagdef_unit->link);
774
	ulong m = link_no(bs, n, VAR_tag);
775
	if (var == 0) {
776
		ENC_make_id_tagdef(bs);
777
	} else if (var == 1) {
778
		ENC_make_var_tagdef(bs);
779
	} else {
780
		ENC_common_tagdef(bs);
781
		use |= USAGE_COMMON;
782
	}
783
	ENC_INT(bs, m);
784
	if (var) {
785
		bs = enc_access(bs, dspec_none);
786
	}
787
	bs = enc_signature(bs, id);
788
	record_usage(n, VAR_tag, use);
789
	UNUSED(t);
790
	return (bs);
2 7u83 791
}
792
 
793
 
794
/*
795
    ENCODE THE END OF A TAG DEFINITION
796
 
797
    This routine ends the tag definition started by enc_tagdef_start.
798
*/
799
 
7 7u83 800
void
801
enc_tagdef_end(BITSTREAM *bs)
2 7u83 802
{
7 7u83 803
	count_item(bs);
804
	tagdef_unit = join_bitstreams(tagdef_unit, bs);
805
	return;
2 7u83 806
}
807
 
808
 
809
/*
810
    CREATE A TAG DEFINITION
811
 
812
    This routine creates a tag declaration and definition for the tag
813
    id of type t and definition e.  var is true for a variable tag.
814
    The expression d gives any associated destructor.  id can be the
815
    null identifier, indicating a local tag, and e can be the null
816
    expression, indicating that the tag is only declared.  The routine
817
    returns the external (capsule) tag number.
818
*/
819
 
7 7u83 820
ulong
821
make_tagdef(IDENTIFIER id, TYPE t, EXP e, EXP d, int var)
2 7u83 822
{
7 7u83 823
	ulong n;
824
	int fn = 0;
825
	int def = 1;
826
	LOCATION loc;
2 7u83 827
 
7 7u83 828
	/* Find the tag number */
829
	bad_crt_loc++;
830
	loc = crt_loc;
831
	if (IS_NULL_id(id)) {
832
		n = capsule_no(NULL_string, VAR_tag);
833
	} else {
834
		PTR(LOCATION)ploc = id_loc(id);
835
		DEREF_loc(ploc, crt_loc);
836
		crt_enc_loc = ploc;
837
		IGNORE capsule_id(id, VAR_tag);
838
		n = DEREF_ulong(id_no(id));
839
		if (IS_id_function_etc(id)) {
840
			var = 0;
841
			fn = 1;
842
		}
2 7u83 843
	}
844
 
7 7u83 845
	/* Encode the declaration */
846
	enc_tagdec(id, n, t, var);
2 7u83 847
 
7 7u83 848
	/* Check for definition */
849
	if (!IS_NULL_exp(e)) {
850
		BITSTREAM *bs;
851
		EXP d1 = NULL_exp;
852
		int uc = unreached_code;
853
		if (!IS_NULL_exp(d)) {
854
			if (!output_term) {
855
				/* Set up terminator if necessary */
856
				d1 = d;
857
				d = NULL_exp;
858
				make_term_global(t, &d1);
859
			}
860
			term_no++;
861
		}
862
		bs = enc_tagdef_start(id, n, t, var);
863
		unreached_code = 0;
864
		if (fn) {
865
			/* Function definition */
866
			bs = enc_func_defn(bs, id, e);
867
		} else if (var) {
868
			/* Variable definition */
869
			bs = enc_init_global(bs, e, d1, n, t);
870
		} else {
871
			/* Identity definition */
872
			int i = in_static_init;
873
			in_static_init = 1;
874
			bs = enc_addr_exp(bs, t, e);
875
			in_static_init = i;
876
		}
877
		unreached_code = uc;
878
		enc_tagdef_end(bs);
879
 
880
		/* Check for destructor */
881
		if (!IS_NULL_exp(d)) {
882
			BITSTREAM *ts = term_func;
883
			ts = enc_term_global(ts, n, t, d, LINK_NONE);
884
			term_func = ts;
885
		}
2 7u83 886
	} else {
7 7u83 887
		/* Only declared */
888
		if (!IS_NULL_id(id)) {
889
			string s = NULL;
890
			IGNORE capsule_name(n, &s, VAR_tag);
891
			if (s == NULL) {
892
				if (has_linkage(id)) {
893
					/* Doesn't have external name */
894
					report(crt_loc,
895
					       ERR_basic_odr_undef(id));
896
				}
897
				s = mangle_anon();
898
			}
899
			IGNORE capsule_name(n, &s, VAR_tag);
900
			def = 0;
901
		}
2 7u83 902
	}
7 7u83 903
	if (!IS_NULL_id(id) && output_diag) {
904
		HASHID nm = DEREF_hashid(id_name(id));
905
		if (!IS_hashid_anon(nm)) {
906
			enc_diag_id(id, def);
2 7u83 907
		}
908
	}
7 7u83 909
	crt_loc = loc;
910
	bad_crt_loc--;
911
	return (n);
2 7u83 912
}
913
 
914
 
915
/*
916
    CREATE THE DYNAMIC INITIALISATION FUNCTIONS
917
 
918
    This routine creates the dynamic initialisation and termination
919
    functions.
920
*/
921
 
7 7u83 922
void
923
enc_dynamic_init (void)
2 7u83 924
{
7 7u83 925
	BITSTREAM *bs;
926
	ulong m1 = LINK_NONE;
927
	ulong m2 = LINK_NONE;
928
	ulong init = init_no;
929
	ulong term = term_no;
930
	int diag = output_diag;
931
	if (output_all) {
932
		diag = 1;
933
	}
2 7u83 934
 
7 7u83 935
	/* Create the termination function */
936
	if (term) {
937
		if (output_term) {
938
			/* Define the termination function */
939
			TYPE t = dummy_func;
940
			m1 = capsule_no(NULL_string, VAR_tag);
941
			if (diag) {
942
				enc_diag_init("__term", m1, t);
943
			}
944
			enc_tagdec(NULL_id, m1, t, 0);
945
			bs = enc_tagdef_start(NULL_id, m1, t, 0);
946
			ENC_make_proc(bs);
947
			ENC_top(bs);
948
			ENC_LIST_SMALL(bs, 0);
949
			ENC_OFF(bs);
950
			ENC_SEQUENCE(bs, term);
951
			bs = join_bitstreams(bs, term_static_func);
952
			bs = join_bitstreams(bs, term_func);
953
			ENC_return(bs);
954
			ENC_make_top(bs);
955
			enc_tagdef_end(bs);
2 7u83 956
 
7 7u83 957
			/* Define the termination link */
958
			m2 = capsule_no(NULL_string, VAR_tag);
959
			bs = enc_tagdec_start(NULL_id, m2, NULL_type, 1);
960
			bs = enc_special(bs, TOK_destr_type);
961
			enc_tagdec_end(bs);
962
			bs = enc_tagdef_start(NULL_id, m2, NULL_type, 1);
963
			bs = enc_special(bs, TOK_destr_null);
964
			enc_tagdef_end(bs);
965
			init++;
966
		}
967
		init++;
2 7u83 968
	}
969
 
7 7u83 970
	/* Create the initialisation function */
971
	if (init) {
972
		int var = 1;
973
		TYPE t = type_sint;
974
		TYPE s = t;
975
		string nm = mangle_init();
976
		ulong n1 = capsule_no(nm, VAR_tag);
977
		if (output_init) {
978
			/* Initialisation function required */
979
			t = dummy_func;
980
			var = 0;
981
		}
982
		if (diag) {
983
			enc_diag_init("__init", n1, t);
984
		}
985
		enc_tagdec(NULL_id, n1, t, var);
986
		bs = enc_tagdef_start(NULL_id, n1, t, var);
987
		if (var == 0) {
988
			ENC_make_proc(bs);
989
			bs = enc_shape(bs, s);
990
			ENC_LIST_SMALL(bs, 0);
991
			ENC_OFF(bs);
992
		} else {
993
			ENC_initial_value(bs);
994
		}
995
		ENC_SEQUENCE(bs, init);
996
		if (term) {
997
			/* Initialise termination function */
998
			bs = enc_special(bs, TOK_destr_init);
999
		}
1000
		bs = join_bitstreams(bs, init_func);
1001
		if (m1 != LINK_NONE) {
1002
			/* Set up termination function */
1003
			ulong n;
1004
			BITSTREAM *ts;
1005
			bs = enc_special(bs, TOK_destr_global);
1006
			ts = start_bitstream(NIL(FILE), bs->link);
1007
			n = link_no(ts, m2, VAR_tag);
1008
			ENC_obtain_tag(ts);
1009
			ENC_make_tag(ts, n);
1010
			ENC_make_null_ptr(ts);
1011
			ts = enc_special(ts, TOK_empty_align);
1012
			n = link_no(ts, m1, VAR_tag);
1013
			ENC_obtain_tag(ts);
1014
			ENC_make_tag(ts, n);
1015
			bs = enc_bitstream(bs, ts);
1016
		}
1017
		if (var == 0) {
1018
			ENC_return(bs);
1019
		}
1020
		bs = enc_make_int(bs, s, 1);
1021
		enc_tagdef_end(bs);
2 7u83 1022
 
7 7u83 1023
		/* Set up initialisation variable */
1024
		if (var == 0 && nm == NULL) {
1025
			ulong n2 = capsule_no(NULL_string, VAR_tag);
1026
			if (diag) {
1027
				enc_diag_init("__init2", n2, s);
1028
			}
1029
			enc_tagdec(NULL_id, n2, s, 1);
1030
			bs = enc_tagdef_start(NULL_id, n2, s, 1);
1031
			ENC_initial_value(bs);
1032
			ENC_apply_proc(bs);
1033
			bs = enc_shape(bs, s);
1034
			n1 = link_no(bs, n1, VAR_tag);
1035
			ENC_obtain_tag(bs);
1036
			ENC_make_tag(bs, n1);
1037
			ENC_LIST_SMALL(bs, 0);
1038
			ENC_OFF(bs);
1039
			enc_tagdef_end(bs);
1040
		}
2 7u83 1041
	}
7 7u83 1042
	return;
2 7u83 1043
}
1044
 
1045
 
1046
/*
1047
    CREATE A TOKEN DECLARATION
1048
 
1049
    This routine creates a token declaration body bitstream for a token
1050
    with external (capsule) number n and sort sorts.  This is only output
1051
    for tokens with at least one parameter to aid in pretty-printing.
1052
*/
1053
 
7 7u83 1054
void
1055
enc_tokdec(ulong n, CONST char *sorts)
2 7u83 1056
{
7 7u83 1057
	BITSTREAM *bs = tokdec_unit;
1058
	if (bs) {
1059
		char res = *(sorts++);
1060
		char arg = *sorts;
1061
		if (arg) {
1062
			ulong m = link_no(bs, n, VAR_token);
1063
			record_usage(n, VAR_token, USAGE_DECL);
1064
			ENC_make_tokdec(bs);
1065
			ENC_INT(bs, m);
1066
			bs = enc_signature(bs, NULL_id);
1067
			ENC_token(bs);
1068
#if (TDF_major >= 4)
1069
			/* Result sort first after TDF 4.0 */
1070
			bs = enc_sort(bs,(int)res);
2 7u83 1071
#endif
7 7u83 1072
			ENC_LIST(bs, strlen(sorts));
1073
			while (arg = *(sorts++), arg != 0) {
1074
				bs = enc_sort(bs,(int)arg);
1075
			}
1076
#if (TDF_major < 4)
1077
			/* Result sort last before TDF 4.0 */
1078
			bs = enc_sort(bs,(int)res);
2 7u83 1079
#endif
7 7u83 1080
			count_item(bs);
1081
			tokdec_unit = bs;
1082
		}
2 7u83 1083
	}
7 7u83 1084
	return;
2 7u83 1085
}
1086
 
1087
 
1088
/*
1089
    START A TOKEN DEFINITION
1090
 
1091
    This routine creates a token definition body bitstream for a token
1092
    with external (capsule) number n and sort given by sorts.  This
1093
    includes the allocation of any parameter token numbers, which are
1094
    returned via pars.
1095
*/
1096
 
7 7u83 1097
BITSTREAM *
1098
enc_tokdef_start(ulong n, CONST char *sorts, ulong *pars, int d)
2 7u83 1099
{
7 7u83 1100
	char res;
1101
	unsigned i, m;
1102
	BITSTREAM *bs;
1103
	if (d) {
1104
		enc_tokdec(n, sorts);
1105
	}
1106
	record_usage(n, VAR_token, USAGE_DEFN);
1107
	bs = start_bitstream(NIL(FILE), tokdef_unit->link);
1108
	ENC_token_definition(bs);
1109
	res = *(sorts++);
1110
	bs = enc_sort(bs,(int)res);
1111
	m = (unsigned)strlen(sorts);
1112
	ENC_LIST(bs, m);
1113
	for (i = 0; i < m; i++) {
1114
		/* Encode token parameters */
1115
		char arg = sorts[i];
1116
		ulong r = unit_no(bs, NULL_id, VAR_token, 1);
1117
		bs = enc_sort(bs,(int)arg);
1118
		ENC_INT(bs, r);
1119
		pars[i] = r;
1120
	}
1121
	return (bs);
2 7u83 1122
}
1123
 
1124
 
1125
/*
1126
    COMPLETE A TOKEN DEFINITION
1127
 
1128
    This routine adds the definition of the token with external (capsule)
1129
    number n and token definition body ps to the main token definition unit.
1130
*/
1131
 
7 7u83 1132
void
1133
enc_tokdef_end(ulong n, BITSTREAM *ps)
2 7u83 1134
{
7 7u83 1135
	BITSTREAM *bs = tokdef_unit;
1136
	ulong m = link_no(bs, n, VAR_token);
1137
	ENC_make_tokdef(bs);
1138
	ENC_INT(bs, m);
1139
	bs = enc_signature(bs, NULL_id);
1140
	bs = enc_bitstream(bs, ps);
1141
	count_item(bs);
1142
	tokdef_unit = bs;
1143
	return;
2 7u83 1144
}
1145
 
1146
 
1147
/*
1148
    ENCODE A TOKEN DEFINITION
1149
 
1150
    This routine encodes the declaration and, if necessary, the definition
1151
    of the token id.  If def is true then a dummy definition is output even
1152
    if id is not defined. It returns the code letter of the return sort.
1153
*/
1154
 
7 7u83 1155
int
1156
enc_tokdef(IDENTIFIER id, int def)
2 7u83 1157
{
7 7u83 1158
	int dec;
1159
	ulong n;
1160
	BUFFER *bf;
1161
	unsigned npars = 0;
1162
	IDENTIFIER fid = NULL_id;
1163
	TOKEN tok = DEREF_tok(id_token_sort(id));
1164
	unsigned tag = TAG_tok(tok);
1165
	int r = token_code(tok);
2 7u83 1166
 
7 7u83 1167
	/* Check for declaration and definition */
1168
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
1169
	if (ds & dspec_auto) {
1170
		/* Token parameter */
1171
		LOCATION loc;
1172
		if (ds & dspec_register) {
1173
			return (r);
1174
		}
1175
		DEREF_loc(id_loc(id), loc);
1176
		report(loc, ERR_token_scope(id));
1177
		ds |= dspec_register;
1178
		COPY_dspec(id_storage(id), ds);
1179
		clear_no(id);
1180
	}
1181
	if (ds & dspec_defn) {
1182
		def = 1;
1183
	}
1184
	dec = capsule_id(id, VAR_token);
1185
	if (def) {
1186
		if (ds & dspec_done) {
1187
			return (r);
1188
		}
1189
	} else if (dec) {
1190
		if (tokdec_unit == NULL) {
1191
			return (r);
1192
		}
1193
	} else {
1194
		return (r);
1195
	}
2 7u83 1196
 
7 7u83 1197
	/* Construct token sort */
1198
	bf = clear_buffer(&mangle_buff, NIL(FILE));
1199
	bfputc(bf, r);
1200
	if (tag == tok_func_tag) {
1201
		/* Function token */
1202
		fid = DEREF_id(tok_func_defn(tok));
1203
		tok = func_proc_token(tok);
1204
		tag = TAG_tok(tok);
1205
		if (tag != tok_proc_tag) {
1206
			/* Ellipsis function */
1207
			return (r);
1208
		}
2 7u83 1209
	}
7 7u83 1210
	if (tag == tok_proc_tag) {
1211
		/*  Parameters for procedure tokens */
1212
		LIST(IDENTIFIER)p = DEREF_list(tok_proc_bids(tok));
1213
		while (!IS_NULL_list(p)) {
1214
			IDENTIFIER pid = DEREF_id(HEAD_list(p));
1215
			if (!IS_NULL_id(pid) && IS_id_token(pid)) {
1216
				TOKEN ptok = DEREF_tok(id_token_sort(pid));
1217
				int s = token_code(ptok);
1218
				npars++;
1219
				bfputc(bf, s);
1220
			}
1221
			p = TAIL_list(p);
1222
		}
2 7u83 1223
	}
7 7u83 1224
	bfputc(bf, 0);
2 7u83 1225
 
7 7u83 1226
	/* Output declaration and definition */
1227
	n = DEREF_ulong(id_no(id));
1228
	if (dec) {
1229
		enc_tokdec(n, strlit(bf->start));
1230
	}
1231
	if (def) {
1232
		BITSTREAM *bs;
1233
		ulong std_pars[20];
1234
		ulong *pars = std_pars;
1235
		if (npars >= 20) {
1236
			pars = xmalloc_nof(ulong, npars);
2 7u83 1237
		}
7 7u83 1238
		bs = enc_tokdef_start(n, strlit(bf->start), pars, 0);
1239
		COPY_dspec(id_storage(id), (ds | dspec_done));
1240
		COPY_ulong(id_no(id), LINK_TOKDEF);
1241
		last_params[DUMMY_token] = n;
1242
		if (tag == tok_proc_tag) {
1243
			unsigned i = 0;
1244
			if (IS_NULL_id(fid)) {
1245
				/* Procedure tokens */
1246
				LIST(IDENTIFIER)p, q;
1247
				p = DEREF_list(tok_proc_bids(tok));
1248
				q = p;
1249
				while (!IS_NULL_list(q)) {
1250
					IDENTIFIER pid = DEREF_id(HEAD_list(q));
1251
					if (!IS_NULL_id(pid) && IS_id_token(pid)) {
1252
						DECL_SPEC pds = DEREF_dspec(id_storage(pid));
1253
						pds |= dspec_register;
1254
						COPY_dspec(id_storage(pid), pds);
1255
						COPY_ulong(id_no(pid), pars[i]);
1256
						i++;
1257
					}
1258
					q = TAIL_list(q);
1259
				}
1260
				bs = enc_tokdef_body(bs, id, tok);
1261
				set_proc_token(p);
1262
			} else {
1263
				/* Function tokens */
1264
				ulong m;
1265
				TOKEN res = DEREF_tok(tok_proc_res(tok));
1266
				TYPE ret = DEREF_type(tok_exp_type(res));
1267
				ENC_apply_proc(bs);
1268
				bs = enc_shape(bs, ret);
1269
				IGNORE capsule_id(fid, VAR_tag);
1270
				m = unit_no(bs, fid, VAR_tag, 1);
1271
				ENC_obtain_tag(bs);
1272
				ENC_make_tag(bs, m);
1273
				ENC_LIST(bs, npars);
1274
				while (i < npars) {
1275
					ENC_exp_apply_token(bs);
1276
					ENC_make_tok(bs, pars[i]);
1277
					ENC_LEN_SMALL(bs, 0);
1278
					i++;
1279
				}
1280
				ENC_OFF(bs);
1281
			}
1282
		} else {
1283
			/* Other tokens */
1284
			bs = enc_tokdef_body(bs, id, tok);
2 7u83 1285
		}
7 7u83 1286
		COPY_ulong(id_no(id), n);
1287
		enc_tokdef_end(n, bs);
1288
		if (pars != std_pars) {
1289
			xfree_nof(pars);
1290
		}
2 7u83 1291
	}
7 7u83 1292
	return (r);
2 7u83 1293
}
1294
 
1295
 
1296
/*
1297
    SHOULD A VARIABLE BE COMPILED?
1298
 
1299
    This routine determines whether a variable declared with specifiers
1300
    ds and type t should be output.  It returns 1 if it should be output
1301
    immediately, 2 if the decision on whether to output should be deferred
1302
    until later, and 0 otherwise.
1303
*/
1304
 
7 7u83 1305
static int
1306
need_variable(DECL_SPEC ds, TYPE t, EXP e, ulong n)
2 7u83 1307
{
7 7u83 1308
	if (ds & dspec_temp) {
1309
		/* Temporary variables */
1310
		if (ds & dspec_ignore) {
1311
			return (0);
1312
		}
1313
		if (ds & dspec_explicit) {
1314
			return (2);
1315
		}
1316
	}
1317
	if (ds & dspec_defn) {
1318
		/* Output defined variables */
1319
		if (ds & dspec_extern) {
1320
			return (1);
1321
		}
1322
		if (n == LINK_NONE) {
2 7u83 1323
#if LANGUAGE_CPP
7 7u83 1324
			CV_SPEC qual = DEREF_cv(type_qual(t));
1325
			if (qual == (cv_lvalue | cv_const)) {
1326
				/* Defer literal constants */
1327
				return (2);
1328
			}
2 7u83 1329
#else
7 7u83 1330
			UNUSED(t);
2 7u83 1331
#endif
7 7u83 1332
			if (!output_unused) {
1333
				return (2);
1334
			}
1335
			if (!overflow_exp(e)) {
1336
				return (2);
1337
			}
1338
		}
1339
		return (1);
2 7u83 1340
	}
7 7u83 1341
	if (ds & dspec_used) {
1342
		/* Defer used variables */
1343
		return (2);
1344
	}
1345
	return (0);
2 7u83 1346
}
1347
 
1348
 
1349
/*
1350
    COMPILE A VARIABLE
1351
 
1352
    This routine compiles the global variable or static data member id.
1353
*/
1354
 
7 7u83 1355
void
1356
compile_variable(IDENTIFIER id, int force)
2 7u83 1357
{
7 7u83 1358
	if (output_capsule) {
1359
		IDENTIFIER lid = DEREF_id(id_alias(id));
1360
		DECL_SPEC ds = DEREF_dspec(id_storage(lid));
1361
		if (!(ds & dspec_done)) {
1362
			TYPE t;
1363
			EXP e, d;
1364
			int output;
1365
			switch (TAG_id(id)) {
1366
			case id_variable_tag:
1367
			case id_stat_member_tag: {
1368
				/* Variables and static data members */
1369
				t = DEREF_type(id_variable_etc_type(lid));
1370
				e = DEREF_exp(id_variable_etc_init(lid));
1371
				d = DEREF_exp(id_variable_etc_term(lid));
1372
				if (!IS_NULL_exp(e) && IS_exp_zero(e)) {
1373
					/* Ignore tentative definitions */
1374
					ds &= ~dspec_defn;
1375
				}
1376
				break;
1377
			}
1378
			case id_enumerator_tag: {
1379
				/* Dummy enumerator values */
1380
				if (!output_unused) {
1381
					return;
1382
				}
1383
				e = DEREF_exp(id_enumerator_value(lid));
1384
				e = eval_exp(e, 1);
1385
				if (!overflow_exp(e)) {
1386
					return;
1387
				}
1388
				t = DEREF_type(exp_type(e));
1389
				d = NULL_exp;
1390
				force = 1;
1391
				break;
1392
			}
1393
			default: {
1394
				/* Shouldn't happen */
1395
				return;
1396
			}
1397
			}
1398
			if (!IS_NULL_exp(d) && IS_exp_paren(d)) {
1399
				/* Ignore parenthesised type information */
1400
				d = DEREF_exp(exp_paren_arg(d));
1401
			}
1402
			if (!(ds & dspec_defn)) {
1403
				/* Object not defined */
1404
				e = NULL_exp;
1405
				d = NULL_exp;
1406
			}
1407
			if (ds & dspec_explicit) {
1408
				/* Explicitly initialised object */
1409
				d = NULL_exp;
1410
			}
1411
			if (force) {
1412
				/* Force output */
1413
				output = 1;
1414
			} else if (!IS_NULL_exp(e) && IS_exp_dynamic(e)) {
1415
				/* Dynamic initialiser */
1416
				output = 1;
1417
			} else if (!IS_NULL_exp(d)) {
1418
				/* Dynamic destructor */
1419
				output = 1;
1420
			} else {
1421
				/* Determine whether to output */
1422
				ulong n = DEREF_ulong(id_no(lid));
1423
				output = need_variable(ds, t, e, n);
1424
				if (output == 2) {
1425
					/* Defer variable until later */
1426
					CONS_id(lid, pending_funcs, pending_funcs);
1427
					output = 0;
1428
				}
1429
			}
1430
			if (output) {
1431
				/* Output variable definition */
1432
				ds |= dspec_done;
1433
				COPY_dspec(id_storage(lid), ds);
1434
				crt_enc_loc = id_loc(lid);
1435
				IGNORE make_tagdef(lid, t, e, d, 1);
1436
				crt_enc_loc = NULL_ptr(LOCATION);
1437
			}
1438
		} else {
1439
			/* Check for anonymous unions */
1440
			if (!EQ_id(id, lid)) {
1441
				if (output_diag && is_anon_member(id)) {
1442
					enc_diag_id(id, 1);
1443
				}
1444
			}
2 7u83 1445
		}
1446
	} else {
7 7u83 1447
		check_mangled(id);
2 7u83 1448
	}
7 7u83 1449
	return;
2 7u83 1450
}
1451
 
1452
 
1453
/*
1454
    COMPILE ALL PENDING FUNCTIONS
1455
 
1456
    This routine compiles all the inline and implicit functions which
1457
    have been used in the program.  The usage information comes from
1458
    the fact that the function tag has actually been output rather than
1459
    the function has been used (possibly in a function which is not
1460
    itself used).
1461
*/
1462
 
7 7u83 1463
void
1464
compile_pending(void)
2 7u83 1465
{
7 7u83 1466
	int changed;
1467
	do {
1468
		LIST(IDENTIFIER)p = pending_funcs;
1469
		if (!output_capsule)break;
1470
		changed = 0;
1471
		while (!IS_NULL_list(p)) {
1472
			IDENTIFIER id = DEREF_id(HEAD_list(p));
1473
			if (!IS_NULL_id(id)) {
1474
				ulong n = DEREF_ulong(id_no(id));
1475
				if (n != LINK_NONE) {
1476
					DECL_SPEC ds = DEREF_dspec(id_storage(id));
1477
					if (!(ds & dspec_done)) {
1478
						if (IS_id_function_etc(id)) {
1479
							if (ds & dspec_trivial) {
1480
								/* It can happen ... */
1481
								ds &= ~(dspec_defn | dspec_trivial);
1482
								COPY_dspec(id_storage(id), ds);
1483
							}
1484
							if (!(ds & dspec_defn)) {
1485
								/* Function not defined */
1486
								if (ds & dspec_implicit) {
1487
									/* Compile implicit functions */
1488
									LOCATION loc;
1489
									bad_crt_loc++;
1490
									loc = crt_loc;
1491
									DEREF_loc(id_loc(id), crt_loc);
1492
									implicit_defn(id, DEFAULT_USR);
1493
									crt_loc = loc;
1494
									bad_crt_loc--;
1495
								} else if (ds & dspec_extern) {
1496
									/* External linkage */
1497
									update_tag(id, 1);
1498
								}
1499
							}
1500
							compile_function(id, 1);
1501
						} else {
1502
							compile_variable(id, 1);
1503
						}
1504
						changed = 1;
1505
					}
1506
					COPY_id(HEAD_list(p), NULL_id);
2 7u83 1507
				}
1508
			}
7 7u83 1509
			p = TAIL_list(p);
2 7u83 1510
		}
7 7u83 1511
		if (!changed)changed = enc_diag_pending();
1512
	} while (changed);
1513
	compile_incompl();
1514
	return;
2 7u83 1515
}
1516
 
1517
 
1518
/*
1519
    SHOULD A FUNCTION BE COMPILED?
1520
 
1521
    This routine determines whether a function declared with specifiers
1522
    ds should be output.  It returns 1 if it should be output immediately,
1523
    2 if the decision on whether to output should be deferred until later,
1524
    and 0 otherwise.  The algorithm is somewhat complex to avoid outputting
1525
    inline and implicit function definitions unless absolutely necessary
1526
    and to only declare virtual functions when explicitly called or when
1527
    defining a virtual function table.
1528
*/
1529
 
7 7u83 1530
static int
1531
need_function(DECL_SPEC ds, ulong n)
2 7u83 1532
{
7 7u83 1533
	if (ds & (dspec_inline | dspec_implicit | dspec_token)) {
1534
		/* Defer inline functions */
1535
		if ((ds & dspec_defn) && n != LINK_NONE) {
1536
			return (1);
1537
		}
1538
		return (2);
1539
	}
1540
	if (ds & dspec_defn) {
1541
		/* Output defined functions */
1542
		if ((ds & dspec_extern) || output_unused) {
1543
			return (1);
1544
		}
1545
		if (n != LINK_NONE) {
1546
			return (1);
1547
		}
1548
		return (2);
1549
	}
1550
	if (ds & (dspec_used | dspec_called | dspec_virtual)) {
1551
		/* Defer called functions */
1552
		return (2);
1553
	}
1554
	return (0);
2 7u83 1555
}
1556
 
1557
 
1558
/*
1559
    COMPILE A FUNCTION
1560
 
1561
    This routine compiles the function or member function id.  If force
1562
    is true then the definition of id is always output.
1563
*/
1564
 
7 7u83 1565
void
1566
compile_function(IDENTIFIER id, int force)
2 7u83 1567
{
7 7u83 1568
	/* Check for template functions */
1569
	TYPE t;
1570
	IDENTIFIER lid = DEREF_id(id_alias(id));
1571
	if (IS_id_ambig(lid)) {
1572
		return;
1573
	}
1574
	t = DEREF_type(id_function_etc_type(lid));
1575
	if (IS_type_templ(t)) {
1576
		return;
1577
	}
2 7u83 1578
 
7 7u83 1579
	/* Simple functions */
1580
	if (output_capsule) {
1581
		DECL_SPEC ds = DEREF_dspec(id_storage(lid));
1582
		if (!(ds & (dspec_done | dspec_trivial))) {
1583
			int output;
1584
			if (force) {
1585
				/* Force output */
1586
				output = 1;
1587
			} else {
1588
				/* Determine whether to output */
1589
				ulong n = DEREF_ulong(id_no(lid));
1590
				output = need_function(ds, n);
1591
				if (output == 2) {
1592
					/* Defer function until later */
1593
					CONS_id(lid, pending_funcs, pending_funcs);
1594
					output = 0;
1595
				}
1596
			}
1597
			if (output == 1) {
1598
				/* Output function definition */
1599
				EXP e = DEREF_exp(id_function_etc_defn(lid));
1600
				if (!(ds & dspec_defn)) {
1601
					e = NULL_exp;
1602
				}
1603
				ds |= dspec_done;
1604
				COPY_dspec(id_storage(lid), ds);
1605
				crt_enc_loc = id_loc(lid);
1606
				IGNORE make_tagdef(lid, t, e, NULL_exp, 0);
1607
				crt_enc_loc = NULL_ptr(LOCATION);
1608
				free_function(lid);
1609
			}
2 7u83 1610
		}
7 7u83 1611
	} else {
1612
		free_function(lid);
1613
		check_mangled(lid);
2 7u83 1614
	}
7 7u83 1615
	return;
2 7u83 1616
}
1617
 
1618
 
1619
/*
1620
    VIRTUAL FUNCTION DECLARATION CHECK
1621
 
1622
    This value gives those virtual functions which are ignored when
1623
    deciding whether to output a virtual function table.
1624
*/
1625
 
1626
#define dspec_ignore_virtual\
7 7u83 1627
   (dspec_inherit | dspec_implicit | dspec_inline | dspec_pure)
2 7u83 1628
 
1629
 
1630
/*
1631
    COMPILE A VIRTUAL FUNCTION TABLE
1632
 
1633
    This routine compiles the virtual function table associated with
1634
    the polymorphic class type ct.  anon is as in check_identifier.
1635
    The criterion used to limit duplicate copies is putting the virtual
1636
    function table definition in the same file as the definition of the
1637
    first (in the sense of first in the virtual function table, rather
1638
    than in the class definition) non-inline virtual function declared
1639
    in the class.
1640
*/
1641
 
1642
#if LANGUAGE_CPP
1643
 
7 7u83 1644
void
1645
compile_virtual(CLASS_TYPE ct, int anon)
2 7u83 1646
{
7 7u83 1647
	if (output_capsule) {
1648
		IDENTIFIER cid = DEREF_id(ctype_name(ct));
1649
		crt_enc_loc = id_loc(cid);
1650
		if (anon == ANON_NONE && !output_virtual) {
1651
			LIST(VIRTUAL)pt;
1652
			VIRTUAL vt = DEREF_virt(ctype_virt(ct));
1653
			if (IS_NULL_virt(vt)) {
1654
				return;
2 7u83 1655
			}
7 7u83 1656
			pt = DEREF_list(virt_table_entries(vt));
1657
			while (!IS_NULL_list(pt)) {
1658
				VIRTUAL at = DEREF_virt(HEAD_list(pt));
1659
				unsigned tag = TAG_virt(at);
1660
				while (tag == virt_link_tag) {
1661
					/* Allow for symbolic links */
1662
					at = DEREF_virt(DEREF_ptr(virt_link_to(at)));
1663
					tag = TAG_virt(at);
1664
				}
1665
				if (tag == virt_simple_tag || tag == virt_override_tag) {
1666
					/* Examine virtual functions */
1667
					IDENTIFIER fn = DEREF_id(virt_func(at));
1668
					DECL_SPEC ds = DEREF_dspec(id_storage(fn));
1669
					if (!(ds & dspec_ignore_virtual)) {
1670
						if (ds & dspec_defn) {
1671
							/* Define the table externally */
1672
							define_vtable(ct, 2, 1);
1673
						} else {
1674
							/* Declare the table externally */
1675
							define_vtable(ct, 0, 1);
1676
						}
1677
						return;
1678
					}
1679
				}
1680
				pt = TAIL_list(pt);
1681
			}
2 7u83 1682
		}
7 7u83 1683
		/* Define the table internally */
1684
		define_vtable(ct, 1, 0);
2 7u83 1685
	}
7 7u83 1686
	return;
2 7u83 1687
}
1688
 
1689
#endif
1690
 
1691
 
1692
/*
1693
    COMPILE A TOKEN
1694
 
1695
    This routine compiles the token id.  It is only called if id is defined
1696
    (in which case def is true) or should be defined.
1697
*/
1698
 
7 7u83 1699
void
1700
compile_token(IDENTIFIER id, int def)
2 7u83 1701
{
7 7u83 1702
	if (!def) {
1703
		report(crt_loc, ERR_token_undef(id));
1704
	}
1705
	if (output_capsule) {
1706
		crt_enc_loc = id_loc(id);
1707
		IGNORE enc_tokdef(id, 1);
1708
		if (output_diag) {
1709
			enc_diag_token(id, NULL_type);
1710
		}
1711
		crt_enc_loc = NULL_ptr(LOCATION);
1712
	}
1713
	return;
2 7u83 1714
}
1715
 
1716
 
1717
/*
1718
    COMPILE A TYPE
1719
 
1720
    This routine compiles the type named id.  This only has an effect in
1721
    diagnostics mode.
1722
*/
1723
 
7 7u83 1724
void
1725
compile_type(IDENTIFIER id)
2 7u83 1726
{
7 7u83 1727
	if (output_capsule && output_diag) {
1728
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
1729
		if ((ds & dspec_used) && !(ds & dspec_done)) {
1730
			ds |= dspec_done;
1731
			COPY_dspec(id_storage(id), ds);
1732
			if (ds & dspec_token) {
1733
				/* Tokenised type */
1734
				/* EMPTY */
1735
			} else {
1736
				crt_enc_loc = id_loc(id);
1737
				enc_diag_id(id, 0);
1738
				crt_enc_loc = NULL_ptr(LOCATION);
1739
			}
1740
		}
2 7u83 1741
	}
7 7u83 1742
	return;
2 7u83 1743
}
1744
 
1745
 
1746
/*
1747
    COMPILE AN EXTERNAL ASSEMBLER DIRECTIVE
1748
 
1749
    This routine compiles the asm definition e which is declared outside
1750
    any function definition.
1751
*/
1752
 
7 7u83 1753
void
1754
compile_asm(EXP e)
2 7u83 1755
{
7 7u83 1756
	TYPE t = DEREF_type(exp_type(e));
1757
	IGNORE make_tagdef(NULL_id, t, e, NULL_exp, 1);
1758
	return;
2 7u83 1759
}
1760
 
1761
 
1762
/*
1763
    COMPILE A COMMENT
1764
 
1765
    This routine adds the comment string s of length n to the output
1766
    capsule.  This is used in the implementation of the '#ident' directive.
1767
*/
1768
 
7 7u83 1769
void
1770
compile_comment(string s, unsigned long n)
2 7u83 1771
{
7 7u83 1772
	if (output_capsule) {
1773
		BITSTREAM *bs = linkinfo_unit;
1774
		ENC_make_comment(bs);
1775
		bs = enc_tdfstring(bs, n, s);
1776
		count_item(bs);
1777
		linkinfo_unit = bs;
1778
	}
1779
	return;
2 7u83 1780
}
1781
 
1782
 
1783
/*
1784
    COMPILE A PRESERVED STATIC IDENTIFIER
1785
 
1786
    This routine adds the preserved static identifier id to the output
1787
    capsule.
1788
*/
1789
 
7 7u83 1790
void
1791
compile_preserve(IDENTIFIER id)
2 7u83 1792
{
7 7u83 1793
	if (output_capsule) {
1794
		ulong n;
1795
		BITSTREAM *bs = linkinfo_unit;
1796
		ENC_static_name_def(bs);
1797
		ENC_obtain_tag(bs);
1798
		IGNORE capsule_id(id, VAR_tag);
1799
		n = unit_no(bs, id, VAR_tag, 1);
1800
		ENC_make_tag(bs, n);
1801
		bs = enc_diag_name(bs, id, 1);
1802
		count_item(bs);
1803
		linkinfo_unit = bs;
1804
	}
1805
	return;
2 7u83 1806
}
1807
 
1808
 
1809
/*
1810
    COMPILE A WEAK LINKAGE DIRECTIVE
1811
 
1812
    This routine adds a weak linkage directive '#pragma weak id = aid'
1813
    to the output capsule.
1814
*/
1815
 
7 7u83 1816
void
1817
compile_weak(IDENTIFIER id, IDENTIFIER aid)
2 7u83 1818
{
7 7u83 1819
	if (output_capsule && !IS_NULL_id(id)) {
1820
		ulong n;
1821
		string s = NULL;
1822
		BITSTREAM *bs = linkinfo_unit;
2 7u83 1823
 
7 7u83 1824
		/* Set up weak symbol name */
1825
		id = DEREF_id(id_alias(id));
1826
		IGNORE capsule_id(id, VAR_tag);
1827
		n = DEREF_ulong(id_no(id));
1828
		IGNORE capsule_name(n, &s, VAR_tag);
1829
		if (s) {
1830
			ENC_make_weak_symbol(bs);
1831
			bs = enc_ustring(bs, s);
1832
			ENC_obtain_tag(bs);
1833
			n = unit_no(bs, id, VAR_tag, 1);
1834
			ENC_make_tag(bs, n);
1835
			count_item(bs);
1836
		}
2 7u83 1837
 
7 7u83 1838
		/* Set up weak symbol definition */
1839
		if (!IS_NULL_id(aid)) {
1840
			aid = DEREF_id(id_alias(aid));
1841
			ENC_make_weak_defn(bs);
1842
			ENC_obtain_tag(bs);
1843
			n = unit_no(bs, id, VAR_tag, 1);
1844
			ENC_make_tag(bs, n);
1845
			ENC_obtain_tag(bs);
1846
			IGNORE capsule_id(aid, VAR_tag);
1847
			n = unit_no(bs, aid, VAR_tag, 1);
1848
			ENC_make_tag(bs, n);
1849
			count_item(bs);
1850
		}
1851
		linkinfo_unit = bs;
2 7u83 1852
	}
7 7u83 1853
	return;
2 7u83 1854
}
1855
 
1856
 
1857
/*
1858
    UPDATE A TAG NAME
1859
 
1860
    This routine updates the external name of the identifier id forcing
1861
    it to become internal or external, depending on the value of ext.  It
1862
    is used to handle inline functions with external linkage.
1863
*/
1864
 
7 7u83 1865
void
1866
update_tag(IDENTIFIER id, int ext)
2 7u83 1867
{
7 7u83 1868
	IDENTIFIER lid = DEREF_id(id_alias(id));
1869
	ulong n = DEREF_ulong(id_no(lid));
1870
	if (n != LINK_NONE && (n & LINK_EXTERN)) {
1871
		string s = mangle_name(lid, VAR_tag, ext);
1872
		n = capsule_name(n, &s, VAR_tag);
1873
		COPY_ulong(id_no(lid), n);
1874
		COPY_ulong(id_no(id), n);
1875
	}
1876
	return;
2 7u83 1877
}
1878
 
1879
 
1880
/*
1881
    START OF DUMMY TDF OUTPUT ROUTINES
1882
 
1883
    The following routines are dummies which are used if TDF output is
1884
    disabled.  The output is still a valid TDF capsule, it just contains
1885
    no information.
1886
*/
1887
 
1888
#else /* TDF_OUTPUT */
1889
 
1890
 
1891
/*
1892
    COMPILE A VARIABLE (DUMMY VERSION)
1893
 
1894
    This routine is a dummy for compiling the variable id when TDF
1895
    output is disabled.
1896
*/
1897
 
7 7u83 1898
void
1899
compile_variable(IDENTIFIER id, int force)
2 7u83 1900
{
7 7u83 1901
	check_mangled(id);
1902
	UNUSED(force);
1903
	return;
2 7u83 1904
}
1905
 
1906
 
1907
/*
1908
    COMPILE ALL PENDING FUNCTIONS (DUMMY VERSION)
1909
 
1910
    This routine is a dummy for compiling all pending functions when
1911
    TDF output is disabled.
1912
*/
1913
 
7 7u83 1914
void
1915
compile_pending(void)
2 7u83 1916
{
7 7u83 1917
	return;
2 7u83 1918
}
1919
 
1920
 
1921
/*
1922
    COMPILE A FUNCTION (DUMMY VERSION)
1923
 
1924
    This routine is a dummy for compiling the function id when TDF
1925
    output is disabled.
1926
*/
1927
 
7 7u83 1928
void
1929
compile_function(IDENTIFIER id, int force)
2 7u83 1930
{
7 7u83 1931
	TYPE t = DEREF_type(id_function_etc_type(t));
1932
	if (IS_type_func(t)) {
1933
		free_function(id);
1934
	}
1935
	check_mangled(id);
1936
	UNUSED(force);
1937
	return;
2 7u83 1938
}
1939
 
1940
 
1941
/*
1942
    COMPILE A VIRTUAL FUNCTION TABLE (DUMMY VERSION)
1943
 
1944
    This routine is a dummy for compiling the virtual function table
1945
    associated with the polymorphic class type ct when TDF output is
1946
    disabled.
1947
*/
1948
 
1949
#if LANGUAGE_CPP
1950
 
7 7u83 1951
void
1952
compile_virtual(CLASS_TYPE ct, int anon)
2 7u83 1953
{
7 7u83 1954
	UNUSED(ct);
1955
	UNUSED(anon);
1956
	return;
2 7u83 1957
}
1958
 
1959
#endif
1960
 
1961
 
1962
/*
1963
    COMPILE A TOKEN (DUMMY VERSION)
1964
 
1965
    This routine is a dummy for compiling the token id when TDF output
1966
    is disabled.
1967
*/
1968
 
7 7u83 1969
void
1970
compile_token(IDENTIFIER id, int def)
2 7u83 1971
{
7 7u83 1972
	if (!def) {
1973
		report(crt_loc, ERR_token_undef(id));
1974
	}
1975
	return;
2 7u83 1976
}
1977
 
1978
 
1979
/*
1980
    COMPILE A TYPE (DUMMY VERSION)
1981
 
1982
    This routine is a dummy for compiling the type named id when TDF
1983
    output is disabled.
1984
*/
1985
 
7 7u83 1986
void
1987
compile_type(IDENTIFIER id)
2 7u83 1988
{
7 7u83 1989
	UNUSED(id);
1990
	return;
2 7u83 1991
}
1992
 
1993
 
1994
/*
1995
    COMPILE AN EXTERNAL ASSEMBLER DIRECTIVE (DUMMY VERSION)
1996
 
1997
    This routine is a dummy for compiling the asm definition e which is
1998
    declared outside any function definition.
1999
*/
2000
 
7 7u83 2001
void
2002
compile_asm(EXP e)
2 7u83 2003
{
7 7u83 2004
	UNUSED(e);
2005
	return;
2 7u83 2006
}
2007
 
2008
 
2009
/*
2010
    COMPILE A COMMENT (DUMMY VERSION)
2011
 
2012
    This routine is a dummy for compiling the comment given by s and n
2013
    when TDF output is disabled.
2014
*/
2015
 
7 7u83 2016
void
2017
compile_comment(string s, unsigned long n)
2 7u83 2018
{
7 7u83 2019
	UNUSED(s);
2020
	UNUSED(n);
2021
	return;
2 7u83 2022
}
2023
 
2024
 
2025
/*
2026
    COMPILE A PRESERVED STATIC IDENTIFIER (DUMMY VERSION)
2027
 
2028
    This routine is a dummy for compiling the preserved static identifier
2029
    id when TDF output is disabled.
2030
*/
2031
 
7 7u83 2032
void
2033
compile_preserve(IDENTIFIER id)
2 7u83 2034
{
7 7u83 2035
	UNUSED(id);
2036
	return;
2 7u83 2037
}
2038
 
2039
 
2040
/*
2041
    COMPILE A WEAK LINKAGE DIRECTIVE (DUMMY VERSION)
2042
 
2043
    This routine is a dummy for compiling the weak linkage directive
2044
    '#pragma weak id = aid' when TDF output is disabled.
2045
*/
2046
 
7 7u83 2047
void
2048
compile_weak(IDENTIFIER id, IDENTIFIER aid)
2 7u83 2049
{
7 7u83 2050
	UNUSED(id);
2051
	UNUSED(aid);
2052
	return;
2 7u83 2053
}
2054
 
2055
 
2056
/*
2057
    UPDATE A TAG NAME (DUMMY VERSION)
2058
 
2059
    This routine is a dummy for updating the external name of the
2060
    identifier id when TDF output is disabled.
2061
*/
2062
 
7 7u83 2063
void
2064
update_tag(IDENTIFIER id, int ext)
2 7u83 2065
{
7 7u83 2066
	UNUSED(id);
2067
	UNUSED(ext);
2068
	return;
2 7u83 2069
}
2070
 
2071
 
2072
#endif /* TDF_OUTPUT */