Subversion Repositories tendra.SVN

Rev

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

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