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 "hashid_ops.h"
35
#include "id_ops.h"
36
#include "inst_ops.h"
37
#include "member_ops.h"
38
#include "nspace_ops.h"
39
#include "off_ops.h"
40
#include "type_ops.h"
41
#include "virt_ops.h"
42
#include "error.h"
43
#include "catalog.h"
44
#include "buffer.h"
45
#include "capsule.h"
46
#include "char.h"
47
#include "debug.h"
48
#include "encode.h"
49
#include "file.h"
50
#include "hash.h"
51
#include "label.h"
52
#include "lex.h"
53
#include "mangle.h"
54
#include "operator.h"
55
#include "option.h"
56
#include "print.h"
57
#include "syntax.h"
58
#include "unmangle.h"
59
#include "ustring.h"
60
#ifdef RUNTIME
61
 
62
 
63
/*
64
    EXTENDED DEBUGGING FLAG
65
 
66
    This flag enables the extended debug printing routines.
67
*/
68
 
69
int debugging = 0 ;
70
 
71
 
72
/*
73
    EXTENDED OFFSET PRINTING
74
 
75
    This routine deals with those cases in print_offset which are only
76
    output in debugging mode.
77
*/
78
 
79
int print_offset_aux
80
    PROTO_N ( ( off, bf, sp ) )
81
    PROTO_T ( OFFSET off X BUFFER *bf X int sp )
82
{
83
    if ( !IS_NULL_off ( off ) ) {
84
	switch ( TAG_off ( off ) ) {
85
	    case off_type_tag : {
86
		TYPE t = DEREF_type ( off_type_type ( off ) ) ;
87
		sp = print_type ( t, bf, sp ) ;
88
		break ;
89
	    }
90
	    default : {
91
		sp = print_lex ( lex_member_Hcap, bf, sp ) ;
92
		break ;
93
	    }
94
	}
95
    }
96
    return ( sp ) ;
97
}
98
 
99
 
100
/*
101
    PRINT A UNARY OPERATION
102
 
103
    This routine prints the unary operation 'op a' to the buffer bf.
104
*/
105
 
106
static int print_unary
107
    PROTO_N ( ( a, op, bf, sp ) )
108
    PROTO_T ( EXP a X int op X BUFFER *bf X int sp )
109
{
110
    IGNORE print_lex ( op, bf, sp ) ;
111
    sp = print_exp ( a, 1, bf, 0 ) ;
112
    return ( sp ) ;
113
}
114
 
115
 
116
/*
117
    PRINT A BINARY OPERATION
118
 
119
    This routine prints the binary operation 'a op b' to the buffer bf.
120
*/
121
 
122
static int print_binary
123
    PROTO_N ( ( a, b, op, bf, sp ) )
124
    PROTO_T ( EXP a X EXP b X int op X BUFFER *bf X int sp )
125
{
126
    sp = print_exp ( a, 1, bf, sp ) ;
127
    sp = print_lex ( op, bf, sp ) ;
128
    sp = print_exp ( b, 1, bf, sp ) ;
129
    return ( sp ) ;
130
}
131
 
132
 
133
/*
134
    PRINT A CAST OPERATION
135
 
136
    This routine prints the cast operation 'op < t > ( a )' to the
137
    buffer bf.
138
*/
139
 
140
static int print_cast
141
    PROTO_N ( ( t, a, op, bf, sp ) )
142
    PROTO_T ( TYPE t X EXP a X int op X BUFFER *bf X int sp )
143
{
144
    sp = print_lex ( op, bf, sp ) ;
145
    sp = print_lex ( lex_less, bf, sp ) ;
146
    sp = print_type ( t, bf, sp ) ;
147
    sp = print_lex ( lex_greater, bf, sp ) ;
148
    sp = print_exp ( a, 1, bf, sp ) ;
149
    return ( sp ) ;
150
}
151
 
152
 
153
/*
154
    PRINT A LIST OF EXPRESSIONS
155
 
156
    This routine prints the list of expressions p, enclosed in brackets,
157
    to the buffer bf.
158
*/
159
 
160
static int print_exp_list
161
    PROTO_N ( ( p, bf, sp ) )
162
    PROTO_T ( LIST ( EXP ) p X BUFFER *bf X int sp )
163
{
164
    sp = print_lex ( lex_open_Hround, bf, sp ) ;
165
    if ( IS_NULL_list ( p ) ) {
166
	sp = 0 ;
167
    } else {
168
	while ( !IS_NULL_list ( p ) ) {
169
	    EXP a = DEREF_exp ( HEAD_list ( p ) ) ;
170
	    sp = print_exp ( a, 1, bf, sp ) ;
171
	    bfputc ( bf, ',' ) ;
172
	    p = TAIL_list ( p ) ;
173
	}
174
    }
175
    sp = print_lex ( lex_close_Hround, bf, sp ) ;
176
    return ( sp ) ;
177
}
178
 
179
 
180
/*
181
    EXTENDED EXPRESSION PRINTING
182
 
183
    This routine deals with those cases in print_exp which are only
184
    output in debugging mode.
185
*/
186
 
187
int print_exp_aux
188
    PROTO_N ( ( e, paren, bf, sp ) )
189
    PROTO_T ( EXP e X int paren X BUFFER *bf X int sp )
