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 "c_types.h"
33
#include "exp_ops.h"
34
#include "id_ops.h"
35
#include "member_ops.h"
36
#include "nspace_ops.h"
37
#include "off_ops.h"
38
#include "type_ops.h"
39
#include "error.h"
40
#include "destroy.h"
41
#include "exception.h"
42
#include "macro.h"
43
 
44
 
45
/*
46
    FREE A LOCAL IDENTIFIER
47
 
48
    This routine frees the local identifier id.
49
*/
50
 
51
static void free_id
52
    PROTO_N ( ( id, force ) )
53
    PROTO_T ( IDENTIFIER id X int force )
54
{
55
    if ( IS_NULL_id ( id ) ) return ;
56
    switch ( TAG_id ( id ) ) {
57
	case id_variable_tag : {
58
	    DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
59
	    if ( ds & dspec_auto ) {
60
		EXP e = DEREF_exp ( id_variable_init ( id ) ) ;
61
		EXP d = DEREF_exp ( id_variable_term ( id ) ) ;
62
		if ( !IS_NULL_exp ( e ) ) free_exp ( e, force ) ;
63
		if ( !IS_NULL_exp ( d ) ) free_exp ( d, force ) ;
64
		COPY_exp ( id_variable_init ( id ), NULL_exp ) ;
65
		COPY_exp ( id_variable_term ( id ), NULL_exp ) ;
66
	    }
67
	    break ;
68
	}
69
	case id_label_tag : {
70
	    LIST ( VARIABLE ) v = DEREF_list ( id_label_vars ( id ) ) ;
71
	    DESTROY_list ( v, SIZE_var ) ;
72
	    COPY_list ( id_label_vars ( id ), NULL_list ( VARIABLE ) ) ;
73
	    COPY_exp ( id_label_stmt ( id ), NULL_exp ) ;
74
	    COPY_exp ( id_label_gotos ( id ), NULL_exp ) ;
75
	    break ;
76
	}
77
    }
78
    return ;
79
}
80
 
81
 
82
/*
83
    FREE A NAMESPACE
84
 
85
    This routine frees the block namespace ns.
86
*/
87
 
88
void free_nspace
89
    PROTO_N ( ( ns ) )
90
    PROTO_T ( NAMESPACE ns )
91
{
92
    if ( !IS_NULL_nspace ( ns ) ) {
93
	MEMBER mem = DEREF_member ( nspace_last ( ns ) ) ;
94
	while ( !IS_NULL_member ( mem ) ) {
95
	    IDENTIFIER id ;
96
	    IDENTIFIER alt ;
97
	    DESTROY_member_small ( destroy, id, alt, mem, mem ) ;
98
	    UNUSED ( id ) ;
99
	    UNUSED ( alt ) ;
100
	}
101
	COPY_member ( nspace_last ( ns ), NULL_member ) ;
102
	COPY_member ( nspace_prev ( ns ), NULL_member ) ;
103
    }
104
    return ;
105
}
106
 
107
 
108
/*
109
    FREE AN OFFSET
110
 
111
    This routine frees the offset off.  Note that member and base offsets
112
    are linked directly to the classes they represent and so are not
113
    destroyed here.
114
*/
115
 
116
void free_offset
117
    PROTO_N ( ( off, force ) )
118
    PROTO_T ( OFFSET off X int force )
