Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
6 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
6 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:-
6 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
6 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;
6 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;
6 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 "system.h"
64
#include "c_types.h"
65
#include "ctype_ops.h"
66
#include "etype_ops.h"
67
#include "exp_ops.h"
68
#include "graph_ops.h"
69
#include "hashid_ops.h"
70
#include "id_ops.h"
71
#include "itype_ops.h"
72
#include "member_ops.h"
73
#include "nat_ops.h"
74
#include "nspace_ops.h"
75
#include "tok_ops.h"
76
#include "type_ops.h"
77
#include "virt_ops.h"
78
#include "error.h"
79
#include "tdf.h"
80
#include "basetype.h"
81
#include "buffer.h"
82
#include "capsule.h"
83
#include "compile.h"
84
#include "constant.h"
85
#include "diag.h"
86
#include "diag2.h"
87
#include "encode.h"
88
#include "exp.h"
89
#include "expression.h"
90
#include "function.h"
91
#include "initialise.h"
92
#include "mangle.h"
93
#include "print.h"
94
#include "shape.h"
95
#include "stmt.h"
96
#include "struct.h"
97
#include "tok.h"
98
#include "ustring.h"
99
#if TDF_OUTPUT
100
 
101
 
102
/*
103
    STANDARD DIAGNOSTIC TOKENS
104
 
105
    These variables give the standard tokens used in the diagnostic
106
    output.
107
*/
108
 
6 7u83 109
static ulong diag_id_scope_tok = LINK_NONE;
110
static ulong exp_to_source_tok = LINK_NONE;
2 7u83 111
 
112
 
113
/*
114
    ENCODE A DIAGNOSTIC FILE NAME
115
 
116
    This routine adds the diagnostic file name given by posn to the
117
    bitstream bs.
118
*/
119
 
6 7u83 120
static BITSTREAM *
121
enc_diag_file(BITSTREAM *bs, PTR(POSITION)posn)
2 7u83 122
{
6 7u83 123
	ulong n = DEREF_ulong(posn_tok(posn));
124
	if (n == LINK_NONE) {
125
		BITSTREAM *ts;
126
		string bn = DEREF_string(posn_base(posn));
127
		string mn = ustrlit(find_machine());
128
		ulong date = DEREF_ulong(posn_datestamp(posn));
129
		n = capsule_no(NULL_string, VAR_token);
130
		COPY_ulong(posn_tok(posn), n);
131
		if (!output_date) {
132
			date = 0;
133
		}
134
		ts = enc_tokdef_start(n, "P", NIL(ulong), 0);
135
		ENC_make_filename(ts);
136
		ENC_make_nat(ts);
137
		ENC_INT(ts, date);
138
		ts = enc_ustring(ts, mn);
139
		ts = enc_ustring(ts, bn);
140
		enc_tokdef_end(n, ts);
141
	}
2 7u83 142
 
6 7u83 143
	/* Encode token application */
144
	ENC_filename_apply_token(bs);
145
	n = link_no(bs, n, VAR_token);
146
	ENC_make_tok(bs, n);
147
	ENC_LEN_SMALL(bs, 0);
148
	return (bs);
2 7u83 149
}
150
 
151
 
152
/*
153
    ENCODE A DIAGNOSTIC SOURCE MARK
154
 
155
    This routine adds the diagnostic source mark given by loc to the
156
    bitstream bs.
157
*/
158
 
6 7u83 159
static BITSTREAM *
160
enc_diag_loc(BITSTREAM *bs, PTR(LOCATION)loc)
2 7u83 161
{
6 7u83 162
	ulong ln, cn;
163
	PTR(POSITION)posn;
164
	if (IS_NULL_ptr(loc)) {
165
		ln = builtin_loc.line;
166
		cn = builtin_loc.line;
167
		posn = builtin_loc.posn;
168
	} else {
169
		ln = DEREF_ulong(loc_line(loc));
170
		cn = DEREF_ulong(loc_column(loc));
171
		posn = DEREF_ptr(loc_posn(loc));
172
	}
173
	ENC_make_sourcemark(bs);
174
	bs = enc_diag_file(bs, posn);
175
	ENC_make_nat(bs);
176
	ENC_INT(bs, ln);
177
	ENC_make_nat(bs);
178
	ENC_INT(bs, cn);
179
	return (bs);
2 7u83 180
}
181
 
182
 
183
/*
184
    ENCODE A DIAGNOSTIC IDENTIFIER NAME
185
 
186
    This routine adds the name of the identifier id to the bitstream bs
187
    as a TDF string.
188
*/
189
 
6 7u83 190
BITSTREAM *
191
enc_diag_name(BITSTREAM *bs, IDENTIFIER id, int q)
2 7u83 192
{
6 7u83 193
	string s = mangle_diag(id, q);
194
	bs = enc_ustring(bs, s);
195
	return (bs);
2 7u83 196
}
197
 
198
 
199
/*
200
    ENCODE THE START OF A DIAGNOSTIC TAG DEFINITION
201
 
202
    This routine encodes the start of a diagnostic tag definition for
203
    diagnostic tag number n.  It returns a bitstream to which the
204
    diagnostic type definition needs to be added.
205
*/
206
 