190
{
191
    if ( !IS_NULL_exp ( e ) ) {
192
	ASSERT ( ORDER_exp == 88 ) ;
193
	if ( paren ) sp = print_lex ( lex_open_Hround, bf, sp ) ;
194
	switch ( TAG_exp ( e ) ) {
195
	    case exp_paren_tag : {
196
		EXP a = DEREF_exp ( exp_paren_arg ( e ) ) ;
197
		sp = print_exp ( a, !paren, bf, sp ) ;
198
		break ;
199
	    }
200
	    case exp_copy_tag : {
201
		EXP a = DEREF_exp ( exp_copy_arg ( e ) ) ;
202
		sp = print_exp ( a, 0, bf, sp ) ;
203
		break ;
204
	    }
205
	    case exp_assign_tag : {
206
		EXP a = DEREF_exp ( exp_assign_ref ( e ) ) ;
207
		EXP b = DEREF_exp ( exp_assign_arg ( e ) ) ;
208
		sp = print_binary ( a, b, lex_assign, bf, sp ) ;
209
		break ;
210
	    }
211
	    case exp_init_tag : {
212
		IDENTIFIER id = DEREF_id ( exp_init_id ( e ) ) ;
213
		EXP a = DEREF_exp ( exp_init_arg ( e ) ) ;
214
		sp = print_id_short ( id, qual_none, bf, sp ) ;
215
		sp = print_lex ( lex_assign, bf, sp ) ;
216
		sp = print_exp ( a, 0, bf, sp ) ;
217
		break ;
218
	    }
219
	    case exp_preinc_tag : {
220
		EXP a = DEREF_exp ( exp_preinc_ref ( e ) ) ;
221
		EXP b = DEREF_exp ( exp_preinc_op ( e ) ) ;
222
		sp = print_binary ( a, b, lex_assign, bf, sp ) ;
223
		break ;
224
	    }
225
	    case exp_postinc_tag : {
226
		EXP a = DEREF_exp ( exp_postinc_ref ( e ) ) ;
227
		EXP b = DEREF_exp ( exp_postinc_op ( e ) ) ;
228
		sp = print_binary ( a, b, lex_assign, bf, sp ) ;
229
		break ;
230
	    }
231
	    case exp_indir_tag : {
232
		EXP a = DEREF_exp ( exp_indir_ptr ( e ) ) ;
233
		sp = print_unary ( a, lex_star, bf, sp ) ;
234
		break ;
235
	    }
236
	    case exp_address_tag : {
237
		EXP a = DEREF_exp ( exp_address_arg ( e ) ) ;
238
		sp = print_unary ( a, lex_and_H1, bf, sp ) ;
239
		break ;
240
	    }
241
	    case exp_address_mem_tag : {
242
		EXP a = DEREF_exp ( exp_address_mem_arg ( e ) ) ;
243
		sp = print_unary ( a, lex_and_H1, bf, sp ) ;
244
		break ;
245
	    }
246
	    case exp_func_tag : {
247
		EXP a = DEREF_exp ( exp_func_fn ( e ) ) ;
248
		LIST ( EXP ) p = DEREF_list ( exp_func_args ( e ) ) ;
249
		sp = print_exp ( a, 1, bf, sp ) ;
250
		sp = print_exp_list ( p, bf, sp ) ;
251
		break ;
252
	    }
253
	    case exp_func_id_tag : {
254
		IDENTIFIER id = DEREF_id ( exp_func_id_id ( e ) ) ;
255
		LIST ( EXP ) p = DEREF_list ( exp_func_id_args ( e ) ) ;
256
		sp = print_id_short ( id, qual_none, bf, sp ) ;
257
		sp = print_exp_list ( p, bf, sp ) ;
258
		break ;
259
	    }
260
	    case exp_call_tag : {
261
		EXP a = DEREF_exp ( exp_call_ptr ( e ) ) ;
262
		EXP b = DEREF_exp ( exp_call_arg ( e ) ) ;
263
		sp = print_binary ( a, b, lex_dot_Hstar, bf, sp ) ;
264
		break ;
265
	    }
266
	    case exp_negate_tag :
267
	    case exp_compl_tag :
268
	    case exp_not_tag :
269
	    case exp_abs_tag : {
270
		int op = op_token ( e, lex_unknown ) ;
271
		EXP a = DEREF_exp ( exp_negate_etc_arg ( e ) ) ;
272
		sp = print_unary ( a, op, bf, sp ) ;
273
		break ;
274
	    }
275
	    case exp_plus_tag :
276
	    case exp_minus_tag :
277
	    case exp_mult_tag :
278
	    case exp_div_tag :
279
	    case exp_rem_tag :
280
	    case exp_and_tag :
281
	    case exp_or_tag :
282
	    case exp_xor_tag :
283
	    case exp_log_and_tag :
284
	    case exp_log_or_tag :
285
	    case exp_lshift_tag :
286
	    case exp_rshift_tag :
287
	    case exp_max_tag :
288
	    case exp_min_tag : {
289
		int op = op_token ( e, lex_unknown ) ;
290
		EXP a = DEREF_exp ( exp_plus_etc_arg1 ( e ) ) ;
291
		EXP b = DEREF_exp ( exp_plus_etc_arg2 ( e ) ) ;
292
		sp = print_binary ( a, b, op, bf, sp ) ;
293
		break ;
294
	    }
295
	    case exp_test_tag : {
296
		int op = op_token ( e, lex_unknown ) ;
297
		EXP a = DEREF_exp ( exp_test_arg ( e ) ) ;
298
		sp = print_exp ( a, 1, bf, sp ) ;
299
		IGNORE print_lex ( op, bf, sp ) ;
300
		bfprintf ( bf, " 0" ) ;
301
		sp = 1 ;
302
		break ;
303
	    }
304
	    case exp_compare_tag : {
305
		int op = op_token ( e, lex_unknown ) ;
306
		EXP a = DEREF_exp ( exp_compare_arg1 ( e ) ) ;
307
		EXP b = DEREF_exp ( exp_compare_arg2 ( e ) ) ;
308
		sp = print_binary ( a, b, op, bf, sp ) ;
309
		break ;
310
	    }
311
	    case exp_cast_tag : {
312
		TYPE t = DEREF_type ( exp_type ( e ) ) ;
313
		EXP a = DEREF_exp ( exp_cast_arg ( e ) ) ;
314
		sp = print_cast ( t, a, lex_cast, bf, sp ) ;
315
		break ;
316
	    }
317
	    case exp_base_cast_tag : {
318
		TYPE t = DEREF_type ( exp_type ( e ) ) ;
319
		EXP a = DEREF_exp ( exp_base_cast_arg ( e ) ) ;
320
		sp = print_cast ( t, a, lex_cast, bf, sp ) ;
321
		break ;
322
	    }
323
	    case exp_dyn_cast_tag : {
324
		TYPE t = DEREF_type ( exp_type ( e ) ) ;
325
		EXP a = DEREF_exp ( exp_dyn_cast_arg ( e ) ) ;
326
		sp = print_cast ( t, a, lex_dynamic_Hcast, bf, sp ) ;
327
		break ;
328
	    }
329
	    case exp_add_ptr_tag : {
330
		EXP a = DEREF_exp ( exp_add_ptr_ptr ( e ) ) ;
331
		OFFSET off = DEREF_off ( exp_add_ptr_off ( e ) ) ;
332
		sp = print_exp ( a, 0, bf, sp ) ;
333
		sp = print_lex ( lex_plus, bf, sp ) ;
334
		sp = print_offset ( off, bf, sp ) ;
335
		break ;
336
	    }
337
	    case exp_offset_size_tag : {
338
		OFFSET off = DEREF_off ( exp_offset_size_off ( e ) ) ;
339
		TYPE t = DEREF_type ( exp_offset_size_step ( e ) ) ;
340
		sp = print_offset ( off, bf, sp ) ;
341
		sp = print_lex ( lex_div, bf, sp ) ;
342
		sp = print_type ( t, bf, sp ) ;
343
		break ;
344
	    }
345
	    case exp_constr_tag : {
346
		EXP a = DEREF_exp ( exp_constr_call ( e ) ) ;
347
		sp = print_exp ( a, 0, bf, sp ) ;
348
		break ;
349
	    }
350
	    case exp_destr_tag : {
351
		EXP a = DEREF_exp ( exp_destr_call ( e ) ) ;
352
		sp = print_exp ( a, 0, bf, sp ) ;
353
		break ;
354
	    }
355
	    case exp_alloc_tag : {
356
		EXP a = DEREF_exp ( exp_alloc_call ( e ) ) ;
357
		sp = print_exp ( a, 0, bf, sp ) ;
358
		break ;
359
	    }
360
	    case exp_dealloc_tag : {
361
		EXP a = DEREF_exp ( exp_dealloc_call ( e ) ) ;
362
		sp = print_exp ( a, 0, bf, sp ) ;
363
		break ;
364
	    }
365
	    case exp_rtti_tag : {
366
		EXP a = DEREF_exp ( exp_rtti_arg ( e ) ) ;
367
		int op = DEREF_int ( exp_rtti_op ( e ) ) ;
368
		sp = print_lex ( op, bf, sp ) ;
369
		sp = print_exp ( a, 1, bf, sp ) ;
370
		break ;
371
	    }
372
	    case exp_rtti_type_tag : {
373
		TYPE t = DEREF_type ( exp_rtti_type_arg ( e ) ) ;
374
		int op = DEREF_int ( exp_rtti_type_op ( e ) ) ;
375
		sp = print_lex ( op, bf, sp ) ;
376
		sp = print_type ( t, bf, sp ) ;
377
		break ;
378
	    }
379
	    case exp_rtti_no_tag : {
380
		TYPE t = DEREF_type ( exp_rtti_no_arg ( e ) ) ;
381
		sp = print_lex ( lex_typeid, bf, sp ) ;
382
		sp = print_type ( t, bf, sp ) ;
383
		break ;
384
	    }
385
	    case exp_dynamic_tag : {
386
		EXP a = DEREF_exp ( exp_dynamic_arg ( e ) ) ;
387
		sp = print_exp ( a, 0, bf, sp ) ;
388
		break ;
389
	    }
390
	    case exp_aggregate_tag : {
391
		LIST ( EXP ) p = DEREF_list ( exp_aggregate_args ( e ) ) ;
392
		sp = print_lex ( lex_initialization, bf, sp ) ;
393
		sp = print_exp_list ( p, bf, sp ) ;
394
		break ;
395
	    }
396
	    case exp_initialiser_tag : {
397
		LIST ( EXP ) p = DEREF_list ( exp_initialiser_args ( e ) ) ;
398
		sp = print_lex ( lex_initialization, bf, sp ) ;
399
		sp = print_exp_list ( p, bf, sp ) ;
400
		break ;
401
	    }
402
	    case exp_nof_tag : {
403
		EXP a = DEREF_exp ( exp_nof_start ( e ) ) ;
404
		EXP b = DEREF_exp ( exp_nof_pad ( e ) ) ;
405
		EXP c = DEREF_exp ( exp_nof_end ( e ) ) ;
406
		if ( !IS_NULL_exp ( a ) ) {
407
		    sp = print_exp ( a, 0, bf, sp ) ;
408
		    bfprintf ( bf, ", " ) ;
409
		}
410
		sp = print_exp ( b, 0, bf, sp ) ;
411
		bfprintf ( bf, ", ..." ) ;
412
		if ( !IS_NULL_exp ( c ) ) {
413
		    bfprintf ( bf, ", " ) ;
414
		    sp = print_exp ( c, 0, bf, sp ) ;
415
		}
416
		break ;
417
	    }
418
	    case exp_comma_tag : {
419
		LIST ( EXP ) p = DEREF_list ( exp_comma_args ( e ) ) ;
420
		sp = print_exp_list ( p, bf, sp ) ;
421
		break ;
422
	    }
423
	    case exp_set_tag : {
424
		EXP a = DEREF_exp ( exp_set_arg ( e ) ) ;
425
		sp = print_exp ( a, 0, bf, sp ) ;
426
		break ;
427
	    }
428
	    case exp_unused_tag : {
429
		EXP a = DEREF_exp ( exp_unused_arg ( e ) ) ;
430
		sp = print_exp ( a, 0, bf, sp ) ;
431
		break ;
432
	    }
433
	    case exp_if_stmt_tag : {
434
		EXP c = DEREF_exp ( exp_if_stmt_cond ( e ) ) ;
435
		EXP a = DEREF_exp ( exp_if_stmt_true_code ( e ) ) ;
436
		EXP b = DEREF_exp ( exp_if_stmt_false_code ( e ) ) ;
437
		sp = print_exp ( c, 1, bf, sp ) ;
438
		sp = print_lex ( lex_question, bf, sp ) ;
439
		sp = print_binary ( a, b, lex_colon, bf, sp ) ;
440
		break ;
441
	    }
442
	    case exp_exception_tag : {
443
		EXP a = DEREF_exp ( exp_exception_arg ( e ) ) ;
444
		sp = print_lex ( lex_throw, bf, sp ) ;
445
		sp = print_exp ( a, 1, bf, sp ) ;
446
		break ;
447
	    }
448
	    case exp_thrown_tag : {
449
		sp = print_lex ( lex_catch, bf, sp ) ;
450
		break ;
451
	    }
452
	    case exp_op_tag : {
453
		int op = DEREF_int ( exp_op_lex ( e ) ) ;
454
		EXP a = DEREF_exp ( exp_op_arg1 ( e ) ) ;
455
		EXP b = DEREF_exp ( exp_op_arg2 ( e ) ) ;
456
		if ( IS_NULL_exp ( b ) ) {
457
		    sp = print_unary ( a, op, bf, sp ) ;
458
		} else {
459
		    sp = print_binary ( a, b, op, bf, sp ) ;
460
		}
461
		break ;
462
	    }
463
	    case exp_opn_tag : {
464
		int op = DEREF_int ( exp_opn_lex ( e ) ) ;
465
		LIST ( EXP ) p = DEREF_list ( exp_opn_args ( e ) ) ;
466
		sp = print_lex ( op, bf, sp ) ;
467
		sp = print_exp_list ( p, bf, sp ) ;
468
		break ;
469
	    }
470
	    case exp_uncompiled_tag : {
471
		if ( sp ) bfputc ( bf, ' ' ) ;
472
		bfprintf ( bf, "..." ) ;
473
		sp = 1 ;
474
		break ;
475
	    }
476
	    case exp_fail_tag : {
477
		string s = DEREF_string ( exp_fail_msg ( e ) ) ;
478
		if ( sp ) bfputc ( bf, ' ' ) ;
479
		bfputs ( bf, s ) ;
480
		sp = 1 ;
481
		break ;
482
	    }
483
	    case exp_dummy_tag : {
484
		EXP a = DEREF_exp ( exp_dummy_value ( e ) ) ;
485
		if ( IS_NULL_exp ( a ) ) {
486
		    sp = print_lex ( lex_exp_Hcap, bf, sp ) ;
487
		} else {
488
		    sp = print_exp ( a, 0, bf, sp ) ;
489
		}
490
		break ;
491
	    }
492
	    default : {
493
		sp = print_lex ( lex_exp_Hcap, bf, sp ) ;
494
		break ;
495
	    }
496
	}
497
	if ( paren ) sp = print_lex ( lex_close_Hround, bf, sp ) ;
498
    }
499
    return ( sp ) ;
500
}
501
 