119
{
120
    if ( IS_NULL_off ( off ) ) return ;
121
    ASSERT ( ORDER_off == 13 ) ;
122
    switch ( TAG_off ( off ) ) {
123
	case off_zero_tag : {
124
	    TYPE t ;
125
	    DESTROY_off_zero ( destroy, t, off ) ;
126
	    UNUSED ( t ) ;
127
	    break ;
128
	}
129
	case off_type_tag : {
130
	    TYPE t ;
131
	    DESTROY_off_type ( destroy, t, off ) ;
132
	    UNUSED ( t ) ;
133
	    break ;
134
	}
135
	case off_extra_tag : {
136
	    int n ;
137
	    TYPE t ;
138
	    DESTROY_off_extra ( destroy, t, n, off ) ;
139
	    UNUSED ( n ) ;
140
	    UNUSED ( t ) ;
141
	    break ;
142
	}
143
	case off_array_tag : {
144
	    TYPE t ;
145
	    unsigned n ;
146
	    DESTROY_off_array ( destroy, t, n, off ) ;
147
	    UNUSED ( n ) ;
148
	    UNUSED ( t ) ;
149
	    break ;
150
	}
151
	case off_ptr_mem_tag : {
152
	    EXP a ;
153
	    DESTROY_off_ptr_mem ( destroy, a, off ) ;
154
	    free_exp ( a, force ) ;
155
	    break ;
156
	}
157
	case off_negate_tag : {
158
	    OFFSET a ;
159
	    DESTROY_off_negate ( destroy, a, off ) ;
160
	    free_offset ( a, force ) ;
161
	    break ;
162
	}
163
	case off_mult_tag : {
164
	    EXP b ;
165
	    OFFSET a ;
166
	    DESTROY_off_mult ( destroy, a, b, off ) ;
167
	    free_offset ( a, force ) ;
168
	    free_exp ( b, force ) ;
169
	    break ;
170
	}
171
	case off_ptr_diff_tag : {
172
	    EXP a, b ;
173
	    DESTROY_off_ptr_diff ( destroy, a, b, off ) ;
174
	    free_exp ( a, force ) ;
175
	    free_exp ( b, force ) ;
176
	    break ;
177
	}
178
	case off_base_tag :
179
	case off_deriv_tag :
180
	case off_member_tag :
181
	case off_plus_tag :
182
	case off_token_tag : {
183
	    /* Don't free these cases */
184
	    break ;
185
	}
186
    }
187
    return ;
188
}
189
 
190
 
191
/*
192
    DESTROY A LIST OF EXPRESSIONS
193
 
194
    This routine frees the list of expressions p.
195
*/
196
 
197
void free_exp_list
198
    PROTO_N ( ( p, force ) )
199
    PROTO_T ( LIST ( EXP ) p X int force )
200
{
201
    while ( !IS_NULL_list ( p ) ) {
202
	EXP e ;
203
	DESTROY_CONS_exp ( destroy, e, p, p ) ;
204
	free_exp ( e, force ) ;
205
    }
206
    return ;
207
}
208
 
209
 
210
/*
211
    FREE AN EXPRESSION
212
 
213
    This routine frees the expression e.  It is possible for the same
214
    sub-expression to be reused twice in an expression, so freed expressions
215
    are marked by having their type set to the rule type.  This exploits
216
    some knowledge about about how destroy_c_class works.
217
*/
218
 
219
void free_exp
220
    PROTO_N ( ( e, force ) )
221
    PROTO_T ( EXP e X int force )
