Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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