502
 
503
/*
504
    PRINT AN INDENTED STRING
505
 
506
    This routine prints an indentation of indent steps followed by the
507
    string text to the file f.
508
*/
509
 
510
static void print_indent
511
    PROTO_N ( ( indent, text, f ) )
512
    PROTO_T ( int indent X CONST char *text X FILE *f )
513
{
514
    while ( indent > 1 ) {
515
	fputc_v ( '\t', f ) ;
516
	indent -= 2 ;
517
    }
518
    if ( indent ) {
519
	unsigned long i = tab_width / 2 ;
520
	while ( i ) {
521
	    fputc_v ( ' ', f ) ;
522
	    i-- ;
523
	}
524
    }
525
    fputs_v ( text, f ) ;
526
    return ;
527
}
528
 
529
 
530
/*
531
    PRINT AN EXPRESSION
532
 
533
    This routine prints the expression e, enclosed in parentheses if paren
534
    is true and preceded by a space if sp is true, to the file f.
535
*/
536
 
537
static void print_expr
538
    PROTO_N ( ( e, paren, sp, f ) )
539
    PROTO_T ( EXP e X int paren X int sp X FILE *f )
540
{
541
    BUFFER *bf = clear_buffer ( &print_buff, f ) ;
542
    if ( paren ) sp = print_lex ( lex_open_Hround, bf, sp ) ;
543
    IGNORE print_exp ( e, 0, bf, sp ) ;
544
    if ( paren ) IGNORE print_lex ( lex_close_Hround, bf, sp ) ;
545
    output_buffer ( bf, 1 ) ;
546
    return ;
547
}
548
 
549
 
550
/*
551
    PRINT AN INTEGER CONSTANT
552
 
553
    This routine prints the integer constant n to the file f.
554
*/
555
 
556
static void print_nat_val
557
    PROTO_N ( ( n, f ) )
558
    PROTO_T ( NAT n X FILE *f )
559
{
560
    BUFFER *bf = clear_buffer ( &print_buff, f ) ;
561
    IGNORE print_nat ( n, 0, bf, 0 ) ;
562
    output_buffer ( bf, 1 ) ;
563
    return ;
564
}
565
 
566
 
567
/*
568
    PRINT A DECLARATION
569
 
570
    This routine prints the declaration id to the file f.
571
*/
572
 
573
static void print_decl
574
    PROTO_N ( ( id, f ) )
575
    PROTO_T ( IDENTIFIER id X FILE *f )
576
{
577
    EXP e ;
578
    BUFFER *bf = clear_buffer ( &print_buff, f ) ;
579
    print_id_desc++ ;
580
    IGNORE print_id_long ( id, qual_none, bf, 0 ) ;
581
    print_id_desc-- ;
582
    e = DEREF_exp ( id_variable_init ( id ) ) ;
583
    if ( !IS_NULL_exp ( e ) ) {
584
	bfprintf ( bf, " = " ) ;
585
	IGNORE print_exp ( e, 0, bf, 0 ) ;
586
    }
587
    output_buffer ( bf, 1 ) ;
588
    return ;
589
}
590
 
591
 
592
/*
593
    PRINT A LABEL
594
 
595
    This routine prints the label lab to the file f.
596
*/
597
 
598
static void print_label
599
    PROTO_N ( ( lab, f ) )
600
    PROTO_T ( IDENTIFIER lab X FILE *f )
601
{
602
    int op = DEREF_int ( id_label_op ( lab ) ) ;
603
    if ( op == lex_identifier ) {
604
	HASHID nm = DEREF_hashid ( id_name ( lab ) ) ;
605
	if ( IS_hashid_name_etc ( nm ) ) {
606
	    string s = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
607
	    fputs_v ( strlit ( s ), f ) ;
608
	} else {
609
	    fputs_v ( "????", f ) ;
610
	}
611
    } else if ( op == lex_case ) {
612
	NAT n = find_case_nat ( lab ) ;
613
	fputs_v ( "case ", f ) ;
614
	print_nat_val ( n, f ) ;
615
    } else {
616
	fputs_v ( token_names [ op ], f ) ;
617
    }
618
    return ;
619
}
620
 
621
 
622
/*
623
    PRINT A STATEMENT
624
 
625
    This routine prints the statement e at an indentation of indent to the
626
    file f.  block is false to suppress braces around compound statements.
627
*/
628
 
629
static void print_stmt
630
    PROTO_N ( ( e, indent, block, f ) )
631
    PROTO_T ( EXP e X int indent X int block X FILE *f )