222
{
223
    TYPE t ;
224
    EXP a, b ;
225
    int force1 = force ;
226
    if ( force1 == 0 ) force1 = 1 ;
227
 
228
    /* Check expression type */
229
    if ( IS_NULL_exp ( e ) ) return ;
230
    t = DEREF_type ( exp_type ( e ) ) ;
231
    if ( IS_NULL_type ( t ) || IS_type_error ( t ) ) return ;
232
    COPY_type ( exp_type ( e ), NULL_type ) ;
233
 
234
    /* Deal with the various cases */
235
    ASSERT ( ORDER_exp == 88 ) ;
236
    switch ( TAG_exp ( e ) ) {
237
	case exp_identifier_tag :
238
	case exp_member_tag :
239
	case exp_ambiguous_tag :
240
	case exp_undeclared_tag : {
241
	    IDENTIFIER id ;
242
	    QUALIFIER qual ;
243
	    DESTROY_exp_identifier_etc ( destroy, t, id, qual, e ) ;
244
	    UNUSED ( qual ) ;
245
	    UNUSED ( id ) ;
246
	    break ;
247
	}
248
	case exp_int_lit_tag : {
249
	    NAT n ;
250
	    unsigned etag ;
251
	    DESTROY_exp_int_lit ( destroy, t, n, etag, e ) ;
252
	    UNUSED ( etag ) ;
253
	    UNUSED ( n ) ;
254
	    break ;
255
	}
256
	case exp_float_lit_tag : {
257
	    FLOAT f ;
258
	    DESTROY_exp_float_lit ( destroy, t, f, e ) ;
259
	    UNUSED ( f ) ;
260
	    break ;
261
	}
262
	case exp_char_lit_tag : {
263
	    int r ;
264
	    STRING s ;
265
	    DESTROY_exp_char_lit ( destroy, t, s, r, e ) ;
266
	    UNUSED ( s ) ;
267
	    UNUSED ( r ) ;
268
	    break ;
269
	}
270
	case exp_string_lit_tag : {
271
	    STRING s ;
272
	    DESTROY_exp_string_lit ( destroy, t, s, e ) ;
273
	    UNUSED ( s ) ;
274
	    break ;
275
	}
276
	case exp_value_tag : {
277
	    DESTROY_exp_value ( destroy, t, e ) ;
278
	    break ;
279
	}
280
	case exp_null_tag : {
281
	    DESTROY_exp_null ( destroy, t, e ) ;
282
	    break ;
283
	}
284
	case exp_zero_tag : {
285
	    DESTROY_exp_zero ( destroy, t, e ) ;
286
	    break ;
287
	}
288
	case exp_paren_tag : {
289
	    DESTROY_exp_paren ( destroy, t, a, e ) ;
290
	    free_exp ( a, force1 ) ;
291
	    break ;
292
	}
293
	case exp_copy_tag : {
294
	    DESTROY_exp_copy ( destroy, t, a, e ) ;
295
	    UNUSED ( a ) ;
296
	    break ;
297
	}
298
	case exp_assign_tag : {
299
	    DESTROY_exp_assign ( destroy, t, a, b, e ) ;
300
	    free_exp ( a, force1 ) ;
301
	    free_exp ( b, force1 ) ;
302
	    break ;
303
	}
304
	case exp_init_tag : {
305
	    IDENTIFIER id ;
306
	    DESTROY_exp_init ( destroy, t, id, a, e ) ;
307
	    if ( force == 2 ) {
308
		DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
309
		if ( ds & dspec_temp ) {
310
		    /* Remove temporary variable */
311
		    ds |= dspec_ignore ;
312
		    COPY_dspec ( id_storage ( id ), ds ) ;
313
		}
314
	    }
315
	    free_exp ( a, force1 ) ;
316
	    break ;
317
	}
318
	case exp_preinc_tag : {
319
	    int bc ;
320
	    DESTROY_exp_preinc ( destroy, t, a, b, bc, e ) ;
321
	    free_exp ( b, force1 ) ;
322
	    UNUSED ( bc ) ;
323
	    UNUSED ( a ) ;
324
	    break ;
325
	}
326
	case exp_postinc_tag : {
327
	    EXP c ;
328
	    DESTROY_exp_postinc ( destroy, t, a, b, c, e ) ;
329
	    free_exp ( c, force1 ) ;
330
	    UNUSED ( a ) ;
331
	    UNUSED ( b ) ;
332
	    break ;
333
	}
334
	case exp_indir_tag : {
335
	    int i ;
336
	    DESTROY_exp_indir ( destroy, t, a, i, e ) ;
337
	    free_exp ( a, force1 ) ;
338
	    UNUSED ( i ) ;
339
	    break ;
340
	}
341
	case exp_contents_tag : {
342
	    DESTROY_exp_contents ( destroy, t, a, e ) ;
343
	    free_exp ( a, force1 ) ;
344
	    break ;
345
	}
346
	case exp_address_tag : {
347
	    DESTROY_exp_address ( destroy, t, a, e ) ;
348
	    free_exp ( a, force1 ) ;
349
	    break ;
350
	}
351
	case exp_address_mem_tag : {
352
	    int paren ;
353
	    DESTROY_exp_address_mem ( destroy, t, a, paren, e ) ;
354
	    UNUSED ( paren ) ;
355
	    free_exp ( a, force1 ) ;
356
	    break ;
357
	}
358
	case exp_func_tag : {
359
	    unsigned n ;
360
	    LIST ( EXP ) p ;
361
	    DESTROY_exp_func ( destroy, t, a, p, n, e ) ;
362
	    free_exp_list ( p, force1 ) ;
363
	    free_exp ( a, force1 ) ;
364
	    UNUSED ( n ) ;
365
	    break ;
366
	}
367
	case exp_func_id_tag : {
368
	    unsigned n ;
369
	    IDENTIFIER id ;
370
	    LIST ( EXP ) p ;
371
	    DESTROY_exp_func_id ( destroy, t, id, p, b, n, e ) ;
372
	    free_exp_list ( p, force1 ) ;
373
	    UNUSED ( id ) ;
374
	    UNUSED ( b ) ;
375
	    UNUSED ( n ) ;
376
	    break ;
377
	}
378
	case exp_call_tag : {
379
	    GRAPH gr ;
380
	    DESTROY_exp_call ( destroy, t, a, b, gr, e ) ;
381
	    free_exp ( a, force1 ) ;
382
	    free_exp ( b, force1 ) ;
383
	    UNUSED ( gr ) ;
384
	    break ;
385
	}
386
	case exp_negate_tag :
387
	case exp_compl_tag :
388
	case exp_not_tag :
389
	case exp_abs_tag : {
390
	    DESTROY_exp_negate_etc ( destroy, t, a, e ) ;
391
	    free_exp ( a, force1 ) ;
392
	    break ;
393
	}
394
	case exp_plus_tag :
395
	case exp_minus_tag :
396
	case exp_mult_tag :
397
	case exp_div_tag :
398
	case exp_rem_tag :
399
	case exp_and_tag :
400
	case exp_or_tag :
401
	case exp_xor_tag :
402
	case exp_log_and_tag :
403
	case exp_log_or_tag :
404
	case exp_lshift_tag :
405
	case exp_rshift_tag :
406
	case exp_max_tag :
407
	case exp_min_tag : {
408
	    DESTROY_exp_plus_etc ( destroy, t, a, b, e ) ;
409
	    free_exp ( a, force1 ) ;
410
	    free_exp ( b, force1 ) ;
411
	    break ;
412
	}
413
	case exp_test_tag : {
414
	    NTEST tst ;
415
	    DESTROY_exp_test ( destroy, t, tst, a, e ) ;
416
	    free_exp ( a, force1 ) ;
417
	    UNUSED ( tst ) ;
418
	    break ;
419
	}
420
	case exp_compare_tag : {
421
	    NTEST tst ;
422
	    DESTROY_exp_compare ( destroy, t, tst, a, b, e ) ;
423
	    free_exp ( a, force1 ) ;
424
	    free_exp ( b, force1 ) ;
425
	    UNUSED ( tst ) ;
426
	    break ;
427
	}
428
	case exp_cast_tag : {
429
	    unsigned conv ;
430
	    DESTROY_exp_cast ( destroy, t, conv, a, e ) ;
431
	    free_exp ( a, force1 ) ;
432
	    UNUSED ( conv ) ;
433
	    break ;
434
	}
435
	case exp_base_cast_tag : {
436
	    OFFSET off ;
437
	    unsigned conv ;
438
	    DESTROY_exp_base_cast ( destroy, t, conv, a, off, e ) ;
439
	    free_exp ( a, force1 ) ;
440
	    free_offset ( off, force1 ) ;
441
	    UNUSED ( conv ) ;
442
	    break ;
443
	}
444
	case exp_dyn_cast_tag : {
445
	    DESTROY_exp_dyn_cast ( destroy, t, a, b, e ) ;
446
	    free_exp ( a, force1 ) ;
447
	    free_exp ( b, force1 ) ;
448
	    break ;
449
	}
450
	case exp_add_ptr_tag : {
451
	    int v ;
452
	    OFFSET off ;
453
	    DESTROY_exp_add_ptr ( destroy, t, a, off, v, e ) ;
454
	    free_exp ( a, force1 ) ;
455
	    free_offset ( off, force1 ) ;
456
	    UNUSED ( v ) ;
457
	    break ;
458
	}
459
	case exp_offset_size_tag : {
460
	    TYPE s ;
461
	    int pad ;
462
	    OFFSET off ;
463
	    DESTROY_exp_offset_size ( destroy, t, off, s, pad, e ) ;
464
	    free_offset ( off, force1 ) ;
465
	    UNUSED ( pad ) ;
466
	    UNUSED ( s ) ;
467
	    break ;
468
	}
469
	case exp_constr_tag : {
470
	    int i ;
471
	    EXP c ;
472
	    DESTROY_exp_constr ( destroy, t, a, b, c, i, e ) ;
473
	    free_exp ( a, force1 ) ;
474
	    UNUSED ( b ) ;
475
	    UNUSED ( c ) ;
476
	    UNUSED ( i ) ;
477
	    break ;
478
	}
479
	case exp_destr_tag : {
480
	    EXP c ;
481
	    DESTROY_exp_destr ( destroy, t, a, b, c, e ) ;
482
	    free_exp ( a, force1 ) ;
483
	    free_exp ( c, force1 ) ;
484
	    UNUSED ( b ) ;
485
	    break ;
486
	}
487
	case exp_alloc_tag : {
488
	    EXP c, d ;
489
	    DESTROY_exp_alloc ( destroy, t, a, b, c, d, e ) ;
490
	    free_exp ( a, force1 ) ;
491
	    free_exp ( b, force1 ) ;
492
	    free_exp ( c, force1 ) ;
493
	    UNUSED ( d ) ;
494
	    break ;
495
	}
496
	case exp_dealloc_tag : {
497
	    EXP c, d ;
498
	    DESTROY_exp_dealloc ( destroy, t, a, b, c, d, e ) ;
499
	    free_exp ( a, force1 ) ;
500
	    free_exp ( b, force1 ) ;
501
	    free_exp ( d, force1 ) ;
502
	    UNUSED ( c ) ;
503
	    break ;
504
	}
505
	case exp_rtti_tag : {
506
	    int op ;
507
	    DESTROY_exp_rtti ( destroy, t, a, b, op, e ) ;
508
	    free_exp ( a, force1 ) ;
509
	    free_exp ( b, force1 ) ;
510
	    UNUSED ( op ) ;
511
	    break ;
512
	}
513
	case exp_rtti_type_tag : {
514
	    int op ;
515
	    TYPE s ;
516
	    DESTROY_exp_rtti_type ( destroy, t, s, op, e ) ;
517
	    UNUSED ( s ) ;
518
	    UNUSED ( op ) ;
519
	    break ;
520
	}
521
	case exp_rtti_no_tag : {
522
	    TYPE s ;
523
	    DESTROY_exp_rtti_no ( destroy, t, s, e ) ;
524
	    UNUSED ( s ) ;
525
	    break ;
526
	}
527
	case exp_dynamic_tag : {
528
	    DESTROY_exp_dynamic ( destroy, t, a, e ) ;
529
	    free_exp ( a, force1 ) ;
530
	    break ;
531
	}
532
	case exp_aggregate_tag : {
533
	    LIST ( EXP ) p ;
534
	    LIST ( OFFSET ) q ;
535
	    DESTROY_exp_aggregate ( destroy, t, p, q, e ) ;
536
	    DESTROY_list ( q, SIZE_off ) ;
537
	    free_exp_list ( p, force1 ) ;
538
	    break ;
539
	}
540
	case exp_initialiser_tag : {
541
	    int n ;
542
	    LIST ( EXP ) p ;
543
	    unsigned nv, nb ;
544
	    LIST ( OFFSET ) q ;
545
	    DESTROY_exp_initialiser ( destroy, t, p, q, n, nv, nb, e ) ;
546
	    DESTROY_list ( q, SIZE_off ) ;
547
	    free_exp_list ( p, force1 ) ;
548
	    UNUSED ( nv ) ;
549
	    UNUSED ( nb ) ;
550
	    UNUSED ( n ) ;
551
	    break ;
552
	}
553
	case exp_nof_tag : {
554
	    NAT n ;
555
	    EXP c ;
556
	    DESTROY_exp_nof ( destroy, t, a, n, b, c, e ) ;
557
	    free_exp ( a, force1 ) ;
558
	    free_exp ( b, force1 ) ;
559
	    free_exp ( c, force1 ) ;
560
	    UNUSED ( n ) ;
561
	    break ;
562
	}
563
	case exp_comma_tag : {
564
	    LIST ( EXP ) p ;
565
	    DESTROY_exp_comma ( destroy, t, p, e ) ;
566
	    free_exp_list ( p, force1 ) ;
567
	    break ;
568
	}
569
	case exp_set_tag :
570
	case exp_unused_tag : {
571
	    DESTROY_exp_set_etc ( destroy, t, a, e ) ;
572
	    free_exp ( a, force1 ) ;
573
	    break ;
574
	}
575
	case exp_reach_tag :
576
	case exp_unreach_tag : {
577
	    DESTROY_exp_reach_etc ( destroy, t, a, b, e ) ;
578
	    free_exp ( b, force1 ) ;
579
	    UNUSED ( a ) ;
580
	    break ;
581
	}
582
	case exp_sequence_tag : {
583
	    int bl ;
584
	    NAMESPACE ns ;
585
	    LIST ( EXP ) p, q ;
586
	    DESTROY_exp_sequence ( destroy, t, a, p, q, ns, bl, e ) ;
587
	    if ( force ) free_nspace ( ns ) ;
588
	    free_exp_list ( p, force1 ) ;
589
	    UNUSED ( bl ) ;
590
	    UNUSED ( q ) ;
591
	    UNUSED ( a ) ;
592
	    break ;
593
	}
594
	case exp_solve_stmt_tag : {
595
	    LIST ( IDENTIFIER ) lb ;
596
	    LIST ( IDENTIFIER ) vr ;
597
	    DESTROY_exp_solve_stmt ( destroy, t, a, b, lb, vr, e ) ;
598
	    DESTROY_list ( lb, SIZE_id ) ;
599
	    DESTROY_list ( vr, SIZE_id ) ;
600
	    free_exp ( b, force ) ;
601
	    UNUSED ( a ) ;
602
	    break ;
603
	}
604
	case exp_decl_stmt_tag : {
605
	    IDENTIFIER id ;
606
	    DESTROY_exp_decl_stmt ( destroy, t, a, id, b, e ) ;
607
	    free_exp ( b, force ) ;
608
	    free_id ( id, force ) ;
609
	    UNUSED ( a ) ;
610
	    break ;
611
	}
612
	case exp_if_stmt_tag : {
613
	    EXP c, d ;
614
	    IDENTIFIER lb ;
615
	    DESTROY_exp_if_stmt ( destroy, t, a, b, c, d, lb, e ) ;
616
	    free_exp ( b, force1 ) ;
617
	    free_exp ( c, force1 ) ;
618
	    free_exp ( d, force1 ) ;
619
	    free_id ( lb, force1 ) ;
620
	    UNUSED ( a ) ;
621
	    break ;
622
	}
623
	case exp_while_stmt_tag : {
624
	    EXP c ;
625
	    IDENTIFIER bk, ct, lp ;
626
	    LIST ( IDENTIFIER ) cn ;
627
	    DESTROY_exp_while_stmt ( destroy, t, a, b, c, bk, ct, lp, cn, e ) ;
628
	    DESTROY_list ( cn, SIZE_id ) ;
629
	    free_exp ( b, force1 ) ;
630
	    free_exp ( c, force1 ) ;
631
	    free_id ( bk, force1 ) ;
632
	    free_id ( ct, force1 ) ;
633
	    free_id ( lp, force1 ) ;
634
	    UNUSED ( a ) ;
635
	    break ;
636
	}
637
	case exp_do_stmt_tag : {
638
	    EXP c ;
639
	    IDENTIFIER bk, ct, lp ;
640
	    DESTROY_exp_do_stmt ( destroy, t, a, b, c, bk, ct, lp, e ) ;
641
	    free_exp ( b, force1 ) ;
642
	    free_exp ( c, force1 ) ;
643
	    free_id ( bk, force1 ) ;
644
	    free_id ( ct, force1 ) ;
645
	    free_id ( lp, force1 ) ;
646
	    UNUSED ( a ) ;
647
	    break ;
648
	}
649
	case exp_switch_stmt_tag : {
650
	    EXP c ;
651
	    int ex ;
652
	    LIST ( NAT ) p ;
653
	    IDENTIFIER df, bk ;
654
	    LIST ( IDENTIFIER ) q ;
655
	    DESTROY_exp_switch_stmt ( destroy, t, a, b, c, p, q,
656
				      df, ex, bk, e ) ;
657
	    free_exp ( b, force1 ) ;
658
	    free_exp ( c, force1 ) ;
659
	    free_id ( df, force1 ) ;
660
	    free_id ( bk, force1 ) ;
661
	    DESTROY_list ( p, SIZE_nat ) ;
662
	    DESTROY_list ( q, SIZE_id ) ;
663
	    UNUSED ( ex ) ;
664
	    UNUSED ( a ) ;
665
	    break ;
666
	}
667
	case exp_hash_if_tag : {
668
	    EXP c, d, f ;
669
	    DESTROY_exp_hash_if ( destroy, t, a, b, c, d, f, e ) ;
670
	    free_exp ( c, force1 ) ;
671
	    free_exp ( d, force1 ) ;
672
	    UNUSED ( f ) ;
673
	    UNUSED ( a ) ;
674
	    UNUSED ( b ) ;
675
	    break ;
676
	}
677
	case exp_return_stmt_tag : {
678
	    DESTROY_exp_return_stmt ( destroy, t, a, b, e ) ;
679
	    free_exp ( b, force1 ) ;
680
	    UNUSED ( a ) ;
681
	    break ;
682
	}
683
	case exp_goto_stmt_tag : {
684
	    EXP c ;
685
	    IDENTIFIER lb ;
686
	    DESTROY_exp_goto_stmt ( destroy, t, a, lb, b, c, e ) ;
687
	    free_id ( lb, force1 ) ;
688
	    UNUSED ( c ) ;
689
	    UNUSED ( b ) ;
690
	    UNUSED ( a ) ;
691
	    break ;
692
	}
693
	case exp_label_stmt_tag : {
694
	    IDENTIFIER lb ;
695
	    IDENTIFIER nt ;
696
	    DESTROY_exp_label_stmt ( destroy, t, a, lb, b, nt, e ) ;
697
	    free_id ( lb, force1 ) ;
698
	    free_exp ( b, force1 ) ;
699
	    UNUSED ( nt ) ;
700
	    UNUSED ( a ) ;
701
	    break ;
702
	}
703
	case exp_try_block_tag : {
704
	    int f ;
705
	    EXP c ;
706
	    ulong n ;
707
	    LIST ( EXP ) p ;
708
	    LIST ( TYPE ) q, r ;
709
	    LIST ( LOCATION ) s ;
710
	    LIST ( TYPE ) u = univ_type_set ;
711
	    LIST ( TYPE ) v = empty_type_set ;
712
	    DESTROY_exp_try_block ( destroy, t, a, b, f, p, q, c, r, s, n, e ) ;
713
	    if ( !EQ_list ( q, r ) ) {
714
		if ( !EQ_list ( q, u ) && !EQ_list ( q, v ) ) {
715
		    DESTROY_list ( q, SIZE_type ) ;
716
		}
717
	    }
718
	    if ( !EQ_list ( r, u ) && !EQ_list ( r, v ) ) {
719
		DESTROY_list ( r, SIZE_type ) ;
720
	    }
721
	    DESTROY_list ( s, SIZE_loc ) ;
722
	    free_exp_list ( p, force1 ) ;
723
	    free_exp ( b, force ) ;
724
	    free_exp ( c, force1 ) ;
725
	    UNUSED ( f ) ;
726
	    UNUSED ( n ) ;
727
	    UNUSED ( a ) ;
728
	    break ;
729
	}
730
	case exp_handler_tag : {
731
	    ulong n ;
732
	    IDENTIFIER id ;
733
	    DESTROY_exp_handler ( destroy, t, a, id, b, n, e ) ;
734
	    free_exp ( b, force1 ) ;
735
	    free_id ( id, force1 ) ;
736
	    UNUSED ( n ) ;
737
	    UNUSED ( a ) ;
738
	    break ;
739
	}
740
	case exp_exception_tag : {
741
	    int d ;
742
	    EXP c ;
743
	    DESTROY_exp_exception ( destroy, t, a, b, c, d, e ) ;
744
	    free_exp ( a, force1 ) ;
745
	    free_exp ( b, force1 ) ;
746
	    free_exp ( c, force1 ) ;
747
	    UNUSED ( d ) ;
748
	    break ;
749
	}
750
	case exp_thrown_tag : {
751
	    int d ;
752
	    DESTROY_exp_thrown ( destroy, t, d, e ) ;
753
	    UNUSED ( d ) ;
754
	    break ;
755
	}
756
	case exp_op_tag : {
757
	    int op ;
758
	    DESTROY_exp_op ( destroy, t, op, a, b, e ) ;
759
	    free_exp ( a, force1 ) ;
760
	    free_exp ( b, force1 ) ;
761
	    UNUSED ( op ) ;
762
	    break ;
763
	}
764
	case exp_opn_tag : {
765
	    int op ;
766
	    LIST ( EXP ) p ;
767
	    DESTROY_exp_opn ( destroy, t, op, p, e ) ;
768
	    free_exp_list ( p, force1 ) ;
769
	    UNUSED ( op ) ;
770
	    break ;
771
	}
772
	case exp_assembler_tag : {
773
	    STRING s ;
774
	    LIST ( EXP ) p ;
775
	    DESTROY_exp_assembler ( destroy, t, s, p, e ) ;
776
	    free_exp_list ( p, force1 ) ;
777
	    UNUSED ( s ) ;
778
	    break ;
779
	}
780
	case exp_uncompiled_tag : {
781
	    PPTOKEN *p ;
782
	    LOCATION loc ;
783
	    DESTROY_exp_uncompiled ( destroy, t, loc, p, e ) ;
784
	    free_tok_list ( p ) ;
785
	    UNUSED ( loc ) ;
786
	    break ;
787
	}
788
	case exp_location_tag : {
789
	    LOCATION loc ;
790
	    DESTROY_exp_location ( destroy, t, loc, a, e ) ;
791
	    free_exp ( a, force1 ) ;
792
	    UNUSED ( loc ) ;
793
	    break ;
794
	}
795
	case exp_fail_tag : {
796
	    string s ;
797
	    DESTROY_exp_fail ( destroy, t, s, e ) ;
798
	    UNUSED ( s ) ;
799
	    break ;
800
	}
801
	case exp_token_tag : {
802
	    IDENTIFIER id ;
803
	    LIST ( TOKEN ) p ;
804
	    DESTROY_exp_token ( destroy, t, a, id, p, e ) ;
805
	    UNUSED ( id ) ;
806
	    UNUSED ( p ) ;
807
	    UNUSED ( a ) ;
808
	    break ;
809
	}
810
	case exp_dummy_tag : {
811
	    int v ;
812
	    ulong n ;
813
	    int cnt ;
814
	    OFFSET off ;
815
	    DESTROY_exp_dummy ( destroy, t, a, n, off, v, cnt, e ) ;
816
	    free_exp ( a, force1 ) ;
817
	    free_offset ( off, force1 ) ;
818
	    UNUSED ( cnt ) ;
819
	    UNUSED ( n ) ;
820
	    UNUSED ( v ) ;
821
	    break ;
822
	}
823
    }
824
    UNUSED ( t ) ;
825
    return ;
826
}
827
 
828
 
829
/*
830
    FREE A FUNCTION DEFINITION
831
 
832
    This routine frees the definition of the function id, replacing it
833
    by a dummy definition.
834
*/
835
 
836
void free_function
837
    PROTO_N ( ( id ) )
838
    PROTO_T ( IDENTIFIER id )
839
{
840
    EXP e = DEREF_exp ( id_function_etc_defn ( id ) ) ;
841
    if ( !IS_NULL_exp ( e ) ) {
842
	TYPE t = DEREF_type ( id_function_etc_type ( id ) ) ;
843
	free_exp ( e, 0 ) ;
844
	MAKE_exp_value ( t, e ) ;
845
	COPY_exp ( id_function_etc_defn ( id ), e ) ;
846
    }
847
    return ;
848
}