6 7u83 207
static BITSTREAM *
208
enc_diag_tagdef_start(ulong n)
2 7u83 209
{
6 7u83 210
	BITSTREAM *bs = start_bitstream(NIL(FILE), diagtype_unit->link);
211
	record_usage(n, VAR_diagtag, USAGE_DEFN);
212
	ENC_make_diag_tagdef(bs);
213
	n = link_no(bs, n, VAR_diagtag);
214
	ENC_INT(bs, n);
215
	return (bs);
2 7u83 216
}
217
 
218
 
219
/*
220
    ENCODE THE END OF A DIAGNOSTIC TAG DEFINITION
221
 
222
    This routine completes the definition of a diagnostic tag.  bs is the
223
    result of a previous call to enc_diag_tagdef_start.
224
*/
225
 
6 7u83 226
static void
227
enc_diag_tagdef_end(BITSTREAM *bs)
2 7u83 228
{
6 7u83 229
	count_item(bs);
230
	diagtype_unit = join_bitstreams(diagtype_unit, bs);
231
	return;
2 7u83 232
}
233
 
234
 
235
/*
236
    ENCODE A LIST OF DIAGNOSTIC BASE CLASSES
237
 
238
    This routine adds the list of diagnostic base classes given by br
239
    to the bitstream bs in reverse order.  A count of the number of bases
240
    is maintained in pm.
241
*/
242
 
6 7u83 243
static BITSTREAM *
244
enc_diag_bases(BITSTREAM *bs, LIST(GRAPH)br, unsigned *pm)
2 7u83 245
{
6 7u83 246
	if (!IS_NULL_list(br)) {
247
		GRAPH gs = DEREF_graph(HEAD_list(br));
248
		CLASS_TYPE cs = DEREF_ctype(graph_head(gs));
249
		IDENTIFIER cid = DEREF_id(ctype_name(cs));
250
		DECL_SPEC acc = DEREF_dspec(graph_access(gs));
251
		bs = enc_diag_bases(bs, TAIL_list(br), pm);
252
		bs = enc_diag_name(bs, cid, 0);
253
		bs = enc_base(bs, gs, 1);
254
		if (acc & dspec_virtual) {
255
			ENC_diag_ptr(bs);
256
			bs = enc_diag_ctype(bs, cs);
257
			ENC_diag_tq_null(bs);
258
		} else {
259
			bs = enc_diag_ctype(bs, cs);
260
		}
261
		(*pm)++;
2 7u83 262
	}
6 7u83 263
	return (bs);
2 7u83 264
}
265
 
266
 
267
/*
268
    ENCODE A LIST OF DIAGNOSTIC CLASS MEMBERS
269
 
270
    This routine adds the list of diagnostic class members given by mem
271
    to the bitstream bs in reverse order.  A count of the number of members
272
    is maintained in pm.
273
*/
274
 
6 7u83 275
static BITSTREAM *
276
enc_diag_mems(BITSTREAM *bs, MEMBER mem, unsigned *pm)
2 7u83 277
{
6 7u83 278
	if (!IS_NULL_member(mem)) {
279
		IDENTIFIER mid = DEREF_id(member_id(mem));
280
		TYPE s = DEREF_type(id_member_type(mid));
281
		mem = DEREF_member(member_next(mem));
282
		mem = next_data_member(mem, 2);
283
		bs = enc_diag_mems(bs, mem, pm);
284
		bs = enc_diag_name(bs, mid, 0);
285
		bs = enc_member(bs, mid);
286
		bs = enc_diag_type(bs, s, 0);
287
		(*pm)++;
288
	}
289
	return (bs);
2 7u83 290
}
291
 
292
 
293
/*
294
    ENCODE A DIAGNOSTIC VIRTUAL FUNCTION TABLE
295
 
296
    This routine adds the diagnostic information for the virtual function
297
    table vt to the bitstream bs.  A count of the number of items is
298
    maintained in pm.
299
*/
300
 
6 7u83 301
static BITSTREAM *
302
enc_diag_vtable(BITSTREAM *bs, VIRTUAL vt, unsigned *pm)
2 7u83 303
{
6 7u83 304
	while (!IS_NULL_virt(vt)) {
305
		OFFSET off = DEREF_off(virt_table_off(vt));
306
		if (IS_NULL_off(off)) {
307
			/* New virtual function table */
308
			ulong n = DEREF_ulong(virt_table_tok(vt));
309
			bs = enc_ustring(bs, ustrlit("__vptr"));
310
			ENC_exp_apply_token(bs);
311
			n = link_no(bs, n, VAR_token);
312
			ENC_make_tok(bs, n);
313
			ENC_LEN_SMALL(bs, 0);
314
			ENC_diag_ptr(bs);
315
			bs = enc_diag_special(bs, TOK_vtab_diag, VAR_diagtag);
316
			ENC_diag_tq_null(bs);
317
			(*pm)++;
318
		}
319
		vt = DEREF_virt(virt_next(vt));
2 7u83 320
	}
6 7u83 321
	return (bs);
2 7u83 322
}
323
 
324
 
325
/*
326
    LIST OF INCOMPLETE CLASSES
327
 
328
    This list is used to hold all the classes which are used while they
329
    are incomplete.  A diagnostic tag is introduced for each such class
330
    which may be defined later if the class is completed.
331
*/
332
 