632
{
633
    if ( IS_NULL_exp ( e ) ) {
634
	/* Empty statements */
635
	print_indent ( indent, ";\n", f ) ;
636
	return ;
637
    }
638
    ASSERT ( ORDER_exp == 88 ) ;
639
    switch ( TAG_exp ( e ) ) {
640
	case exp_sequence_tag : {
641
	    /* Compound statements */
642
	    LIST ( EXP ) p = DEREF_list ( exp_sequence_first ( e ) ) ;
643
	    p = TAIL_list ( p ) ;
644
	    if ( block ) print_indent ( indent, "{\n", f ) ;
645
	    while ( !IS_NULL_list ( p ) ) {
646
		EXP a = DEREF_exp ( HEAD_list ( p ) ) ;
647
		print_stmt ( a, indent + block, 1, f ) ;
648
		p = TAIL_list ( p ) ;
649
	    }
650
	    if ( block ) print_indent ( indent, "}\n", f ) ;
651
	    break ;
652
	}
653
	case exp_solve_stmt_tag : {
654
	    /* Solve statements */
655
	    EXP a = DEREF_exp ( exp_solve_stmt_body ( e ) ) ;
656
	    print_stmt ( a, indent, block, f ) ;
657
	    break ;
658
	}
659
	case exp_decl_stmt_tag : {
660
	    /* Declaration statements */
661
	    EXP a = DEREF_exp ( exp_decl_stmt_body ( e ) ) ;
662
	    IDENTIFIER id = DEREF_id ( exp_decl_stmt_id ( e ) ) ;
663
	    print_indent ( indent, "", f ) ;
664
	    print_decl ( id, f ) ;
665
	    fputs_v ( " : {\n", f ) ;
666
	    print_stmt ( a, indent + 1, 0, f ) ;
667
	    print_indent ( indent, "}\n", f ) ;
668
	    break ;
669
	}
670
	case exp_if_stmt_tag : {
671
	    /* Conditional statements */
672
	    EXP c = DEREF_exp ( exp_if_stmt_cond ( e ) ) ;
673
	    EXP a = DEREF_exp ( exp_if_stmt_true_code ( e ) ) ;
674
	    EXP b = DEREF_exp ( exp_if_stmt_false_code ( e ) ) ;
675
	    print_indent ( indent, "if ", f ) ;
676
	    print_expr ( c, 1, 0, f ) ;
677
	    fputs_v ( " {\n", f ) ;
678
	    print_stmt ( a, indent + 1, 0, f ) ;
679
	    if ( !IS_NULL_exp ( b ) ) {
680
		print_indent ( indent, "} else {\n", f ) ;
681
		print_stmt ( b, indent + 1, 0, f ) ;
682
	    }
683
	    print_indent ( indent, "}\n", f ) ;
684
	    break ;
685
	}
686
	case exp_while_stmt_tag : {
687
	    /* While statements */
688
	    EXP c = DEREF_exp ( exp_while_stmt_cond ( e ) ) ;
689
	    EXP a = DEREF_exp ( exp_while_stmt_body ( e ) ) ;
690
	    IDENTIFIER blab = DEREF_id ( exp_while_stmt_break_lab ( e ) ) ;
691
	    IDENTIFIER clab = DEREF_id ( exp_while_stmt_cont_lab ( e ) ) ;
692
	    EXP bs = DEREF_exp ( id_label_stmt ( blab ) ) ;
693
	    EXP cs = DEREF_exp ( id_label_stmt ( clab ) ) ;
694
	    print_indent ( indent, "while ", f ) ;
695
	    print_expr ( c, 1, 0, f ) ;
696
	    fputs_v ( " {\n", f ) ;
697
	    print_stmt ( a, indent + 1, 0, f ) ;
698
	    print_stmt ( cs, indent + 1, 0, f ) ;
699
	    print_indent ( indent, "}\n", f ) ;
700
	    print_stmt ( bs, indent, 0, f ) ;
701
	    break ;
702
	}
703
	case exp_do_stmt_tag : {
704
	    /* Do statements */
705
	    EXP c = DEREF_exp ( exp_do_stmt_cond ( e ) ) ;
706
	    EXP a = DEREF_exp ( exp_do_stmt_body ( e ) ) ;
707
	    IDENTIFIER blab = DEREF_id ( exp_do_stmt_break_lab ( e ) ) ;
708
	    IDENTIFIER clab = DEREF_id ( exp_do_stmt_cont_lab ( e ) ) ;
709
	    EXP bs = DEREF_exp ( id_label_stmt ( blab ) ) ;
710
	    EXP cs = DEREF_exp ( id_label_stmt ( clab ) ) ;
711
	    print_indent ( indent, "do {\n", f ) ;
712
	    print_stmt ( a, indent + 1, 0, f ) ;
713
	    print_stmt ( cs, indent + 1, 0, f ) ;
714
	    print_indent ( indent, "} while ", f ) ;
715
	    print_expr ( c, 1, 0, f ) ;
716
	    fputs_v ( " ;\n", f ) ;
717
	    print_stmt ( bs, indent, 0, f ) ;
718
	    break ;
719
	}
720
	case exp_switch_stmt_tag : {
721
	    /* Switch statements */
722
	    EXP c = DEREF_exp ( exp_switch_stmt_control ( e ) ) ;
723
	    EXP a = DEREF_exp ( exp_switch_stmt_body ( e ) ) ;
724
	    IDENTIFIER blab = DEREF_id ( exp_switch_stmt_break_lab ( e ) ) ;
725
	    EXP bs = DEREF_exp ( id_label_stmt ( blab ) ) ;
726
	    print_indent ( indent, "switch ", f ) ;
727
	    print_expr ( c, 1, 0, f ) ;
728
	    fputs_v ( " {\n", f ) ;
729
	    print_stmt ( a, indent + 1, 0, f ) ;
730
	    print_indent ( indent, "}\n", f ) ;
731
	    print_stmt ( bs, indent, 0, f ) ;
732
	    break ;
733
	}
734
	case exp_hash_if_tag : {
735
	    /* Target dependent conditional statements */
736
	    EXP c = DEREF_exp ( exp_hash_if_cond ( e ) ) ;
737
	    EXP a = DEREF_exp ( exp_hash_if_true_code ( e ) ) ;
738
	    EXP b = DEREF_exp ( exp_hash_if_false_code ( e ) ) ;
739
	    fputs_v ( "#if ", f ) ;
740
	    print_expr ( c, 0, 0, f ) ;
741
	    fputs_v ( "\n", f ) ;
742
	    print_stmt ( a, indent, 0, f ) ;
743
	    if ( !IS_NULL_exp ( b ) ) {
744
		fputs_v ( "#else\n", f ) ;
745
		print_stmt ( b, indent, 0, f ) ;
746
	    }
747
	    fputs_v ( "#endif\n", f ) ;
748
	    break ;
749
	}
750
	case exp_return_stmt_tag : {
751
	    /* Return statements */
752
	    EXP a = DEREF_exp ( exp_return_stmt_value ( e ) ) ;
753
	    print_indent ( indent, "return", f ) ;
754
	    if ( !IS_NULL_exp ( a ) ) print_expr ( a, 1, 1, f ) ;
755
	    fputs_v ( " ;\n", f ) ;
756
	    break ;
757
	}
758
	case exp_goto_stmt_tag : {
759
	    /* Goto statements */
760
	    IDENTIFIER lab = DEREF_id ( exp_goto_stmt_label ( e ) ) ;
761
	    print_indent ( indent, "goto ", f ) ;
762
	    print_label ( lab, f ) ;
763
	    fputs_v ( " ;\n", f ) ;
764
	    break ;
765
	}
766
	case exp_label_stmt_tag : {
767
	    /* Labelled statements */
768
	    EXP a = DEREF_exp ( exp_label_stmt_body ( e ) ) ;
769
	    IDENTIFIER lab = DEREF_id ( exp_label_stmt_label ( e ) ) ;
770
	    IDENTIFIER nlab = DEREF_id ( exp_label_stmt_next ( e ) ) ;
771
	    print_indent ( indent, "", f ) ;
772
	    print_label ( lab, f ) ;
773
	    fputs_v ( " : {\n", f ) ;
774
	    print_stmt ( a, indent + 1, 0, f ) ;
775
	    if ( !IS_NULL_id ( nlab ) ) {
776
		print_indent ( indent + 1, "goto ", f ) ;
777
		print_label ( nlab, f ) ;
778
		fputs_v ( " ;\n", f ) ;
779
	    }
780
	    print_indent ( indent, "}\n", f ) ;
781
	    break ;
782
	}
783
	case exp_try_block_tag : {
784
	    /* Try blocks */
785
	    EXP a = DEREF_exp ( exp_try_block_body ( e ) ) ;
786
	    LIST ( EXP ) p = DEREF_list ( exp_try_block_handlers ( e ) ) ;
787
	    EXP b = DEREF_exp ( exp_try_block_ellipsis ( e ) ) ;
788
	    print_indent ( indent, "try {\n", f ) ;
789
	    print_stmt ( a, indent + 1, 0, f ) ;
790
	    print_indent ( indent, "}\n", f ) ;
791
	    while ( !IS_NULL_list ( p ) ) {
792
		EXP c = DEREF_exp ( HEAD_list ( p ) ) ;
793
		print_stmt ( c, indent + 1, 0, f ) ;
794
		p = TAIL_list ( p ) ;
795
	    }
796
	    if ( !IS_NULL_exp ( b ) ) {
797
		print_indent ( indent, "catch ( ... ) {\n", f ) ;
798
		print_stmt ( b, indent + 1, 0, f ) ;
799
		print_indent ( indent, "}\n", f ) ;
800
	    }
801
	    break ;
802
	}
803
	case exp_handler_tag : {
804
	    /* Exception handlers */
805
	    IDENTIFIER id = DEREF_id ( exp_handler_except ( e ) ) ;
806
	    EXP a = DEREF_exp ( exp_handler_body ( e ) ) ;
807
	    print_indent ( indent, "catch ( ", f ) ;
808
	    if ( !IS_NULL_id ( id ) ) print_decl ( id, f ) ;
809
	    fputs_v ( " ) {\n", f ) ;
810
	    print_stmt ( a, indent + 1, 0, f ) ;
811
	    print_indent ( indent, "}\n", f ) ;
812
	    break ;
813
	}
814
	case exp_reach_tag :
815
	case exp_unreach_tag : {
816
	    /* Reached statements */
817
	    EXP a = DEREF_exp ( exp_reach_etc_body ( e ) ) ;
818
	    print_stmt ( a, indent, block, f ) ;
819
	    break ;
820
	}
821
	case exp_location_tag : {
822
	    /* Location statements */
823
	    EXP a = DEREF_exp ( exp_location_arg ( e ) ) ;
824
	    print_stmt ( a, indent, block, f ) ;
825
	    break ;
826
	}
827
	default : {
828
	    /* Expression statements */
829
	    print_indent ( indent, "", f ) ;
830
	    print_expr ( e, 0, 0, f ) ;
831
	    fputs_v ( " ;\n", f ) ;
832
	    break ;
833
	}
834
    }
835
    return ;
836
}
837
 
838
 