6 7u83 333
static LIST(CLASS_TYPE)diag_classes = NULL_list(CLASS_TYPE);
2 7u83 334
 
335
 
336
/*
337
    DEFINE A DIAGNOSTIC TAG FOR A CLASS
338
 
339
    This routine defines a diagnostic tag for the class ct if it is complete
340
    or def is true.
341
*/
342
 
6 7u83 343
static ulong
344
enc_diag_class(CLASS_TYPE ct, int def)
2 7u83 345
{
6 7u83 346
	ulong tok = LINK_NONE;
347
	CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
348
	IDENTIFIER id = DEREF_id(ctype_name(ct));
349
	ulong n = DEREF_ulong(id_no(id));
350
	if (n == LINK_NONE) {
351
		/* Create diagnostic tag information */
352
		n = capsule_no(NULL_string, VAR_diagtag);
353
		COPY_ulong(id_no(id), n);
354
	}
355
	if ((ci & cinfo_complete) && (ci & cinfo_defined)) {
356
		/* Complete class */
357
		tok = compile_class(ct);
358
		def = 1;
359
	} else {
360
		/* Incomplete class */
361
		if (def) {
362
			tok = special_no(TOK_empty_shape);
363
		}
364
	}
365
	if (def) {
366
		/* Define diagnostic tag */
367
		unsigned m = 0;
368
		BITSTREAM *bs, *ts;
369
		GRAPH gr = DEREF_graph(ctype_base(ct));
370
		LIST(GRAPH)br = DEREF_list(graph_tails(gr));
371
		NAMESPACE ns = DEREF_nspace(ctype_member(ct));
372
		MEMBER mem = DEREF_member(nspace_ctype_first(ns));
2 7u83 373
 
6 7u83 374
		/* Encode diagnostic tag definition */
375
		bs = enc_diag_tagdef_start(n);
376
		ts = start_bitstream(NIL(FILE), bs->link);
377
		if (ci & cinfo_union) {
378
			ENC_diag_union(bs);
379
		} else {
380
			ENC_diag_struct(bs);
381
		}
382
		ENC_shape_apply_token(bs);
383
		tok = link_no(bs, tok, VAR_token);
384
		ENC_make_tok(bs, tok);
385
		ENC_LEN_SMALL(bs, 0);
386
		bs = enc_diag_name(bs, id, 1);
387
		mem = next_data_member(mem, 2);
388
		if (ci & cinfo_polymorphic) {
389
			VIRTUAL vt = DEREF_virt(ctype_virt(ct));
390
			ts = enc_diag_vtable(ts, vt, &m);
391
		}
392
		ts = enc_diag_mems(ts, mem, &m);
393
		ts = enc_diag_bases(ts, br, &m);
394
		ENC_LIST(bs, m);
395
		bs = join_bitstreams(bs, ts);
396
		enc_diag_tagdef_end(bs);
2 7u83 397
	} else {
6 7u83 398
		CONS_ctype(ct, diag_classes, diag_classes);
2 7u83 399
	}
6 7u83 400
	return (n);
2 7u83 401
}
402
 
403
 
404
/*
405
    DEFINE INCOMPLETE CLASSES
406
 
407
    This routine defines the diagnostic tags for the incomplete classes
408
    in the list above.
409
*/
410
 
6 7u83 411
int
412
enc_diag_pending(void)
2 7u83 413
{
6 7u83 414
	int changed = 0;
415
	if (output_diag) {
416
		LIST(CLASS_TYPE)p;
2 7u83 417
#if TDF_NEW_DIAG
6 7u83 418
		if (output_new_diag) {
419
			changed = enc_dg_pending();
420
			return (changed);
421
		}
2 7u83 422
#endif
6 7u83 423
		while (p = diag_classes, !IS_NULL_list(p)) {
424
			diag_classes = NULL_list(CLASS_TYPE);
425
			while (!IS_NULL_list(p)) {
426
				CLASS_TYPE ct;
427
				DESTROY_CONS_ctype(destroy, ct, p, p);
428
				IGNORE enc_diag_class(ct, 1);
429
				changed = 1;
430
			}
431
		}
2 7u83 432
	}
6 7u83 433
	return (changed);
2 7u83 434
}
435
 
436
 
437
/*
438
    ENCODE A DIAGNOSTIC CLASS TYPE
439
 
440
    This routine encodes the diagnostic information for the class type ct
441
    to the bitstream bs.
442
*/
443
 
6 7u83 444
BITSTREAM *
445
enc_diag_ctype(BITSTREAM *bs, CLASS_TYPE ct)
2 7u83 446
{
6 7u83 447
	IDENTIFIER id = DEREF_id(ctype_name(ct));
448
	ulong n = DEREF_ulong(id_no(id));
449
	if (n == LINK_NONE) {
450
		CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
451
		if (ci & cinfo_token) {
452
			/* Allow for tokenised types */
453
			TYPE t = DEREF_type(ctype_form(ct));
454
			bs = enc_diag_type(bs, t, 0);
455
			return (bs);
456
		}
457
		n = enc_diag_class(ct, 0);
2 7u83 458
	}
6 7u83 459
	n = link_no(bs, n, VAR_diagtag);
460
	ENC_use_diag_tag(bs);
461
	ENC_make_diag_tag(bs, n);
462
	return (bs);
2 7u83 463
}
464
 
465
 
466
/*
467
    ENCODE A DIAGNOSTIC ENUMERATION TYPE
468
 
469
    This routine encodes the diagnostic information for the enumeration
470
    type et to the bitstream bs.  This is represented by a diagnostic tag.
471
*/
472
 
6 7u83 473
static BITSTREAM *
474
enc_diag_etype(BITSTREAM *bs, ENUM_TYPE et)
2 7u83 475
{
6 7u83 476
	IDENTIFIER id = DEREF_id(etype_name(et));
477
	ulong n = DEREF_ulong(id_no(id));
478
	if (n == LINK_NONE) {
479
		/* Decompose enumeration type */
480
		BITSTREAM *ts;
481
		TYPE t = DEREF_type(etype_rep(et));
482
		LIST(IDENTIFIER)p = DEREF_list(etype_values(et));
483
		CLASS_INFO ei = DEREF_cinfo(etype_info(et));
484
		if (!(ei & cinfo_complete)) {
485
			bs = enc_diag_type(bs, t, 0);
486
			return (bs);
487
		}
2 7u83 488
 
6 7u83 489
		/* Encode diagnostic tag definition */
490
		n = capsule_no(NULL_string, VAR_diagtag);
491
		COPY_ulong(id_no(id), n);
492
		ts = enc_diag_tagdef_start(n);
493
		ENC_diag_enum(ts);
494
		ts = enc_diag_type(ts, t, 0);
495
		ts = enc_diag_name(ts, id, 1);
496
		ENC_LIST(ts, LENGTH_list(p));
497
		while (!IS_NULL_list(p)) {
498
			/* Scan through enumerators */
499
			IDENTIFIER pid = DEREF_id(HEAD_list(p));
500
			EXP e = DEREF_exp(id_enumerator_value(pid));
501
			ts = enc_exp(ts, e);
502
			ts = enc_diag_name(ts, pid, 1);
503
			p = TAIL_list(p);
504
		}
505
		enc_diag_tagdef_end(ts);
2 7u83 506
	}
507
 
6 7u83 508
	/* Encode diagnostic tag use */
509
	n = link_no(bs, n, VAR_diagtag);
510
	ENC_use_diag_tag(bs);
511
	ENC_make_diag_tag(bs, n);
512
	return (bs);
2 7u83 513
}
514
 
515
 
516
/*
517
    ENCODE A TOKENISED DIAGNOSTIC TYPE
518
 
519
    This routine adds the diagnostic information for the tokenised type
520
    id ( args ) to the bitstream bs.
521
*/
522
 
6 7u83 523
static BITSTREAM *
524
enc_diag_tok_type(BITSTREAM *bs, IDENTIFIER id, LIST(TOKEN)args)
2 7u83 525
{
6 7u83 526
	if (IS_NULL_list(args)) {
527
		ulong n = get_diag_tag(id, VAR_token);
528
		if (n == LINK_NONE) {
529
			/* Find external name */
530
			string s = mangle_name(id, VAR_diagtag, 0);
531
			n = capsule_no(s, VAR_diagtag);
532
			set_diag_tag(id, VAR_token, n);
533
		}
534
		n = link_no(bs, n, VAR_diagtag);
535
		ENC_use_diag_tag(bs);
536
		ENC_make_diag_tag(bs, n);
537
	} else {
538
		/* NOT YET IMPLEMENTED */
539
		ENC_diag_type_null(bs);
2 7u83 540
	}
6 7u83 541
	return (bs);
2 7u83 542
}
543
 
544
 
545
/*
546
    ENCODE A DIAGNOSTIC TYPE QUALIFIER
547
 
548
    This routine adds the diagnostic type qualifiers cv to the bitstream bs.
549
*/
550
 
6 7u83 551
static BITSTREAM *
552
enc_diag_type_qual(BITSTREAM *bs, CV_SPEC cv)
2 7u83 553
{
6 7u83 554
	if (cv & cv_const) {
555
		ENC_add_diag_const(bs);
556
	}
557
	if (cv & cv_volatile) {
558
		ENC_add_diag_volatile(bs);
559
	}
560
	ENC_diag_tq_null(bs);
561
	return (bs);
2 7u83 562
}
563
 
564
 
565
/*
566
    ENCODE A DIAGNOSTIC TYPE
567
 
568
    This routine adds the diagnostic information for the type t to the
569
    bitstream bs.  The type qualifiers are only output if qual is true.
570
*/
571
 