839
/*
840
    PRINT A BITMASK TYPE
841
 
842
    This routine prints the bitmask value n using the attribute names
843
    given by s.
844
*/
845
 
846
static void print_bitmask
847
    PROTO_N ( ( n, s ) )
848
    PROTO_T ( unsigned long n X CONST char **s )
849
{
850
    int sp = 0 ;
851
    FILE *f = DEBUG_file ;
852
    if ( n ) {
853
	int i ;
854
	unsigned long m = 1 ;
855
	for ( i = 0 ; i < 32 ; i++ ) {
856
	    if ( n & m ) {
857
		CONST char *c = s [i] ;
858
		if ( c ) {
859
		    if ( sp ) fputs_v ( " | ", f ) ;
860
		    fputs_v ( c, f ) ;
861
		    sp = 1 ;
862
		}
863
	    }
864
	    m <<= 1 ;
865
	}
866
    }
867
    if ( !sp ) fputs_v ( "none", f ) ;
868
    fputc_v ( '\n', f ) ;
869
    fflush_v ( f ) ;
870
    return ;
871
}
872
 
873
 
874
/*
875
    PRINT A BITSTREAM
876
 
877
    This routine prints the contents of the bitstream bs to the file f.
878
*/
879
 
880
static void print_bitstream
881
    PROTO_N ( ( bs, f ) )
882
    PROTO_T ( BITSTREAM *bs X FILE *f )
883
{
884
    if ( bs ) {
885
	string s = bs->text ;
886
	unsigned i = bs->bits ;
887
	unsigned n = bs->bytes ;
888
	print_bitstream ( bs->prev, f ) ;
889
	fprintf_v ( f, "0x%p = { ", ( gen_ptr ) bs ) ;
890
	while ( n ) {
891
	    unsigned j ;
892
	    unsigned c = ( unsigned ) *s ;
893
	    for ( j = 0 ; j < 8 ; j++ ) {
894
		fputc_v ( ( ( c & 0x80 ) ? '1' : '0' ), f ) ;
895
		c <<= 1 ;
896
	    }
897
	    fputc_v ( ' ', f ) ;
898
	    n-- ;
899
	    s++ ;
900
	}
901
	if ( i ) {
902
	    unsigned j ;
903
	    unsigned c = ( unsigned ) *s ;
904
	    for ( j = 0 ; j < i ; j++ ) {
905
		fputc_v ( ( ( c & 0x80 ) ? '1' : '0' ), f ) ;
906
		c <<= 1 ;
907
	    }
908
	}
909
	fputs_v ( " }\n", f ) ;
910
    }
911
    return ;
912
}
913
 
914
 
915
/*
916
    TYPE DEBUGGING ROUTINES
917
 
918
    These routines are used during debugging for printing objects of various
919
    types.
920
*/
921
 
922
void DEBUG_access
923
    PROTO_N ( ( ds ) )
924
    PROTO_T ( DECL_SPEC ds )
925
{
926
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
927
    debugging++ ;
928
    IGNORE print_access ( ds, bf, 0 ) ;
929
    debugging-- ;
930
    bfputc ( bf, '\n' ) ;
931
    output_buffer ( bf, 1 ) ;
932
    return ;
933
}
934
 
935
void DEBUG_bits
936
    PROTO_N ( ( bs ) )
937
    PROTO_T ( BITSTREAM *bs )
938
{
939
    FILE *f = DEBUG_file ;
940
    print_bitstream ( bs, f ) ;
941
    fflush_v ( f ) ;
942
    return ;
943
}
944
 
945
void DEBUG_btype
946
    PROTO_N ( ( bt ) )
947
    PROTO_T ( BASE_TYPE bt )
948
{
949
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
950
    debugging++ ;
951
    IGNORE print_btype ( bt, bf, 0 ) ;
952
    debugging-- ;
953
    bfputc ( bf, '\n' ) ;
954
    output_buffer ( bf, 1 ) ;
955
    return ;
956
}
957
 
958
void DEBUG_cinfo
959
    PROTO_N ( ( ci ) )
960
    PROTO_T ( CLASS_INFO ci )
961
{
962
    static CONST char *cinfos [32] = {
963
	/* Keep in line with c_class.alg */
964
	"complete", "defined", "struct", "union", "template", "token",
965
	"pod", "nested", "merge", "rescan", "recursive", "incomplete",
966
	"base", "multiple_base", "virtual_base", "templ_base", "ambiguous",
967
	"empty", "private", "static", "function", "params", "polymorphic",
968
	"poly_base", "abstract", "trivial_constr", "trivial_destr",
969
	"trivial_copy", "trivial_assign", "const_copy", "const_assign",
970
	"usr_constr"
971
    } ;
972
    print_bitmask ( ( unsigned long ) ci, cinfos ) ;
973
    return ;
974
}
975
 
976
void DEBUG_ctype
977
    PROTO_N ( ( ct ) )
978
    PROTO_T ( CLASS_TYPE ct )
979
{
980
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
981
    debugging++ ;
982
    IGNORE print_ctype ( ct, qual_none, 0, bf, 0 ) ;
983
    debugging-- ;
984
    bfputc ( bf, '\n' ) ;
985
    output_buffer ( bf, 1 ) ;
986
    return ;
987
}
988
 
989
void DEBUG_cusage
990
    PROTO_N ( ( cu ) )
991
    PROTO_T ( CLASS_USAGE cu )
992
{
993
    static CONST char *cusages [32] = {
994
	/* Keep in line with c_class.alg */
995
	"address", "destr", "delete", "delete_array", NULL, NULL, NULL,
996
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
997
	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
998
	NULL, NULL, NULL
999
    } ;
1000
    print_bitmask ( ( unsigned long ) cu, cusages ) ;
1001
    return ;
1002
}
1003
 
1004
void DEBUG_cv
1005
    PROTO_N ( ( cv ) )
1006
    PROTO_T ( CV_SPEC cv )
1007
{
1008
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1009
    debugging++ ;
1010
    IGNORE print_cv ( cv, bf, 0 ) ;
1011
    debugging-- ;
1012
    bfputc ( bf, '\n' ) ;
1013
    output_buffer ( bf, 1 ) ;
1014
    return ;
1015
}
1016
 
1017
void DEBUG_dspec
1018
    PROTO_N ( ( ds ) )
1019
    PROTO_T ( DECL_SPEC ds )
1020
{
1021
    static CONST char *dspecs [32] = {
1022
	/* Keep in step with c_class.alg */
1023
	"used", "called", "defn", "inherit", "alias", "done", "static",
1024
	"extern", "auto", "register", "mutable", "inline", "virtual",
1025
	"explicit", "friend", "typedef", "public", "protected", "public2",
1026
	"protected2", "c", "cpp", "ignore", "implicit", "instance",
1027
	"main", "pure", "reserve", "temp", "template", "token", "trivial"
1028
    } ;
1029
    print_bitmask ( ( unsigned long ) ds, dspecs ) ;
1030
    return ;
1031
}
1032
 
1033
void DEBUG_etype
1034
    PROTO_N ( ( et ) )
1035
    PROTO_T ( ENUM_TYPE et )
1036
{
1037
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1038
    debugging++ ;
1039
    IGNORE print_etype ( et, 0, bf, 0 ) ;
1040
    debugging-- ;
1041
    bfputc ( bf, '\n' ) ;
1042
    output_buffer ( bf, 1 ) ;
1043
    return ;
1044
}
1045
 
1046
void DEBUG_exp
1047
    PROTO_N ( ( e ) )
1048
    PROTO_T ( EXP e )
1049
{
1050
    FILE *f = DEBUG_file ;
1051
    debugging++ ;
1052
    print_expr ( e, 0, 0, f ) ;
1053
    debugging-- ;
1054
    fputc_v ( '\n', f ) ;
1055
    fflush_v ( f ) ;
1056
    return ;
1057
}
1058
 
1059
void DEBUG_flt
1060
    PROTO_N ( ( f ) )
1061
    PROTO_T ( FLOAT f )
1062
{
1063
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1064
    debugging++ ;
1065
    IGNORE print_flt ( f, bf, 0 ) ;
1066
    debugging-- ;
1067
    bfputc ( bf, '\n' ) ;
1068
    output_buffer ( bf, 1 ) ;
1069
    return ;
1070
}
1071
 
1072
void DEBUG_ftype
1073
    PROTO_N ( ( ft ) )
1074
    PROTO_T ( FLOAT_TYPE ft )
1075
{
1076
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1077
    debugging++ ;
1078
    IGNORE print_ftype ( ft, bf, 0 ) ;
1079
    debugging-- ;
1080
    bfputc ( bf, '\n' ) ;
1081
    output_buffer ( bf, 1 ) ;
1082
    return ;
1083
}
1084
 
1085
void DEBUG_func
1086
    PROTO_N ( ( id ) )
1087
    PROTO_T ( IDENTIFIER id )
1088
{
1089
    if ( !IS_NULL_id ( id ) ) {
1090
	DEBUG_id_long ( id ) ;
1091
	if ( IS_id_function_etc ( id ) ) {
1092
	    id = DEREF_id ( id_function_etc_over ( id ) ) ;
1093
	    DEBUG_func ( id ) ;
1094
	}
1095
    }
1096
    return ;
1097
}
1098
 