6 7u83 572
BITSTREAM *
573
enc_diag_type(BITSTREAM *bs, TYPE t, int qual)
2 7u83 574
{
6 7u83 575
	if (IS_NULL_type(t)) {
576
		ENC_diag_type_null(bs);
577
		return (bs);
2 7u83 578
	}
6 7u83 579
	if (qual) {
580
		/* Output type qualifier */
581
		CV_SPEC cv = DEREF_cv(type_qual(t));
582
		if (cv & cv_qual) {
583
			ENC_diag_loc(bs);
584
			bs = enc_diag_type(bs, t, 0);
585
			bs = enc_diag_type_qual(bs, cv);
586
			return (bs);
587
		}
2 7u83 588
	}
6 7u83 589
	ASSERT(ORDER_type == 18);
590
	switch (TAG_type(t)) {
591
	case type_integer_tag: {
592
		/* Integral types */
593
		ENC_diag_variety(bs);
594
		bs = enc_variety(bs, t);
595
		break;
2 7u83 596
	}
6 7u83 597
	case type_floating_tag: {
598
		/* Floating point types */
599
		ENC_diag_floating_variety(bs);
600
		bs = enc_flvar(bs, t);
601
		break;
2 7u83 602
	}
6 7u83 603
	case type_ptr_tag:
604
	case type_ref_tag: {
605
		/* Pointer types */
606
		TYPE s = DEREF_type(type_ptr_etc_sub(t));
607
		CV_SPEC cv = DEREF_cv(type_qual(s));
608
		ENC_diag_ptr(bs);
609
		bs = enc_diag_type(bs, s, 0);
610
		bs = enc_diag_type_qual(bs, cv);
611
		break;
2 7u83 612
	}
6 7u83 613
	case type_ptr_mem_tag: {
614
		/* Pointer to member types */
615
		int tok = TOK_pm_type;
616
		TYPE s = DEREF_type(type_ptr_mem_sub(t));
617
		if (IS_type_func(s)) {
618
			tok = TOK_pmf_type;
619
		}
620
		bs = enc_diag_special(bs, tok, VAR_diagtag);
621
		break;
2 7u83 622
	}
6 7u83 623
	case type_func_tag: {
624
		/* Function types */
625
		TYPE r = DEREF_type(type_func_ret(t));
626
		LIST(TYPE)p = DEREF_list(type_func_mtypes(t));
627
		int ell = DEREF_int(type_func_ellipsis(t));
628
		ENC_diag_proc(bs);
629
		ENC_LIST(bs, LENGTH_list(p));
630
		while (!IS_NULL_list(p)) {
631
			TYPE s = DEREF_type(HEAD_list(p));
632
			bs = enc_diag_type(bs, s, 0);
633
			p = TAIL_list(p);
634
		}
635
		bs = enc_bool(bs,(ell & FUNC_ELLIPSIS));
636
		bs = enc_diag_type(bs, r, 0);
637
		break;
638
	}
639
	case type_array_tag: {
640
		/* Array types */
641
		TYPE i = type_sint;
642
		TYPE s = DEREF_type(type_array_sub(t));
643
		NAT n = DEREF_nat(type_array_size(t));
644
		ENC_diag_array(bs);
645
		bs = enc_diag_type(bs, s, 0);
646
		bs = enc_shape_offset(bs, s);
647
		bs = enc_make_int(bs, i, 0);
648
		if (IS_NULL_nat(n)) {
649
			/* Empty array bound */
650
			bs = enc_make_int(bs, i, 0);
2 7u83 651
		} else {
6 7u83 652
			/* Calculated array bound */
653
			unsigned long v = get_nat_value(n);
654
			if (v < SMALL_ARRAY_BOUND) {
655
				/* Small value */
656
				if (v) {
657
					v--;
658
				}
659
				bs = enc_make_int(bs, i,(int)v);
660
			} else {
661
				ENC_minus(bs);
662
				bs = enc_error_treatment(bs, i);
663
				ENC_make_int(bs);
664
				bs = enc_variety(bs, i);
665
				bs = enc_snat(bs, n, 0, 1);
666
				bs = enc_make_int(bs, i, 1);
667
			}
2 7u83 668
		}
6 7u83 669
		bs = enc_diag_type(bs, i, 0);
670
		break;
2 7u83 671
	}
6 7u83 672
	case type_bitfield_tag: {
673
		/* Bitfield types */
674
		INT_TYPE bf = DEREF_itype(type_bitfield_defn(t));
675
		TYPE s = DEREF_type(itype_bitfield_sub(bf));
676
		NAT n = DEREF_nat(itype_bitfield_size(bf));
677
		ENC_diag_bitfield(bs);
678
		bs = enc_diag_type(bs, s, 0);
679
		bs = enc_nat(bs, n, 1);
680
		break;
2 7u83 681
	}
6 7u83 682
	case type_compound_tag: {
683
		/* Class types */
684
		CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
685
		bs = enc_diag_ctype(bs, ct);
686
		break;
2 7u83 687
	}
6 7u83 688
	case type_enumerate_tag: {
689
		/* Enumeration types */
690
		ENUM_TYPE et = DEREF_etype(type_enumerate_defn(t));
691
		bs = enc_diag_etype(bs, et);
692
		break;
2 7u83 693
	}
6 7u83 694
	case type_token_tag: {
695
		/* Tokenised types */
696
		IDENTIFIER tok = DEREF_id(type_token_tok(t));
697
		LIST(TOKEN)args = DEREF_list(type_token_args(t));
698
		bs = enc_diag_tok_type(bs, tok, args);
699
		break;
2 7u83 700
	}
701
	default : {
6 7u83 702
		/* Other types */
703
		ENC_diag_type_null(bs);
704
		break;
2 7u83 705
	}
6 7u83 706
	}
707
	return (bs);
2 7u83 708
}
709
 
710
 
711
/*
712
    ENCODE DIAGNOSTICS FOR A TOKEN DEFINITION
713
 
714
    This routine outputs any diagnostic information for the token id
715
    to the appropriate diagnostic units.  It is only called if id is
716
    defined.  The type t may be used to override the type of id.
717
*/
718
 
6 7u83 719
void
720
enc_diag_token(IDENTIFIER id, TYPE t)
2 7u83 721
{
6 7u83 722
	TOKEN tok;
2 7u83 723
#if TDF_NEW_DIAG
6 7u83 724
	if (output_new_diag) {
725
		enc_dg_token(id, t);
726
		return;
727
	}
2 7u83 728
#endif
6 7u83 729
	tok = DEREF_tok(id_token_sort(id));
730
	if (IS_tok_type(tok)) {
731
		BASE_TYPE bt = DEREF_btype(tok_type_kind(tok));
732
		if (bt & btype_scalar) {
733
			/* Tokenised arithmetic types */
734
			/* EMPTY */
735
		} else {
736
			/* Tokenised generic types */
737
			BITSTREAM *bs;
738
			IDENTIFIER alt = DEREF_id(id_token_alt(id));
739
			DECL_SPEC ds = DEREF_dspec(id_storage(alt));
740
			ulong n = get_diag_tag(id, VAR_token);
741
			if (n == LINK_NONE) {
742
				/* Find external name */
743
				string s = mangle_name(id, VAR_diagtag, 0);
744
				n = capsule_no(s, VAR_diagtag);
745
				set_diag_tag(id, VAR_token, n);
746
			}
747
			bs = enc_diag_tagdef_start(n);
748
			if (IS_NULL_type(t)) {
749
				/* Extract type if not given */
750
				t = DEREF_type(tok_type_value(tok));
751
			}
752
			bs = enc_diag_type(bs, t, 0);
753
			enc_diag_tagdef_end(bs);
754
			if (!(ds & dspec_done)) {
755
				/* Output internal name */
756
				ds |= dspec_done;
757
				COPY_dspec(id_storage(alt), ds);
758
				enc_diag_id(alt, 1);
759
			}
760
		}
2 7u83 761
	}
6 7u83 762
	return;
2 7u83 763
}
764
 
765
 
766
/*
767
    ENCODE A GLOBAL DIAGNOSTIC IDENTIFIER
768
 
769
    This routine adds the diagnostic information for the global identifier
770
    id to the diagnostic definition unit.  def is true for a definition.
771
*/
772
 
6 7u83 773
void
774
enc_diag_id(IDENTIFIER id, int def)
2 7u83 775
{
6 7u83 776
	TYPE t;
777
	ulong n;
778
	BITSTREAM *bs = NULL;
2 7u83 779
#if TDF_NEW_DIAG
6 7u83 780
	if (output_new_diag) {
781
		enc_dg_id(id, def);
782
		return;
783
	}
2 7u83 784
#endif
6 7u83 785
	UNUSED(def);
786
	n = DEREF_ulong(id_no(id));
787
	switch (TAG_id(id)) {
788
	case id_class_alias_tag:
789
	case id_enum_alias_tag:
790
	case id_type_alias_tag: {
791
		/* Typedef names */
792
		t = DEREF_type(id_class_name_etc_defn(id));
793
		bs = start_bitstream(NIL(FILE), diagdef_unit->link);
794
		ENC_diag_desc_typedef(bs);
795
		bs = enc_diag_name(bs, id, 1);
796
		bs = enc_diag_loc(bs, id_loc(id));
797
		bs = enc_diag_type(bs, t, 1);
798
		break;
2 7u83 799
	}
6 7u83 800
	case id_variable_tag:
801
	case id_parameter_tag:
802
	case id_stat_member_tag: {
803
		/* Variable names */
804
		t = DEREF_type(id_variable_etc_type(id));
805
		goto diag_label;
2 7u83 806
	}
6 7u83 807
	case id_function_tag:
808
	case id_mem_func_tag:
809
	case id_stat_mem_func_tag: {
810
		/* Function names */
811
		t = DEREF_type(id_function_etc_type(id));
812
		goto diag_label;
2 7u83 813
	}
6 7u83 814
diag_label: {
815
		     bs = start_bitstream(NIL(FILE), diagdef_unit->link);
816
		     ENC_diag_desc_id(bs);
817
		     bs = enc_diag_name(bs, id, 1);
818
		     bs = enc_diag_loc(bs, id_loc(id));
819
		     ENC_obtain_tag(bs);
820
		     n = link_no(bs, n, VAR_tag);
821
		     ENC_make_tag(bs, n);
822
		     bs = enc_diag_type(bs, t, 1);
823
		     break;
824
	     }
2 7u83 825
	}
6 7u83 826
	if (bs) {
827
		count_item(bs);
828
		diagdef_unit = join_bitstreams(diagdef_unit, bs);
829
	}
830
	return;
2 7u83 831
}
832
 
833
 
834
/*
835
    ENCODE DIAGNOSTICS INITIALISATION FUNCTION
836
 
837
    This routine adds the diagnostic information for the initialisation
838
    or termination function named s with tag number n to the diagnostics
839
    definition unit.
840
*/
841
 