1099
void DEBUG_graph
1100
    PROTO_N ( ( gr ) )
1101
    PROTO_T ( GRAPH gr )
1102
{
1103
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1104
    debugging++ ;
1105
    IGNORE print_graph ( gr, 0, bf, 0 ) ;
1106
    debugging-- ;
1107
    bfputc ( bf, '\n' ) ;
1108
    output_buffer ( bf, 1 ) ;
1109
    return ;
1110
}
1111
 
1112
void DEBUG_hashid
1113
    PROTO_N ( ( nm ) )
1114
    PROTO_T ( HASHID nm )
1115
{
1116
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1117
    debugging++ ;
1118
    IGNORE print_hashid ( nm, 1, 1, bf, 0 ) ;
1119
    debugging-- ;
1120
    bfputc ( bf, '\n' ) ;
1121
    output_buffer ( bf, 1 ) ;
1122
    return ;
1123
}
1124
 
1125
void DEBUG_hash_table
1126
    PROTO_N ( ( s ) )
1127
    PROTO_T ( string s )
1128
{
1129
    unsigned long i = 0 ;
1130
    unsigned long m = HASH_SIZE ;
1131
    if ( s ) {
1132
	i = hash ( s ) ;
1133
	m = i + 1 ;
1134
	IGNORE lookup_name ( s, i, 0, lex_unknown ) ;
1135
    }
1136
    debugging++ ;
1137
    while ( i < m ) {
1138
	HASHID nm = hash_table [i] ;
1139
	if ( !IS_NULL_hashid ( nm ) ) {
1140
	    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1141
	    bfprintf ( bf, "%lu:", i ) ;
1142
	    while ( !IS_NULL_hashid ( nm ) ) {
1143
		IGNORE print_hashid ( nm, 1, 1, bf, 1 ) ;
1144
		nm = DEREF_hashid ( hashid_next ( nm ) ) ;
1145
	    }
1146
	    bfputc ( bf, '\n' ) ;
1147
	    output_buffer ( bf, 1 ) ;
1148
	}
1149
	i++ ;
1150
    }
1151
    debugging-- ;
1152
    return ;
1153
}
1154
 
1155
void DEBUG_id
1156
    PROTO_N ( ( id ) )
1157
    PROTO_T ( IDENTIFIER id )
1158
{
1159
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1160
    debugging++ ;
1161
    IGNORE print_id_short ( id, qual_none, bf, 0 ) ;
1162
    debugging-- ;
1163
    bfputc ( bf, '\n' ) ;
1164
    output_buffer ( bf, 1 ) ;
1165
    return ;
1166
}
1167
 
1168
void DEBUG_id_long
1169
    PROTO_N ( ( id ) )
1170
    PROTO_T ( IDENTIFIER id )
1171
{
1172
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1173
    debugging++ ;
1174
    print_id_desc++ ;
1175
    IGNORE print_id_long ( id, qual_none, bf, 0 ) ;
1176
    print_id_desc-- ;
1177
    debugging-- ;
1178
    bfputc ( bf, '\n' ) ;
1179
    output_buffer ( bf, 1 ) ;
1180
    return ;
1181
}
1182
 
1183
void DEBUG_inst
1184
    PROTO_N ( ( inst ) )
1185
    PROTO_T ( INSTANCE inst )
1186
{
1187
    if ( !IS_NULL_inst ( inst ) ) {
1188
	TYPE form = DEREF_type ( inst_form ( inst ) ) ;
1189
	DEBUG_type ( form ) ;
1190
    }
1191
    return ;
1192
}
1193
 
1194
void DEBUG_insts
1195
    PROTO_N ( ( inst ) )
1196
    PROTO_T ( INSTANCE inst )
1197
{
1198
    while ( !IS_NULL_inst ( inst ) ) {
1199
	DECL_SPEC acc = dspec_none ;
1200
	TYPE form = DEREF_type ( inst_form ( inst ) ) ;
1201
	if ( IS_inst_templ ( inst ) ) {
1202
	    acc = DEREF_dspec ( inst_templ_access ( inst ) ) ;
1203
	}
1204
	DEBUG_dspec ( acc ) ;
1205
	DEBUG_type ( form ) ;
1206
	inst = DEREF_inst ( inst_next ( inst ) ) ;
1207
    }
1208
    return ;
1209
}
1210
 
1211
void DEBUG_itype
1212
    PROTO_N ( ( it ) )
1213
    PROTO_T ( INT_TYPE it )
1214
{
1215
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1216
    debugging++ ;
1217
    IGNORE print_itype ( it, bf, 0 ) ;
1218
    debugging-- ;
1219
    bfputc ( bf, '\n' ) ;
1220
    output_buffer ( bf, 1 ) ;
1221
    return ;
1222
}
1223
 
1224
void DEBUG_lex
1225
    PROTO_N ( ( t ) )
1226
    PROTO_T ( int t )
1227
{
1228
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1229
    debugging++ ;
1230
    IGNORE print_lex ( t, bf, 0 ) ;
1231
    debugging-- ;
1232
    bfputc ( bf, '\n' ) ;
1233
    output_buffer ( bf, 1 ) ;
1234
    return ;
1235
}
1236
 
1237
void DEBUG_loc
1238
    PROTO_N ( ( loc ) )
1239
    PROTO_T ( LOCATION *loc )
1240
{
1241
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1242
    debugging++ ;
1243
    IGNORE print_loc ( loc, NIL ( LOCATION ), bf, 0 ) ;
1244
    debugging-- ;
1245
    bfputc ( bf, '\n' ) ;
1246
    output_buffer ( bf, 1 ) ;
1247
    return ;
1248
}
1249
 
1250
void DEBUG_mangle
1251
    PROTO_N ( ( id ) )
1252
    PROTO_T ( IDENTIFIER id )
1253
{
1254
    FILE *f = DEBUG_file ;
1255
    CONST char *s = NULL ;
1256
    if ( !IS_NULL_id ( id ) ) {
1257
	int v = VAR_tag ;
1258
	if ( IS_id_token ( id ) ) v = VAR_token ;
1259
	s = strlit ( mangle_name ( id, v, 0 ) ) ;
1260
    }
1261
    if ( s == NULL ) s = "(NULL)" ;
1262
    fprintf_v ( f, "%s\n", s ) ;
1263
    fflush_v ( f ) ;
1264
    return ;
1265
}
1266
 
1267
void DEBUG_member
1268
    PROTO_N ( ( mem ) )
1269
    PROTO_T ( MEMBER mem )
1270
{
1271
    if ( !IS_NULL_member ( mem ) ) {
1272
	IDENTIFIER id = DEREF_id ( member_id ( mem ) ) ;
1273
	IDENTIFIER alt = DEREF_id ( member_alt ( mem ) ) ;
1274
	DEBUG_id_long ( id ) ;
1275
	DEBUG_id_long ( alt ) ;
1276
    }
1277
    return ;
1278
}
1279
 
1280
void DEBUG_members
1281
    PROTO_N ( ( ns ) )
1282
    PROTO_T ( NAMESPACE ns )
1283
{
1284
    if ( !IS_NULL_nspace ( ns ) ) {
1285
	MEMBER mem ;
1286
	FILE *f = DEBUG_file ;
1287
	if ( IS_nspace_named_etc ( ns ) ) {
1288
	    mem = DEREF_member ( nspace_named_etc_first ( ns ) ) ;
1289
	} else {
1290
	    mem = DEREF_member ( nspace_last ( ns ) ) ;
1291
	}
1292
	DEBUG_nspace ( ns ) ;
1293
	fputs_v ( "{\n", f ) ;
1294
	while ( !IS_NULL_member ( mem ) ) {
1295
	    IDENTIFIER id = DEREF_id ( member_id ( mem ) ) ;
1296
	    IDENTIFIER alt = DEREF_id ( member_alt ( mem ) ) ;
1297
	    if ( !IS_NULL_id ( id ) ) {
1298
		fputs_v ( "    ", f ) ;
1299
		DEBUG_id_long ( id ) ;
1300
	    }
1301
	    if ( !IS_NULL_id ( alt ) && !EQ_id ( id, alt ) ) {
1302
		fputs_v ( "    ", f ) ;
1303
		DEBUG_id_long ( alt ) ;
1304
	    }
1305
	    mem = DEREF_member ( member_next ( mem ) ) ;
1306
	}
1307
	fputs_v ( "}\n", f ) ;
1308
    }
1309
    return ;
1310
}
1311
 
1312
void DEBUG_nat
1313
    PROTO_N ( ( n ) )
1314
    PROTO_T ( NAT n )
1315
{
1316
    FILE *f = DEBUG_file ;
1317
    debugging++ ;
1318
    print_nat_val ( n, f ) ;
1319
    debugging-- ;
1320
    fputc_v ( '\n', f ) ;
1321
    fflush_v ( f ) ;
1322
    return ;
1323
}
1324
 
1325
void DEBUG_nspace
1326
    PROTO_N ( ( ns ) )
1327
    PROTO_T ( NAMESPACE ns )