6 7u83 842
void
843
enc_diag_init(CONST char *s, ulong n, TYPE t)
2 7u83 844
{
6 7u83 845
	if (output_all) {
846
		string u = ustrlit(s);
847
		n = capsule_name(n, &u, VAR_tag);
848
		if (u) {
849
			n = capsule_name(n, &u, VAR_tag);
850
		}
851
	}
852
	if (output_diag && !output_new_diag) {
853
		BITSTREAM *bs = start_bitstream(NIL(FILE), diagdef_unit->link);
854
		ENC_diag_desc_id(bs);
855
		bs = enc_ustring(bs, ustrlit(s));
856
		bs = enc_diag_loc(bs, NULL_ptr(LOCATION));
857
		ENC_obtain_tag(bs);
858
		n = link_no(bs, n, VAR_tag);
859
		ENC_make_tag(bs, n);
860
		bs = enc_diag_type(bs, t, 0);
861
		count_item(bs);
862
		diagdef_unit = join_bitstreams(diagdef_unit, bs);
863
	}
864
	return;
2 7u83 865
}
866
 
867
 
868
/*
869
    ENCODE A LOCAL DIAGNOSTIC IDENTIFIER
870
 
871
    This routine adds the diagnostic information for the local identifier
872
    id to the bitstream bs.  ts gives the encoding of the scope of id.
873
*/
874
 
6 7u83 875
BITSTREAM *
876
enc_diag_local(BITSTREAM *bs, IDENTIFIER id, BITSTREAM *ts)
2 7u83 877
{
6 7u83 878
	TYPE t;
879
	ulong n, m;
2 7u83 880
#if TDF_NEW_DIAG
6 7u83 881
	if (output_new_diag) {
882
		bs = enc_dg_local(bs, id, ts);
883
		return (bs);
884
	}
2 7u83 885
#endif
6 7u83 886
	n = diag_id_scope_tok;
887
	if (n == LINK_NONE) {
888
		/* Assign token number */
889
		n = capsule_no(ustrlit("~diag_id_scope"), VAR_token);
890
		diag_id_scope_tok = n;
891
	}
2 7u83 892
 
6 7u83 893
	/* Add identifier information to ts */
894
	t = DEREF_type(id_variable_etc_type(id));
895
	ts = enc_diag_name(ts, id, 0);
896
	ENC_obtain_tag(ts);
897
	m = unit_no(ts, id, VAR_tag, 0);
898
	ENC_make_tag(ts, m);
899
	ts = enc_diag_type(ts, t, 1);
2 7u83 900
 
6 7u83 901
	/* Create a token application */
902
	ENC_exp_apply_token(bs);
903
	n = link_no(bs, n, VAR_token);
904
	ENC_make_tok(bs, n);
905
	bs = enc_bitstream(bs, ts);
906
	return (bs);
2 7u83 907
}
908
 
909
 
910
/*
911
    ENCODE A LIST OF DIAGNOSTIC PARAMETERS
912
 
913
    This routine adds the diagnostic information for the list of function
914
    parameters p to the bitstream bs.  ts and e give the function body.
915
*/
916
 
6 7u83 917
BITSTREAM *
918
enc_diag_params(BITSTREAM *bs, LIST(IDENTIFIER)p, BITSTREAM *ts, EXP e)
2 7u83 919
{
920
#if TDF_NEW_DIAG
6 7u83 921
	if (output_new_diag) {
922
		bs = enc_dg_params(bs, p, ts, e);
923
		return (bs);
924
	}
2 7u83 925
#endif
6 7u83 926
	if (IS_NULL_list(p)) {
927
		bs = join_bitstreams(bs, ts);
928
	} else {
929
		IDENTIFIER pid = DEREF_id(HEAD_list(p));
930
		BITSTREAM *us = start_bitstream(NIL(FILE), bs->link);
931
		us = enc_diag_params(us, TAIL_list(p), ts, e);
932
		bs = enc_diag_local(bs, pid, us);
933
	}
934
	return (bs);
2 7u83 935
}
936
 
937
 
938
/*
939
    ENCODE DIAGNOSTIC STATEMENT TOKEN
940
 
941
    This routine adds the token used to associate diagnostic information
942
    with a statement to the bitstream bs.
943
*/
944
 
6 7u83 945
BITSTREAM *
946
enc_diag_start(BITSTREAM *bs)
2 7u83 947
{
6 7u83 948
	ulong n = exp_to_source_tok;
949
	if (n == LINK_NONE) {
950
		/* Assign token number */
951
		string tok = ustrlit("~exp_to_source");
2 7u83 952
#if TDF_NEW_DIAG
6 7u83 953
		if (output_new_diag) {
954
			tok = ustrlit("~dg_exp");
955
		}
2 7u83 956
#endif
6 7u83 957
		n = capsule_no(tok, VAR_token);
958
		exp_to_source_tok = n;
959
	}
960
	n = link_no(bs, n, VAR_token);
961
	ENC_exp_apply_token(bs);
962
	ENC_make_tok(bs, n);
963
	return (bs);
2 7u83 964
}
965
 