1328
{
1329
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1330
    debugging++ ;
1331
    IGNORE print_nspace ( ns, qual_none, 0, bf, 0 ) ;
1332
    debugging-- ;
1333
    bfputc ( bf, '\n' ) ;
1334
    output_buffer ( bf, 1 ) ;
1335
    return ;
1336
}
1337
 
1338
void DEBUG_ntype
1339
    PROTO_N ( ( nt ) )
1340
    PROTO_T ( BUILTIN_TYPE nt )
1341
{
1342
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1343
    debugging++ ;
1344
    IGNORE print_ntype ( nt, bf, 0 ) ;
1345
    debugging-- ;
1346
    bfputc ( bf, '\n' ) ;
1347
    output_buffer ( bf, 1 ) ;
1348
    return ;
1349
}
1350
 
1351
void DEBUG_offset
1352
    PROTO_N ( ( off ) )
1353
    PROTO_T ( OFFSET off )
1354
{
1355
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1356
    debugging++ ;
1357
    IGNORE print_offset ( off, bf, 0 ) ;
1358
    debugging-- ;
1359
    bfputc ( bf, '\n' ) ;
1360
    output_buffer ( bf, 1 ) ;
1361
    return ;
1362
}
1363
 
1364
void DEBUG_ntest
1365
    PROTO_N ( ( nt ) )
1366
    PROTO_T ( NTEST nt )
1367
{
1368
    int op = ntest_token ( nt, lex_unknown ) ;
1369
    DEBUG_lex ( op ) ;
1370
    return ;
1371
}
1372
 
1373
void DEBUG_pptok
1374
    PROTO_N ( ( p ) )
1375
    PROTO_T ( PPTOKEN *p )
1376
{
1377
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1378
    debugging++ ;
1379
    IGNORE print_pptok ( p, bf, 0 ) ;
1380
    debugging-- ;
1381
    bfputc ( bf, '\n' ) ;
1382
    output_buffer ( bf, 1 ) ;
1383
    return ;
1384
}
1385
 
1386
void DEBUG_pptoks
1387
    PROTO_N ( ( p ) )
1388
    PROTO_T ( PPTOKEN *p )
1389
{
1390
    while ( p != NULL ) {
1391
	DEBUG_pptok ( p ) ;
1392
	p = p->next ;
1393
    }
1394
    return ;
1395
}
1396
 
1397
void DEBUG_sort
1398
    PROTO_N ( ( tok ) )
1399
    PROTO_T ( TOKEN tok )
1400
{
1401
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1402
    debugging++ ;
1403
    IGNORE print_sort ( tok, 0, bf, 0 ) ;
1404
    bfprintf ( bf, " = " ) ;
1405
    IGNORE print_tok_value ( tok, bf, 0 ) ;
1406
    debugging-- ;
1407
    bfputc ( bf, '\n' ) ;
1408
    output_buffer ( bf, 1 ) ;
1409
    return ;
1410
}
1411
 
1412
void DEBUG_source
1413
    PROTO_N ( ( lines ) )
1414
    PROTO_T ( int lines )
1415
{
1416
    FILE *f = DEBUG_file ;
1417
    update_column () ;
1418
    print_source ( &crt_loc, lines, 1, "", f ) ;
1419
    fflush_v ( f ) ;
1420
    return ;
1421
}
1422
 
1423
void DEBUG_stmt
1424
    PROTO_N ( ( e ) )
1425
    PROTO_T ( EXP e )
1426
{
1427
    FILE *f = DEBUG_file ;
1428
    debugging++ ;
1429
    print_stmt ( e, 0, 1, f ) ;
1430
    debugging-- ;
1431
    fflush_v ( f ) ;
1432
    return ;
1433
}
1434
 
1435
void DEBUG_str
1436
    PROTO_N ( ( s ) )
1437
    PROTO_T ( STRING s )
1438
{
1439
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1440
    debugging++ ;
1441
    IGNORE print_str ( s, bf, 0 ) ;
1442
    debugging-- ;
1443
    bfputc ( bf, '\n' ) ;
1444
    output_buffer ( bf, 1 ) ;
1445
    return ;
1446
}
1447
 
1448
void DEBUG_type
1449
    PROTO_N ( ( t ) )
1450
    PROTO_T ( TYPE t )
1451
{
1452
    int sp = 0 ;
1453
    BUFFER *bf = clear_buffer ( &print_buff, DEBUG_file ) ;
1454
    debugging++ ;
1455
    if ( !IS_NULL_type ( t ) ) {
1456
	CV_SPEC cv = DEREF_cv ( type_qual ( t ) ) ;
1457
	if ( cv & cv_lvalue ) sp = print_lex ( lex_lvalue, bf, sp ) ;
1458
    }
1459
    IGNORE print_type ( t, bf, sp ) ;
1460
    debugging-- ;
1461
    bfputc ( bf, '\n' ) ;
1462
    output_buffer ( bf, 1 ) ;
1463
    return ;
1464
}
1465
 
1466
void DEBUG_unmangle
1467
    PROTO_N ( ( s ) )
1468
    PROTO_T ( CONST char *s )
1469
{
1470
    LIST ( string ) p = NULL_list ( string ) ;
1471
    CONS_string ( ustrlit ( s ), p, p ) ;
1472
    unmangle_list ( p, DEBUG_file, 0 ) ;
1473
    DESTROY_list ( p, SIZE_string ) ;
1474
    return ;
1475
}
1476
 
1477
void DEBUG_virt
1478
    PROTO_N ( ( vt ) )
1479
    PROTO_T ( VIRTUAL vt )
1480
{
1481
    if ( !IS_NULL_virt ( vt ) ) {
1482
	if ( IS_virt_table ( vt ) ) {
1483
	    unsigned n = 1 ;
1484
	    LIST ( VIRTUAL ) vs = DEREF_list ( virt_table_entries ( vt ) ) ;
1485
	    while ( !IS_NULL_list ( vs ) ) {
1486
		vt = DEREF_virt ( HEAD_list ( vs ) ) ;
1487
		fprintf_v ( DEBUG_file, "%u: ", n ) ;
1488
		DEBUG_virt ( vt ) ;
1489
		n++ ;
1490
		vs = TAIL_list ( vs ) ;
1491
	    }
1492
	} else {
1493
	    IDENTIFIER fn = DEREF_id ( virt_func ( vt ) ) ;
1494
	    DEBUG_id_long ( fn ) ;
1495
	}
1496
    }
1497
    return ;
1498
}
1499
 
1500
void DEBUG_where
1501
    PROTO_Z ()
1502
{
1503
    update_column () ;
1504
    DEBUG_loc ( &crt_loc ) ;
1505
    return ;
1506
}
1507
 
1508
 
1509
/*
1510
    GENERIC TYPE DEBUGGING ROUTINE
1511
 
1512
    This routine is a generic debugging routine for printing any c_class
1513
    object.  It relies on run-time type information to determine the
1514
    static type of p.
1515
*/
1516
 
1517
#if c_class_IMPLEMENTATION
1518
 
1519
void DEBUG_c_class
1520
    PROTO_N ( ( p, indent ) )
1521
    PROTO_T ( c_class *p X int indent )
1522
{
1523
    FILE *f = DEBUG_file ;
1524
    debugging++ ;
1525
    if ( p ) {
1526
	unsigned n = TYPEID ( p ) ;
1527
	switch ( n ) {
1528
	    case TYPEID_ptr : {
1529
		DEBUG_c_class ( p->ag_ptr, indent ) ;
1530
		break ;
1531
	    }
1532
	    case TYPEID_list :
1533
	    case TYPEID_stack : {
1534
		print_indent ( indent, "{\n", f ) ;
1535
		while ( !IS_NULL_list ( p ) ) {
1536
		    c_class *q = ( HEAD_list ( p ) )->ag_ptr ;
1537
		    DEBUG_c_class ( q, indent + 1 ) ;
1538
		    p = TAIL_list ( p ) ;
1539
		}
1540
		print_indent ( indent, "}\n", f ) ;
1541
		break ;
1542
	    }
1543
	    case TYPEID_exp : {
1544
		print_stmt ( p, indent, 1, f ) ;
1545
		break ;
1546
	    }
1547
	    default : {
1548
		print_indent ( indent, "", f ) ;
1549
		switch ( n ) {
1550
		    case TYPEID_ctype : DEBUG_ctype ( p ) ; break ;
1551
		    case TYPEID_err : report ( crt_loc, p ) ; break ;
1552
		    case TYPEID_etype : DEBUG_etype ( p ) ; break ;
1553
		    case TYPEID_flt : DEBUG_flt ( p ) ; break ;
1554
		    case TYPEID_ftype : DEBUG_ftype ( p ) ; break ;
1555
		    case TYPEID_graph : DEBUG_graph ( p ) ; break ;
1556
		    case TYPEID_hashid : DEBUG_hashid ( p ) ; break ;
1557
		    case TYPEID_id : DEBUG_id_long ( p ) ; break ;
1558
		    case TYPEID_inst : DEBUG_inst ( p ) ; break ;
1559
		    case TYPEID_itype : DEBUG_itype ( p ) ; break ;
1560
		    case TYPEID_member : DEBUG_member ( p ) ; break ;
1561
		    case TYPEID_nat : DEBUG_nat ( p ) ; break ;
1562
		    case TYPEID_nspace : DEBUG_nspace ( p ) ; break ;
1563
		    case TYPEID_off : DEBUG_offset ( p ) ; break ;
1564
		    case TYPEID_str : DEBUG_str ( p ) ; break ;
1565
		    case TYPEID_tok : DEBUG_sort ( p ) ; break ;
1566
		    case TYPEID_type : DEBUG_type ( p ) ; break ;
1567
		    case TYPEID_virt : DEBUG_virt ( p ) ; break ;
1568
		    case TYPEID_free : fputs_v ( "FREE\n", f ) ; break ;
1569
		    default : fputs_v ( "UNKNOWN\n", f ) ; break ;
1570
		}
1571
		break ;
1572
	    }
1573
	}
1574
    } else {
1575
	print_indent ( indent, "NULL\n", f ) ;
1576
    }
1577
    fflush_v ( f ) ;
1578
    debugging-- ;
1579
    return ;
1580
}
1581
 
1582
void debug
1583
    PROTO_N ( ( p ) )
1584
    PROTO_T ( c_class *p )
1585
{
1586
    DEBUG_c_class ( p, 0 ) ;
1587
    return ;
1588
}
1589
 
1590
#ifdef DEBUG
1591
#undef DEBUG
1592
#endif
1593
 
1594
void DEBUG
1595
    PROTO_N ( ( p ) )
1596
    PROTO_T ( c_class *p )
1597
{
1598
    DEBUG_c_class ( p, 0 ) ;
1599
    return ;
1600
}
1601
 
1602
#endif /* c_class_IMPLEMENTATION */
1603
 
1604
 
1605
/*
1606
    PARSER TERMINALS
1607
 
1608
    The terminals used in the parser are listed in two places - in symbols.h
1609
    and in syntax.sid.
1610
*/
1611
 
1612
#if FS_STDC_HASH
1613
#define LEX_TOKEN( A, B, C )	print_terminal ( ( A ), #A, m ) ;
1614
#else
1615
#define LEX_TOKEN( A, B, C )	print_terminal ( ( A ), "A", m ) ;
1616
#endif
1617
 
1618
 
1619
/*
1620
    TERMINAL COUNT
1621
 
1622
    This variable is used to keep count of the number of lexical tokens
1623
    printed.
1624
*/
1625
 
1626
static int terminal_no = 0 ;
1627
 
1628
 
1629
/*
1630
    PRINT A TERMINAL
1631
 
1632
    This routine prints the single terminal, term, with the given return
1633
    type.  The use argument may be set to false to indicate that the
1634
    terminal is not used in the sid parser.
1635
*/
1636
 
1637
static void print_terminal
1638
    PROTO_N ( ( t, term, m ) )
1639
    PROTO_T ( int t X char *term X int m )
1640
{
1641
    char c ;
1642
    FILE *f = DEBUG_file ;
1643
    unsigned long col = 0 ;
1644
    unsigned long tab = tab_width ;
1645
    while ( *term == ' ' ) term++ ;
1646
    if ( t != terminal_no ) {
1647
	error ( ERROR_WARNING, "Value of '%s' wrong", term ) ;
1648
    }
1649
    if ( m ) {
1650
	term += strlen ( "lex_" ) ;
1651
    } else {
1652
	fprintf_v ( f, "#define " ) ;
1653
	col = ( unsigned long ) strlen ( "#define " ) ;
1654
    }
1655
    while ( c = *( term++ ), ( c != 0 && c != ' ' ) ) {
1656
	if ( c == '_' && m ) c = '-' ;
1657
	fputc_v ( c, f ) ;
1658
	col++ ;
1659
    }
1660
    if ( m ) {
1661
	fprintf_v ( f, " ;\n" ) ;
1662
    } else {
1663
	while ( col < 5 * tab ) {
1664
	    fputc_v ( '\t', f ) ;
1665
	    col = tab * ( col / tab + 1 ) ;
1666
	}
1667
	fprintf_v ( f, "%d\n", terminal_no ) ;
1668
    }
1669
    terminal_no++ ;
1670
    return ;
1671
}
1672
 
1673
 
1674
/*
1675
    PRINT ALL THE TERMINALS
1676
 
1677
    This routine prints all the terminals in a form acceptable to sid.
1678
*/
1679
 
1680
static void sid_terminals
1681
    PROTO_N ( ( m ) )
1682
    PROTO_T ( int m )
1683
{
1684
    FILE *f = DEBUG_file ;
1685
    terminal_no = 0 ;
1686
    fprintf_v ( f, "/* Automatically generated list of terminals */\n" ) ;
1687
#include "symbols.h"
1688
#undef LEX_TOKEN
1689
    return ;
1690
}
1691
 
1692
 
1693
/*
1694
    PRINT ALL THE ERRORS
1695
 
1696
    This routine lists all the error names.
1697
*/
1698
 
1699
static void list_errors
1700
    PROTO_Z ()
1701
{
1702
    FILE *f = DEBUG_file ;
1703
    ERR_DATA *p = ERR_CATALOG ;
1704
    init_option ( 0 ) ;
1705
    while ( p->name ) {
1706
	fprintf_v ( f, "%s\n", p->name ) ;
1707
	p++ ;
1708
    }
1709
    return ;
1710
}
1711
 
1712
 
1713
/*
1714
    PRINT ALL THE OPTIONS
1715
 
1716
    This routine lists all the option names.
1717
*/
1718
 
1719
static void list_options
1720
    PROTO_Z ()
1721
{
1722
    FILE *f = DEBUG_file ;
1723
    OPT_DATA *p = OPT_CATALOG ;
1724
    while ( p->name ) {
1725
	fprintf_v ( f, "%s\n", p->name ) ;
1726
	p++ ;
1727
    }
1728
    return ;
1729
}
1730
 
1731
 
1732
/*
1733
    DEFINE ALL THE OPTION VALUES
1734
 
1735
    This routine prints a list of all option values in a form suitable
1736
    as a usage list in the error catalogue.
1737
*/
1738
 
1739
static void define_options
1740
    PROTO_Z ()
1741
{
1742
    int col = 0 ;
1743
    int comma = 0 ;
1744
    CONST char *s ;
1745
    FILE *f = DEBUG_file ;
1746
    OPT_DATA *p = OPT_CATALOG ;
1747
    fprintf_v ( f, "    " ) ;
1748
    while ( s = p->name, s != NULL ) {
1749
	char c ;
1750
	if ( comma ) {
1751
	    fputc_v ( ',', f ) ;
1752
	    col++ ;
1753
	}
1754
	if ( col > 60 ) {
1755
	    fprintf_v ( f, "\n    " ) ;
1756
	    comma = 0 ;
1757
	    col = 0 ;
1758
	}
1759
	if ( comma ) {
1760
	    fputc_v ( ' ', f ) ;
1761
	    col++ ;
1762
	}
1763
	while ( c = *( s++ ), c != 0 ) {
1764
	    if ( c == '.' ) c = '_' ;
1765
	    fputc_v ( c, f ) ;
1766
	    col++ ;
1767
	}
1768
	comma = 1 ;
1769
	p++ ;
1770
    }
1771
    fputc_v ( '\n', f ) ;
1772
    return ;
1773
}
1774
 
1775
 
1776
/*
1777
    HANDLE DEBUGGING OPTIONS
1778
 
1779
    This routine is called to handle the debug option '-d arg'.
1780
*/
1781
 
1782
void debug_option
1783
    PROTO_N ( ( arg ) )
1784
    PROTO_T ( char *arg )
1785
{
1786
    if ( streq ( arg, "error" ) ) {
1787
	list_errors () ;
1788
    } else if ( streq ( arg, "lex" ) ) {
1789
	sid_terminals ( 0 ) ;
1790
    } else if ( streq ( arg, "opt" ) ) {
1791
	define_options () ;
1792
    } else if ( streq ( arg, "option" ) ) {
1793
	list_options () ;
1794
    } else if ( streq ( arg, "sid" ) ) {
1795
	sid_terminals ( 1 ) ;
1796
    } else {
1797
	error ( ERROR_WARNING, "Unknown option, '-d%s'", arg ) ;
1798
    }
1799
    return ;
1800
}
1801
 
1802
 
1803
#else /* RUNTIME */
1804
 
1805
 
1806
/*
1807
    DUMMY DEBUGGING ROUTINE
1808
 
1809
    This routine is a dummy which is used when run-time routines are
1810
    not enabled.
1811
*/
1812
 
1813
#if c_class_IMPLEMENTATION
1814
 
1815
void debug
1816
   PROTO_N ( ( p ) )
1817
   PROTO_T ( c_class *p )
1818
{
1819
    error ( ERROR_INTERNAL, "Not compiled with debugging enabled" ) ;
1820
    UNUSED ( p ) ;
1821
    return ;
1822
}
1823
 
1824
#endif /* c_class_IMPLEMENTATION */
1825
 
1826
 
1827
#endif /* RUNTIME */