966
 
967
 
968
/*
969
    ENCODE THE START OF A DIAGNOSTIC STATEMENT
970
 
971
    This routine adds the start of a diagnostic statement e to the
972
    bitstream pointed to by pbs.
973
*/
974
 
6 7u83 975
BITSTREAM *
976
enc_diag_begin(BITSTREAM **pbs)
2 7u83 977
{
6 7u83 978
	BITSTREAM *bs = *pbs;
979
	if (output_diag) {
980
		bs = enc_diag_start(bs);
981
		*pbs = bs;
982
		bs = start_bitstream(NIL(FILE), bs->link);
983
	}
984
	return (bs);
2 7u83 985
}
986
 
987
 
988
/*
989
    SHOULD DIAGNOSTICS BE OUTPUT FOR A STATEMENT?
990
 
991
    Not all statements are marked with diagnostic locations because they
992
    are revelant when single stepping through the program.  This routine
993
    checks whether diagnostics should be output for the statement e.
994
*/
995
 
6 7u83 996
int
997
is_diag_stmt(EXP e)
2 7u83 998
{
6 7u83 999
	if (!IS_NULL_exp(e)) {
1000
		switch (TAG_exp(e)) {
1001
		case exp_sequence_tag: {
1002
			/* Lexical blocks */
1003
			if (output_new_diag) {
1004
				int blk = DEREF_int(exp_sequence_block(e));
1005
				return (blk);
1006
			}
1007
			return (0);
2 7u83 1008
		}
6 7u83 1009
		case exp_label_stmt_tag: {
1010
			/* Labelled statements */
1011
			if (output_new_diag) {
1012
				IDENTIFIER lab =
1013
				    DEREF_id(exp_label_stmt_label(e));
1014
				HASHID nm = DEREF_hashid(id_name(lab));
1015
				if (!IS_hashid_anon(nm)) {
1016
					return (1);
1017
				}
1018
			}
1019
			return (0);
2 7u83 1020
		}
6 7u83 1021
		case exp_if_stmt_tag: {
1022
			/* If statements and expressions */
1023
			if (output_diag) {
1024
				IDENTIFIER lab = DEREF_id(exp_if_stmt_label(e));
1025
				if (IS_NULL_id(lab)) {
1026
					return (1);
1027
				}
1028
			}
1029
			return (0);
2 7u83 1030
		}
6 7u83 1031
		case exp_decl_stmt_tag:
1032
		case exp_while_stmt_tag:
1033
		case exp_do_stmt_tag:
1034
		case exp_switch_stmt_tag:
1035
		case exp_hash_if_tag:
1036
		case exp_try_block_tag:
1037
		case exp_handler_tag: {
1038
			/* Control statements */
1039
			return (0);
1040
		}
1041
		}
2 7u83 1042
	}
6 7u83 1043
	return (output_diag);
2 7u83 1044
}
1045
 
1046
 
1047
/*
1048
    ENCODE THE BODY OF A DIAGNOSTIC STATEMENT
1049
 
1050
    This routine adds the diagnostic information associated with the
1051
    statement e to the bitstream bs.
1052
*/
1053
 
6 7u83 1054
BITSTREAM *
1055
enc_diag_stmt(BITSTREAM *bs, EXP e, int stmt)
2 7u83 1056
{
6 7u83 1057
	PTR(LOCATION)loc;
2 7u83 1058
#if TDF_NEW_DIAG
6 7u83 1059
	if (output_new_diag) {
1060
		bs = enc_dg_stmt(bs, e, stmt);
1061
		return (bs);
1062
	}
2 7u83 1063
#endif
6 7u83 1064
	loc = crt_enc_loc;
1065
	if (!IS_NULL_exp(e)) {
1066
		switch (TAG_exp(e)) {
1067
		case exp_decl_stmt_tag: {
1068
			IDENTIFIER id = DEREF_id(exp_decl_stmt_id(e));
1069
			loc = id_loc(id);
1070
			break;
1071
		}
1072
		case exp_label_stmt_tag: {
1073
			IDENTIFIER id = DEREF_id(exp_label_stmt_label(e));
1074
			loc = id_loc(id);
1075
			break;
1076
		}
1077
		}
2 7u83 1078
	}
6 7u83 1079
	bs = enc_diag_loc(bs, loc);
1080
	bs = enc_diag_loc(bs, loc);
1081
	UNUSED(stmt);
1082
	return (bs);
2 7u83 1083
}
1084
 
1085
 
1086
/*
1087
    ENCODE THE END OF A DIAGNOSTIC STATEMENT
1088
 
1089
    This routine adds the end of the diagnostic statement e to the
1090
    bitstream bs.  ts gives the encoding of e.
1091
*/
1092
 
6 7u83 1093
BITSTREAM *
1094
enc_diag_end(BITSTREAM *bs, BITSTREAM *ts, EXP e, int stmt)
2 7u83 1095
{
6 7u83 1096
	if (output_diag) {
1097
		ts = enc_diag_stmt(ts, e, stmt);
1098
		ts = enc_bitstream(bs, ts);
1099
	}
1100
	return (ts);
2 7u83 1101
}
1102
 
1103
 
1104
#endif /* TDF_OUTPUT */