Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
6 7u83 2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
6 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
6 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
6 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
6 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
6 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "version.h"
63
#include "c_types.h"
64
#include "ctype_ops.h"
65
#include "exp_ops.h"
66
#include "hashid_ops.h"
67
#include "id_ops.h"
68
#include "member_ops.h"
69
#include "nat_ops.h"
70
#include "nspace_ops.h"
71
#include "tok_ops.h"
72
#include "type_ops.h"
73
#include "error.h"
74
#include "catalog.h"
75
#include "tdf.h"
76
#include "allocate.h"
77
#include "basetype.h"
78
#include "buffer.h"
79
#include "char.h"
80
#include "class.h"
81
#include "constant.h"
82
#include "convert.h"
83
#include "declare.h"
84
#include "exception.h"
85
#include "function.h"
86
#include "hash.h"
87
#include "identifier.h"
88
#include "initialise.h"
89
#include "lex.h"
90
#include "literal.h"
91
#include "mangle.h"
92
#include "namespace.h"
93
#include "print.h"
94
#include "syntax.h"
95
#include "unmangle.h"
96
#include "ustring.h"
97
#include "xalloc.h"
98
 
99
 
100
/*
101
    LANGUAGE DEPENDENT DEFINITIONS
102
 
103
    The unmangling routines are only included in the C++ producer; the
104
    C producer uses a dummy identity mapping.
105
*/
106
 
107
#if LANGUAGE_CPP
108
 
109
 
110
/*
111
    FORWARD DECLARATIONS
112
 
113
    The following forward declarations are required in the name unmangling
114
    routines.
115
*/
116
 
6 7u83 117
static NAT unmangle_nat(string *);
118
static TYPE unmangle_type(string *, CV_SPEC, BASE_TYPE, int);
119
static IDENTIFIER unmangle_nspace(string *, NAMESPACE, int);
120
static LIST(TOKEN)unmangle_token_args(string *);
121
static TOKEN find_token_arg(string *);
2 7u83 122
 
123
 
124
/*
125
    DUMMY RETURN TYPE
126
 
127
    This variable is a dummy used as a return type when none is given in
128
    a mangled form.  Its printed form is empty.
129
*/
130
 
6 7u83 131
static TYPE dummy_ret_type = NULL_type;
2 7u83 132
 
133
 
134
/*
135
    CURRENT UNMANGLING INFORMATION
136
 
137
    The following variables are used to hold certain information about the
138
    identifier being unmangled.
139
*/
140
 
6 7u83 141
static IDENTIFIER crt_unmangle_class = NULL_id;
142
static LIST(TOKEN)crt_unmangle_args = NULL_list(TOKEN);
2 7u83 143
 
144
 
145
/*
146
    UNMANGLE AN OPERATOR NAME
147
 
148
    This routine unmangles an operator name from the string pointed to
149
    by ps.
150
*/
151
 
6 7u83 152
static int
153
unmangle_op(string *ps)
2 7u83 154
{
6 7u83 155
	string s = *ps;
156
	int t = lex_unknown;
157
	character c = *(s++);
158
	switch (c) {
159
	case 'a': {
160
		c = *(s++);
161
		switch (c) {
162
		case 'a': {
163
			c = *(s++);
164
			if (c == 'd') {
165
				t = lex_and_Heq_H1;
166
			} else {
167
				s--;
168
				t = lex_logical_Hand_H1;
169
			}
170
			break;
2 7u83 171
		}
6 7u83 172
		case 'b': {
173
			t = lex_abs;
174
			break;
2 7u83 175
		}
6 7u83 176
		case 'd': {
177
			c = *(s++);
178
			if (c == 'v') {
179
				t = lex_div_Heq;
180
			} else {
181
				s--;
182
				t = lex_and_H1;
183
			}
184
			break;
2 7u83 185
		}
6 7u83 186
		case 'e': {
187
			c = *(s++);
188
			if (c == 'r') {
189
				t = lex_xor_Heq_H1;
190
			}
191
			break;
2 7u83 192
		}
6 7u83 193
		case 'l': {
194
			c = *(s++);
195
			if (c == 's') {
196
				t = lex_lshift_Heq;
197
			}
198
			break;
2 7u83 199
		}
6 7u83 200
		case 'm': {
201
			c = *(s++);
202
			switch (c) {
203
			case 'd':
204
				t = lex_rem_Heq;
205
				break;
206
			case 'i':
207
				t = lex_minus_Heq;
208
				break;
209
			case 'l':
210
				t = lex_star_Heq;
211
				break;
212
			}
213
			break;
2 7u83 214
		}
6 7u83 215
		case 'o': {
216
			c = *(s++);
217
			if (c == 'r') {
218
				t = lex_or_Heq_H1;
219
			}
220
			break;
2 7u83 221
		}
6 7u83 222
		case 'p': {
223
			c = *(s++);
224
			if (c == 'l') {
225
				t = lex_plus_Heq;
226
			}
227
			break;
2 7u83 228
		}
6 7u83 229
		case 'r': {
230
			c = *(s++);
231
			if (c == 's') {
232
				t = lex_rshift_Heq;
233
			}
234
			break;
2 7u83 235
		}
6 7u83 236
		case 's': {
237
			t = lex_assign;
238
			break;
2 7u83 239
		}
6 7u83 240
		}
241
		break;
2 7u83 242
	}
6 7u83 243
	case 'c': {
244
		c = *(s++);
245
		switch (c) {
246
		case 'c':
247
			t = lex_colon_Hcolon;
248
			break;
249
		case 'l':
250
			t = lex_func_Hop;
251
			break;
252
		case 'm':
253
			t = lex_comma;
254
			break;
255
		case 'n':
256
			t = lex_cond_Hop;
257
			break;
258
		case 'o':
259
			t = lex_compl_H1;
260
			break;
261
		case 's':
262
			t = lex_colon;
263
			break;
264
		case 't':
265
			t = lex_type_Hname;
266
			break;
267
		}
268
		break;
2 7u83 269
	}
6 7u83 270
	case 'd': {
271
		c = *(s++);
272
		switch (c) {
273
		case 'f':
274
			t = lex_dot;
275
			break;
276
		case 'l':
277
			t = lex_delete;
278
			break;
279
		case 'm':
280
			t = lex_dot_Hstar;
281
			break;
282
		case 't':
283
			t = lex_destructor_Hname;
284
			break;
285
		case 'v':
286
			t = lex_div;
287
			break;
288
		}
289
		break;
2 7u83 290
	}
6 7u83 291
	case 'e': {
292
		c = *(s++);
293
		switch (c) {
294
		case 'q':
295
			t = lex_eq;
296
			break;
297
		case 'r':
298
			t = lex_xor_H1;
299
			break;
300
		}
301
		break;
2 7u83 302
	}
6 7u83 303
	case 'f': {
304
		t = lex_float;
305
		break;
2 7u83 306
	}
6 7u83 307
	case 'g': {
308
		c = *(s++);
309
		switch (c) {
310
		case 'e':
311
			t = lex_greater_Heq;
312
			break;
313
		case 't':
314
			t = lex_greater;
315
			break;
316
		}
317
		break;
2 7u83 318
	}
6 7u83 319
	case 'l': {
320
		c = *(s++);
321
		switch (c) {
322
		case 'e':
323
			t = lex_less_Heq;
324
			break;
325
		case 's':
326
			t = lex_lshift;
327
			break;
328
		case 't':
329
			t = lex_less;
330
			break;
331
		}
332
		break;
2 7u83 333
	}
6 7u83 334
	case 'm': {
335
		c = *(s++);
336
		switch (c) {
337
		case 'd':
338
			t = lex_rem;
339
			break;
340
		case 'i':
341
			t = lex_minus;
342
			break;
343
		case 'l':
344
			t = lex_star;
345
			break;
346
		case 'm':
347
			t = lex_minus_Hminus;
348
			break;
349
		case 'n':
350
			t = lex_min;
351
			break;
352
		case 'x':
353
			t = lex_max;
354
			break;
355
		}
356
		break;
2 7u83 357
	}
6 7u83 358
	case 'n': {
359
		c = *(s++);
360
		switch (c) {
361
		case 'e':
362
			t = lex_not_Heq_H1;
363
			break;
364
		case 't':
365
			t = lex_not_H1;
366
			break;
367
		case 'w':
368
			t = lex_new;
369
			break;
370
		}
371
		break;
2 7u83 372
	}
6 7u83 373
	case 'o': {
374
		c = *(s++);
375
		switch (c) {
376
		case 'o':
377
			t = lex_logical_Hor_H1;
378
			break;
379
		case 'p':
380
			t = lex_operator;
381
			break;
382
		case 'r':
383
			t = lex_or_H1;
384
			break;
385
		}
386
		break;
2 7u83 387
	}
6 7u83 388
	case 'p': {
389
		c = *(s++);
390
		switch (c) {
391
		case 'l':
392
			t = lex_plus;
393
			break;
394
		case 'p':
395
			t = lex_plus_Hplus;
396
			break;
397
		}
398
		break;
2 7u83 399
	}
6 7u83 400
	case 'r': {
401
		c = *(s++);
402
		switch (c) {
403
		case 'f':
404
			t = lex_arrow;
405
			break;
406
		case 'm':
407
			t = lex_arrow_Hstar;
408
			break;
409
		case 's':
410
			t = lex_rshift;
411
			break;
412
		}
413
		break;
2 7u83 414
	}
6 7u83 415
	case 's': {
416
		c = *(s++);
417
		if (c == 'z') {
418
			t = lex_sizeof;
419
		}
420
		break;
2 7u83 421
	}
6 7u83 422
	case 't': {
423
		c = *(s++);
424
		switch (c) {
425
		case 'b':
426
			t = lex_vtable;
427
			break;
428
		case 'd':
429
			t = lex_typeid;
430
			break;
431
		case 'i': {
432
			if (s[0] == '_' && s[1] == '_') {
433
				t = lex_typeof;
434
				s += 2;
435
			}
436
			break;
2 7u83 437
		}
6 7u83 438
		}
439
		break;
2 7u83 440
	}
6 7u83 441
	case 'v': {
442
		c = *(s++);
443
		switch (c) {
444
		case 'c':
445
			t = lex_array_Hop;
446
			break;
447
		case 'd':
448
			t = lex_delete_Harray;
449
			break;
450
		case 'n':
451
			t = lex_new_Harray;
452
			break;
453
		case '_':
454
			t = lex_static;
455
			break;
456
		case 't': {
457
			if (s[0] == '_' && s[1] == '_') {
458
				t = lex_virtual;
459
				s += 2;
460
			}
461
			break;
2 7u83 462
		}
6 7u83 463
		}
464
		break;
2 7u83 465
	}
6 7u83 466
	case '0':
467
	case '1':
468
	case '2':
469
	case '3':
470
	case '4':
471
	case '5':
472
	case '6':
473
	case '7':
474
	case '8':
475
	case '9': {
476
		t = lex_auto;
477
		break;
2 7u83 478
	}
6 7u83 479
	}
480
	if (t != lex_unknown) {
481
		*ps = s;
482
	}
483
	return (t);
2 7u83 484
}
485
 
486
 
487
/*
488
    UNMANGLE A NUMBER
489
 
490
    This routine unmangles a series of digits from the string pointed
491
    to by ps.  If e is true then the digits should be terminated by an
492
    underscore.
493
*/
494
 
6 7u83 495
static unsigned
496
unmangle_no(string *ps, int e)
2 7u83 497
{
6 7u83 498
	character c;
499
	unsigned n = 0;
500
	string s = *ps;
501
	while (c = *(s++), (c >= char_zero && c <= char_nine)) {
502
		unsigned d = (unsigned)(c - char_zero);
503
		n = 10 * n + d;
504
	}
505
	if (c != MANGLE_sep || e == 0) {
506
		s--;
507
	}
508
	*ps = s;
509
	return (n);
2 7u83 510
}
511
 
512
 
513
/*
514
    UNMANGLE A SMALL NUMBER
515
 
516
    This routine unmangles a small number from the string pointed to
517
    by ps.  This consists either of a single digit or a series of digits
518
    delimited by underscores.
519
*/
520
 
6 7u83 521
static unsigned
522
unmangle_digit(string *ps)
2 7u83 523
{
6 7u83 524
	unsigned n;
525
	string s = *ps;
526
	character c = *(s++);
527
	if (c >= char_zero && c <= char_nine) {
528
		n = (unsigned)(c - char_zero);
529
	} else if (c == MANGLE_sep) {
530
		n = unmangle_no(&s, 1);
531
	} else {
532
		n = 0;
533
		s--;
534
	}
535
	*ps = s;
536
	return (n);
2 7u83 537
}
538
 
539
 
540
/*
541
    UNMANGLE AN EXPRESSION
542
 
543
    This routine unmangles an expression of type t from the string pointed
544
    to by ps.
545
*/
546
 
6 7u83 547
static EXP
548
unmangle_exp(string *ps, TYPE t)
2 7u83 549
{
6 7u83 550
	EXP e = NULL_exp;
551
	string s = *ps;
552
	character c = *s;
553
	if ((c >= char_zero && c <= char_nine) || c == MANGLE_neg) {
554
		/* Read an integer constant */
555
		NAT n = unmangle_nat(&s);
556
		if (!IS_NULL_nat(n)) {
557
			MAKE_exp_int_lit(t, n, exp_int_lit_tag, e);
558
		}
2 7u83 559
 
6 7u83 560
	} else if (c == MANGLE_op) {
561
		int op;
562
		s++;
563
		op = unmangle_op(&s);
564
		if (op == lex_float) {
565
			/* Floating point literals */
566
			string u = xustrcpy(s);
567
			string v = u;
568
			while (c = *(s++), c != 0) {
569
				if (c == MANGLE_sep) {
570
					*v = 0;
571
					s++;
572
					break;
573
				}
574
				if ((c >= char_zero && c <= char_nine) ||
575
				    c == 'e') {
576
					/* EMPTY */
577
				} else if (c == 'd') {
578
					*v = '.';
579
				} else if (c == MANGLE_neg) {
580
					*v = '-';
581
				} else {
582
					*v = 0;
583
					break;
584
				}
585
				v++;
586
			}
587
			s--;
588
			e = make_literal_exp(u, &op, 0);
2 7u83 589
		} else {
6 7u83 590
			int n = 0;
591
			c = *s;
592
			if (c >= char_zero && c <= char_nine) {
593
				n = (int)(c - char_zero);
594
				s++;
595
			}
596
			if (op == lex_sizeof) {
597
				TYPE r = unmangle_type(&s, cv_none, btype_none,
598
						       1);
599
				e = make_sizeof_exp(r, NULL_exp, 0, op);
600
			} else {
601
				LIST(EXP)p = NULL_list(EXP);
602
				while (n) {
603
					EXP a = unmangle_exp(&s, t);
604
					CONS_exp(a, p, p);
605
					n--;
606
				}
607
				p = REVERSE_list(p);
608
				MAKE_exp_opn(t, op, p, e);
609
			}
2 7u83 610
		}
6 7u83 611
 
612
	} else if (c == MANGLE_sep) {
613
		IDENTIFIER id;
614
		s++;
615
		id = unmangle_nspace(&s, global_namespace, 1);
616
		if (!IS_NULL_id(id)) {
617
			MAKE_exp_identifier(t, id, qual_nested, e);
2 7u83 618
		}
619
 
6 7u83 620
	} else if (c == MANGLE_templ_param) {
621
		/* Template parameter expressions */
622
		TOKEN tok;
623
		s++;
624
		tok = find_token_arg(&s);
625
		if (!IS_NULL_tok(tok) && IS_tok_exp(tok)) {
626
			e = DEREF_exp(tok_exp_value(tok));
627
		}
2 7u83 628
	}
6 7u83 629
	*ps = s;
630
	return (e);
2 7u83 631
}
632
 
633
 
634
/*
635
    UNMANGLE AN INTEGER CONSTANT
636
 
637
    This routine unmangles an integer constant from the string pointed to
638
    by ps.
639
*/
640
 
6 7u83 641
static NAT
642
unmangle_nat(string *ps)
2 7u83 643
{
6 7u83 644
	NAT n = NULL_nat;
645
	string s = *ps;
646
	character c = *s;
647
	if (c >= char_zero && c <= char_nine) {
648
		/* Read a sequence of digits */
649
		s++;
650
		do {
651
			unsigned d = (unsigned)(c - char_zero);
652
			n = make_nat_literal(n,(unsigned)10, d);
653
		} while (c = *(s++), (c >= char_zero && c <= char_nine));
654
		if (c != MANGLE_sep) {
655
			s--;
656
		}
657
	} else if (c == MANGLE_sep) {
658
		/* Empty sequence of digits */
659
		s++;
660
	} else if (c == MANGLE_neg) {
661
		/* Negate an integer */
662
		s++;
663
		n = unmangle_nat(&s);
664
		n = negate_nat(n);
665
	} else {
666
		/* Read an expression */
667
		EXP e = unmangle_exp(&s, type_sint);
668
		if (!IS_NULL_exp(e)) {
669
			MAKE_nat_calc(e, n);
670
		}
2 7u83 671
	}
6 7u83 672
	*ps = s;
673
	return (n);
2 7u83 674
}
675
 
676
 
677
/*
678
    UNMANGLE A NAMESPACE QUALIFIER
679
 
680
    This routine unmangles a namespace qualifier from the string pointed
681
    to by ps.  Note that all such namespaces are declared as classes even
682
    if they are not in reality.
683
*/
684
 
6 7u83 685
static IDENTIFIER
686
unmangle_nspace(string *ps, NAMESPACE ns, int var)
2 7u83 687
{
6 7u83 688
	string s = *ps;
689
	character c = *s;
690
	IDENTIFIER id = NULL_id;
691
	if (c >= char_zero && c <= char_nine) {
692
		unsigned n = unmangle_no(&s, 0);
693
		if (n) {
694
			HASHID nm;
695
			int ext = 0;
696
			TYPE t = NULL_type;
697
			string p = xustr((gen_size)(n + 1));
698
			string q = p;
699
			while (n) {
700
				c = *s;
701
				if (c) {
702
					if (c == MANGLE_sep && s[1] ==
703
					    MANGLE_sep) {
704
						/* Allow for unicode
705
						 * characters */
706
						if (s[2] == MANGLE_unicode4) {
707
							*(q++) = char_backslash;
708
							c = char_u;
709
							ext = 1;
710
							s += 2;
711
						} else if (s[2] ==
712
							   MANGLE_unicode8) {
713
							*(q++) = char_backslash;
714
							c = char_U;
715
							ext = 1;
716
							s += 2;
717
						}
718
					}
719
					*(q++) = c;
720
					s++;
721
				} else {
722
					*(q++) = char_question;
723
				}
724
				n--;
2 7u83 725
			}
6 7u83 726
			*q = 0;
727
			nm = lookup_name(p, hash(p), ext, lex_identifier);
728
			if (var) {
729
				t = type_sint;
730
				MAKE_id_variable(nm, dspec_extern, ns, crt_loc,
731
						 t, id);
732
			} else {
733
				id = make_class(ns, nm, btype_lang,
734
						dspec_extern, t, t);
735
			}
2 7u83 736
		}
737
 
6 7u83 738
	} else if (c == MANGLE_qual) {
739
		unsigned n;
740
		s++;
741
		n = unmangle_digit(&s);
742
		while (n) {
743
			NAMESPACE pns;
744
			id = unmangle_nspace(&s, ns, 0);
745
			pns = find_namespace(id);
746
			if (!IS_NULL_nspace(pns)) {
747
				ns = pns;
748
			}
749
			n--;
750
		}
2 7u83 751
 
6 7u83 752
	} else if (c == MANGLE_template) {
753
		s++;
754
		id = unmangle_nspace(&s, ns, 0);
755
		if (!IS_NULL_id(id)) {
756
			LIST(TOKEN)args = unmangle_token_args(&s);
757
			TYPE t = make_dummy_class(id, args, btype_lang);
758
			CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
759
			id = DEREF_id(ctype_name(ct));
760
		}
2 7u83 761
 
6 7u83 762
	} else if (c == MANGLE_templ_param) {
763
		TOKEN tok;
764
		s++;
765
		tok = find_token_arg(&s);
766
		if (!IS_NULL_tok(tok) && IS_tok_type(tok)) {
767
			TYPE t = DEREF_type(tok_type_value(tok));
768
			if (!IS_NULL_type(t) && IS_type_compound(t)) {
769
				CLASS_TYPE ct =
770
				    DEREF_ctype(type_compound_defn(t));
771
				id = DEREF_id(ctype_name(ct));
772
			}
773
		}
2 7u83 774
	}
6 7u83 775
	*ps = s;
776
	return (id);
2 7u83 777
}
778
 
779
 
780
/*
781
    UNMANGLE A TOKEN ARGUMENT
782
 
783
    This routine unmangles a token or template argument from the string
784
    pointed to by ps.
785
*/
786
 
6 7u83 787
static TOKEN
788
unmangle_token_arg(string *ps)
2 7u83 789
{
6 7u83 790
	TOKEN tok = NULL_tok;
791
	string s = *ps;
792
	character c = *s;
793
	switch (c) {
794
	case MANGLE_nat: {
795
		/* Integer constant tokens */
796
		NAT n;
797
		s++;
798
		n = unmangle_nat(&s);
799
		if (!IS_NULL_nat(n)) {
800
			MAKE_tok_nat(n, tok);
801
		}
802
		break;
2 7u83 803
	}
6 7u83 804
	case MANGLE_stmt: {
805
		/* Statement tokens */
806
		EXP e;
807
		s++;
808
		e = unmangle_exp(&s, type_void);
809
		if (!IS_NULL_exp(e)) {
810
			MAKE_tok_stmt(e, tok);
811
		}
812
		break;
2 7u83 813
	}
6 7u83 814
	case MANGLE_type: {
815
		/* Type tokens */
816
		TYPE t;
817
		s++;
818
		t = unmangle_type(&s, cv_none, btype_none, 1);
819
		MAKE_tok_type(btype_none, t, tok);
820
		break;
2 7u83 821
	}
6 7u83 822
	default: {
823
		/* Expression tokens */
824
		TYPE t = unmangle_type(&s, cv_none, btype_none, 1);
825
		EXP e = unmangle_exp(&s, t);
826
		if (!IS_NULL_exp(e)) {
827
			MAKE_tok_exp(t, 0, e, tok);
828
		}
829
		break;
2 7u83 830
	}
6 7u83 831
	}
832
	*ps = s;
833
	return (tok);
2 7u83 834
}
835
 
836
 
837
/*
838
    UNMANGLE A LIST OF TOKEN ARGUMENTS
839
 
840
    This routine unmangles a list of token or template arguments from the
841
    string pointed to by ps.
842
*/
843
 
6 7u83 844
static LIST(TOKEN)
845
unmangle_token_args(string *ps)
2 7u83 846
{
6 7u83 847
	string s = *ps;
848
	unsigned n = unmangle_digit(&s);
849
	LIST(TOKEN)args = NULL_list(TOKEN);
850
	while (n) {
851
		TOKEN tok = unmangle_token_arg(&s);
852
		if (!IS_NULL_tok(tok)) {
853
			CONS_tok(tok, args, args);
854
		}
855
		if (*s == 0) {
856
			break;
857
		}
858
		n--;
2 7u83 859
	}
6 7u83 860
	args = REVERSE_list(args);
861
	*ps = s;
862
	return (args);
2 7u83 863
}
864
 
865
 
866
/*
867
    FIND A TOKEN ARGUMENT VALUE
868
 
869
    This routine returns the an argument from the current argument list.
870
    The arguments are numbered from zero.
871
*/
872
 
6 7u83 873
static TOKEN
874
find_token_arg(string *ps)
2 7u83 875
{
6 7u83 876
	unsigned n = unmangle_digit(ps);
877
	LIST(TOKEN)args = crt_unmangle_args;
878
	while (!IS_NULL_list(args)) {
879
		if (n == 0) {
880
			/* Token argument found */
881
			TOKEN arg = DEREF_tok(HEAD_list(args));
882
			return (arg);
883
		}
884
		n--;
885
		args = TAIL_list(args);
2 7u83 886
	}
6 7u83 887
	return (NULL_tok);
2 7u83 888
}
889
 
890
 
891
/*
892
    FIND A FUNCTION PARAMETER TYPE
893
 
894
    This routine returns the mth parameter type from the members mem.
895
    The parameters are numbered from one, with n giving the total number
896
    of parameters.
897
*/
898
 
6 7u83 899
static TYPE
900
unmangle_param(unsigned m, unsigned n, MEMBER mem)
2 7u83 901
{
6 7u83 902
	while (!IS_NULL_member(mem)) {
903
		IDENTIFIER id = DEREF_id(member_id(mem));
904
		if (!IS_NULL_id(id) && IS_id_parameter(id)) {
905
			if (m == n) {
906
				/* Parameter type found */
907
				TYPE t = DEREF_type(id_parameter_type(id));
908
				return (t);
909
			}
910
			m++;
911
		}
912
		mem = DEREF_member(member_next(mem));
2 7u83 913
	}
6 7u83 914
	return (type_error);
2 7u83 915
}
916
 
917
 
918
/*
919
    UNMANGLE A FUNCTION TYPE
920
 
921
    This routine unmangles a function type from the string pointed to
922
    by ps.
923
*/
924
 
6 7u83 925
static TYPE
926
unmangle_func(string *ps, CV_SPEC cv, int ret)
2 7u83 927
{
6 7u83 928
	TYPE t;
929
	string s = *ps;
930
	character c = *s;
931
	if (c == MANGLE_const) {
932
		/* Const member function type */
933
		s++;
934
		cv |= cv_const;
935
		t = unmangle_func(&s, cv, ret);
936
	} else if (c == MANGLE_volatile) {
937
		/* Volatile member function type */
938
		s++;
939
		cv |= cv_volatile;
940
		t = unmangle_func(&s, cv, ret);
941
	} else if (c == MANGLE_c_lang) {
942
		/* C linkage function type */
943
		s++;
944
		cv |= cv_c;
945
		t = unmangle_func(&s, cv, ret);
946
	} else {
947
		/* Read list of parameter types */
948
		TYPE t1;
949
		MEMBER mem;
950
		NAMESPACE ns;
951
		unsigned npars = 0;
952
		int ell = FUNC_NONE;
953
		begin_param(NULL_id);
954
		ns = crt_namespace;
955
		for (;;) {
956
			/* Read parameter types */
957
			unsigned m;
958
			unsigned n = 1;
959
			c = *s;
960
			if (c == 0) {
961
				break;
962
			} else if (c == MANGLE_ellipsis) {
963
				/* Ellipsis */
964
				s++;
965
				ell = FUNC_ELLIPSIS;
966
				break;
967
			} else if (c == MANGLE_repeat) {
968
				/* Repeated parameter */
969
				s++;
970
				m = unmangle_digit(&s);
971
				mem = DEREF_member(nspace_last(ns));
972
				t1 = unmangle_param(m, npars, mem);
973
			} else if (c == MANGLE_multi) {
974
				/* Multiply repeated parameter */
975
				s++;
976
				n = unmangle_digit(&s);
977
				m = unmangle_no(&s, 1);
978
				mem = DEREF_member(nspace_last(ns));
979
				t1 = unmangle_param(m, npars, mem);
980
			} else {
981
				/* Simple parameter type */
982
				t1 = unmangle_type(&s, cv_none, btype_none, 1);
983
				if (IS_type_error(t1))break;
984
			}
985
			while (n) {
986
				/* Declare parameters */
987
				DECL_SPEC ds = dspec_none;
988
				HASHID nm = lookup_anon();
989
				IDENTIFIER pid = DEREF_id(hashid_id(nm));
990
				pid = make_param_decl(ds, t1, pid,
991
						      CONTEXT_PARAMETER);
992
				init_param(pid, NULL_exp);
993
				npars++;
994
				n--;
995
			}
996
		}
997
		t = make_func_type(dummy_ret_type, ell, cv, empty_type_set);
998
		end_param();
999
		if (ret) {
1000
			/* Read return type */
1001
			c = *(s++);
1002
			if (c == MANGLE_sep) {
1003
				t1 = unmangle_type(&s, cv_none, btype_none, 1);
1004
			} else {
1005
				t1 = type_error;
1006
				s--;
1007
			}
1008
			COPY_type(type_func_ret(t), NULL_type);
1009
			t = inject_pre_type(t, t1, 0);
1010
		}
2 7u83 1011
	}
6 7u83 1012
	*ps = s;
1013
	return (t);
2 7u83 1014
}
1015
 
1016
 
1017
/*
1018
    UNMANGLE A TYPE
1019
 
1020
    This routine unmangles a type from the string pointed to by ps.
1021
*/
1022
 
6 7u83 1023
static TYPE
1024
unmangle_type(string *ps, CV_SPEC cv, BASE_TYPE bt, int ret)
2 7u83 1025
{
6 7u83 1026
	TYPE t;
1027
	string s = *ps;
1028
	character c = *(s++);
1029
	switch (c) {
2 7u83 1030
 
6 7u83 1031
	case MANGLE_char:
1032
		t = make_base_type(bt | btype_char);
1033
		break;
1034
	case MANGLE_short:
1035
		t = make_base_type(bt | btype_short);
1036
		break;
1037
	case MANGLE_int:
1038
		t = make_base_type(bt | btype_int);
1039
		break;
1040
	case MANGLE_long:
1041
		t = make_base_type(bt | btype_long);
1042
		break;
1043
	case MANGLE_llong:
1044
		t = make_base_type(bt | btype_llong);
1045
		break;
1046
	case MANGLE_float:
1047
		t = type_float;
1048
		break;
1049
	case MANGLE_double:
1050
		t = type_double;
1051
		break;
1052
	case MANGLE_ldouble:
1053
		t = type_ldouble;
1054
		break;
1055
	case MANGLE_void:
1056
		t = type_void;
1057
		break;
1058
	case MANGLE_bottom:
1059
		t = type_bottom;
1060
		break;
1061
	case MANGLE_bool:
1062
		t = type_bool;
1063
		break;
1064
	case MANGLE_ptrdiff_t:
1065
		t = type_ptrdiff_t;
1066
		break;
1067
	case MANGLE_size_t:
1068
		t = type_size_t;
1069
		break;
1070
	case MANGLE_wchar_t:
1071
		t = type_wchar_t;
1072
		break;
1073
	case MANGLE_signed: {
1074
		/* Signed types */
1075
		bt |= btype_signed;
1076
		t = unmangle_type(&s, cv_none, bt, ret);
1077
		break;
2 7u83 1078
	}
6 7u83 1079
	case MANGLE_unsigned: {
1080
		/* Unsigned types */
1081
		bt |= btype_unsigned;
1082
		t = unmangle_type(&s, cv_none, bt, ret);
1083
		break;
2 7u83 1084
	}
6 7u83 1085
	case MANGLE_const: {
1086
		/* Const types */
1087
		cv |= cv_const;
1088
		t = unmangle_type(&s, cv, bt, ret);
1089
		cv = cv_none;
1090
		break;
2 7u83 1091
	}
6 7u83 1092
	case MANGLE_volatile: {
1093
		/* Volatile types */
1094
		cv |= cv_volatile;
1095
		t = unmangle_type(&s, cv, bt, ret);
1096
		cv = cv_none;
1097
		break;
2 7u83 1098
	}
6 7u83 1099
	case MANGLE_ptr: {
1100
		/* Pointer types */
1101
		TYPE t1 = unmangle_type(&s, cv_none, btype_none, 1);
1102
		MAKE_type_ptr(cv, NULL_type, t);
1103
		t = inject_pre_type(t, t1, 0);
1104
		cv = cv_none;
1105
		break;
2 7u83 1106
	}
6 7u83 1107
	case MANGLE_ref: {
1108
		/* Reference types */
1109
		TYPE t1 = unmangle_type(&s, cv, btype_none, 1);
1110
		MAKE_type_ref(cv_none, NULL_type, t);
1111
		t = inject_pre_type(t, t1, 0);
1112
		cv = cv_none;
1113
		break;
2 7u83 1114
	}
6 7u83 1115
	case MANGLE_ptr_mem: {
1116
		/* Pointer to member types */
1117
		TYPE t1 = unmangle_type(&s, cv_none, btype_none, 1);
1118
		TYPE t2 = unmangle_type(&s, cv_none, btype_none, 1);
1119
		if (IS_type_compound(t1)) {
1120
			CLASS_TYPE c1 = DEREF_ctype(type_compound_defn(t1));
1121
			MAKE_type_ptr_mem(cv, c1, NULL_type, t);
1122
		} else {
1123
			report(crt_loc, ERR_dcl_mptr_class(t1));
1124
			MAKE_type_ptr(cv, NULL_type, t);
1125
		}
1126
		t = inject_pre_type(t, t2, 0);
1127
		cv = cv_none;
1128
		break;
2 7u83 1129
	}
6 7u83 1130
	case MANGLE_func: {
1131
		/* Function types */
1132
		t = unmangle_func(&s, cv, ret);
1133
		cv = cv_none;
1134
		break;
2 7u83 1135
	}
6 7u83 1136
	case MANGLE_array: {
1137
		/* Array types */
1138
		NAT n = unmangle_nat(&s);
1139
		TYPE t1 = unmangle_type(&s, cv, btype_none, 1);
1140
		n = check_array_dim(n);
1141
		MAKE_type_array(cv_none, NULL_type, n, t);
1142
		t = inject_pre_type(t, t1, 0);
1143
		cv = cv_none;
1144
		break;
2 7u83 1145
	}
6 7u83 1146
	case MANGLE_bitfield: {
1147
		/* Bitfield types */
1148
		TYPE t1;
1149
		NAT n = unmangle_nat(&s);
1150
		BASE_TYPE b1 = btype_named;
1151
		if (*s == MANGLE_signed) {
1152
			b1 |= btype_signed;
1153
		}
1154
		t1 = unmangle_type(&s, cv_none, btype_none, 1);
1155
		b1 = get_bitfield_rep(t1, b1);
1156
		t = check_bitfield_type(cv, t1, b1, n, 0);
1157
		cv = cv_none;
1158
		break;
2 7u83 1159
	}
6 7u83 1160
	case MANGLE_template: {
1161
		/* Template class types */
1162
		IDENTIFIER id = unmangle_nspace(&s, global_namespace, 0);
1163
		if (IS_NULL_id(id)) {
1164
			t = type_error;
1165
		} else {
1166
			LIST(TOKEN)args = unmangle_token_args(&s);
1167
			MAKE_type_token(cv, id, args, t);
1168
			cv = cv_none;
1169
		}
1170
		break;
2 7u83 1171
	}
6 7u83 1172
	case MANGLE_templ_param: {
1173
		/* Template parameter types */
1174
		TOKEN tok = find_token_arg(&s);
1175
		if (!IS_NULL_tok(tok) && IS_tok_type(tok)) {
1176
			t = DEREF_type(tok_type_value(tok));
1177
		} else {
1178
			t = type_error;
1179
		}
1180
		break;
2 7u83 1181
	}
6 7u83 1182
	case MANGLE_promote: {
1183
		/* Promotion types */
1184
		TYPE t1 = unmangle_type(&s, cv_none, btype_none, 1);
1185
		t = promote_type(t1);
1186
		break;
2 7u83 1187
	}
6 7u83 1188
	case MANGLE_arith: {
1189
		/* Arithmetic types */
1190
		TYPE t1 = unmangle_type(&s, cv_none, btype_none, 1);
1191
		TYPE t2 = unmangle_type(&s, cv_none, btype_none, 1);
1192
		t = arith_type(t1, t2, NULL_exp, NULL_exp);
1193
		break;
2 7u83 1194
	}
6 7u83 1195
	case MANGLE_literal: {
1196
		/* Literal types */
1197
		NAT n;
1198
		int fit = 0;
1199
		int form = BASE_DECIMAL;
1200
		int suff = SUFFIX_NONE;
1201
		c = *s;
1202
		if (c == MANGLE_octal) {
1203
			form = BASE_OCTAL;
1204
			c = *(++s);
1205
		} else if (c == MANGLE_hex) {
1206
			form = BASE_HEXADECIMAL;
1207
			c = *(++s);
1208
		}
1209
		if (c == MANGLE_unsigned) {
1210
			suff |= SUFFIX_U;
1211
			c = *(++s);
1212
		}
1213
		if (c == MANGLE_long) {
1214
			suff |= SUFFIX_L;
1215
			c = *(++s);
1216
		}
1217
		if (c == MANGLE_llong) {
1218
			suff |= SUFFIX_LL;
1219
			s++;
1220
		}
1221
		n = unmangle_nat(&s);
1222
		if (IS_NULL_nat(n)) {
1223
			n = small_nat[0];
1224
		}
1225
		t = find_literal_type(n, form, suff, NULL_string, &fit);
1226
		break;
2 7u83 1227
	}
6 7u83 1228
	case MANGLE_self: {
1229
		/* Parent class type */
1230
		IDENTIFIER self = crt_unmangle_class;
1231
		if (IS_NULL_id(self)) {
1232
			t = type_error;
1233
		} else {
1234
			t = DEREF_type(id_class_name_etc_defn(self));
1235
		}
1236
		break;
2 7u83 1237
	}
6 7u83 1238
	case char_zero:
1239
	case char_one:
1240
	case char_two:
1241
	case char_three:
1242
	case char_four:
1243
	case char_five:
1244
	case char_six:
1245
	case char_seven:
1246
	case char_eight:
1247
	case char_nine:
1248
	case MANGLE_qual: {
1249
		/* Named types */
1250
		IDENTIFIER id;
1251
		s--;
1252
		id = unmangle_nspace(&s, global_namespace, 0);
1253
		if (IS_NULL_id(id)) {
1254
			t = type_error;
1255
		} else {
1256
			t = DEREF_type(id_class_name_etc_defn(id));
1257
		}
1258
		break;
2 7u83 1259
	}
1260
 
6 7u83 1261
	default: {
1262
		/* Invalid mangled types */
1263
		if (bt == btype_none && cv == cv_none) {
1264
			t = type_error;
1265
		} else {
1266
			t = make_base_type(bt | btype_int);
1267
		}
1268
		s--;
1269
		break;
2 7u83 1270
	}
6 7u83 1271
	}
1272
	if (cv) {
1273
		t = qualify_type(t, cv, 0);
1274
	}
1275
	*ps = s;
1276
	return (t);
2 7u83 1277
}
1278
 
1279
 
1280
/*
1281
    UNMANGLE AN IDENTIFIER NAME
1282
 
1283
    This routine unmangles the identifier s into the buffer bf.
1284
*/
1285
 
6 7u83 1286
static string
1287
unmangle_name(string s, BUFFER *bf)
2 7u83 1288
{
6 7u83 1289
	int func = 0;
1290
	int op = lex_identifier;
1291
	IDENTIFIER id = NULL_id;
1292
	HASHID nm = NULL_hashid;
2 7u83 1293
 
6 7u83 1294
	/* Check names beginning with '__' */
1295
	if (s[0] == '_' && s[1] == '_') {
1296
		string s0 = s + 2;
1297
		op = unmangle_op(&s0);
1298
		if (op == lex_unknown) {
1299
#if (TDF_major < 4)
1300
			if (ustrseq(s, "__MAIN__")) {
1301
				s = ustrlit("main");
1302
			}
2 7u83 1303
#endif
6 7u83 1304
			bfputs(bf, s);
1305
			return (NULL);
1306
		}
1307
		s = s0;
2 7u83 1308
	}
1309
 
6 7u83 1310
	/* Read identifier name */
1311
	switch (op) {
1312
	case lex_identifier: {
1313
		/* Identifier name */
1314
		character c;
1315
		int ext = 0;
1316
		unsigned long h;
1317
		BUFFER *tf = clear_buffer(&token_buff, NIL(FILE));
1318
		while (c = *s, c != 0) {
1319
			if (c == MANGLE_sep && s[1] == MANGLE_sep) {
1320
				c = s[2];
1321
				if (c == MANGLE_unicode4) {
1322
					bfputc(tf, char_backslash);
1323
					c = char_u;
1324
					ext = 1;
1325
					s += 2;
1326
				} else if (c == MANGLE_unicode8) {
1327
					bfputc(tf, char_backslash);
1328
					c = char_U;
1329
					ext = 1;
1330
					s += 2;
1331
				} else {
1332
					break;
1333
				}
1334
			}
1335
			bfputc(tf,(int)c);
1336
			s++;
2 7u83 1337
		}
6 7u83 1338
		bfputc(tf, 0);
1339
		h = hash(tf->start);
1340
		nm = lookup_name(tf->start, h, ext, lex_unknown);
1341
		id = DEREF_id(hashid_id(nm));
1342
		break;
2 7u83 1343
	}
6 7u83 1344
	case lex_type_Hname:
1345
	case lex_destructor_Hname: {
1346
		/* Constructor and destructor names */
1347
		func = 1;
1348
		break;
2 7u83 1349
	}
6 7u83 1350
	case lex_operator: {
1351
		/* Conversion function name */
1352
		TYPE t = unmangle_type(&s, cv_none, btype_none, 1);
1353
		nm = lookup_conv(t);
1354
		id = DEREF_id(hashid_id(nm));
1355
		func = 1;
1356
		break;
2 7u83 1357
	}
6 7u83 1358
	case lex_auto: {
1359
		/* Anonymous identifier */
1360
		bfprintf(bf, "<anon>");
1361
		return (NULL);
2 7u83 1362
	}
6 7u83 1363
	case lex_static: {
1364
		/* Local static variable */
1365
		bfprintf(bf, "<static>");
1366
		return (NULL);
2 7u83 1367
	}
6 7u83 1368
	case lex_typeof: {
1369
		/* Run-time type information */
1370
		TYPE t = unmangle_type(&s, cv_none, btype_none, 1);
1371
		bfprintf(bf, "typeid ( ");
1372
		IGNORE print_type(t, bf, 0);
1373
		bfprintf(bf, " )");
1374
		return (s);
2 7u83 1375
	}
6 7u83 1376
	case lex_virtual: {
1377
		/* Virtual function table */
1378
		int sep = 0;
1379
		bfprintf(bf, "vtable ( ");
1380
		for (;;) {
1381
			id = unmangle_nspace(&s, global_namespace, 0);
1382
			if (IS_NULL_id(id)) {
1383
				break;
1384
			}
1385
			if (sep) {
1386
				bfprintf(bf, "::");
1387
			}
1388
			IGNORE print_id_long(id, qual_none, bf, 0);
1389
			sep = 1;
1390
		}
1391
		if (!sep) {
1392
			bfprintf(bf, "<error>");
1393
		}
1394
		bfprintf(bf, " )");
1395
		return (s);
2 7u83 1396
	}
1397
 
6 7u83 1398
	default: {
1399
		/* Operator name */
1400
		nm = lookup_op(op);
1401
		if (!IS_NULL_hashid(nm)) {
1402
			id = DEREF_id(hashid_id(nm));
1403
			func = 1;
1404
		}
1405
		break;
2 7u83 1406
	}
1407
	}
1408
 
6 7u83 1409
	/* Unmangle identifier namespace and type */
1410
	if (s[0] == MANGLE_sep && s[1] == MANGLE_sep) {
1411
		TYPE t;
1412
		string s0 = s + 2;
1413
		NAMESPACE pns = global_namespace;
1414
		IDENTIFIER pid = unmangle_nspace(&s0, pns, 0);
1415
		character c = *s0;
1416
		if (c == MANGLE_func_templ) {
1417
			/* Allow for template functions */
1418
			s0++;
1419
			crt_unmangle_args = unmangle_token_args(&s0);
1420
			if (*s0 == MANGLE_sep) {
1421
				s0++;
1422
			}
1423
		}
2 7u83 1424
 
6 7u83 1425
		/* Unmangle identifier type */
1426
		if (func) {
1427
			crt_unmangle_class = pid;
1428
			t = unmangle_func(&s0, cv_none, 0);
1429
		} else {
1430
			if (c == 0 && !IS_NULL_id(pid)) {
1431
				t = DEREF_type(id_class_name_etc_defn(pid));
1432
				pid = NULL_id;
1433
			} else {
1434
				crt_unmangle_class = pid;
1435
				t = unmangle_type(&s0, cv_none, btype_none, 0);
1436
			}
2 7u83 1437
		}
6 7u83 1438
		if (IS_NULL_id(pid)) {
1439
			member_func_type(NULL_ctype, id_function_tag, t);
1440
		}
1441
 
1442
		/* Look up constructor and destructor names */
1443
		if (!IS_NULL_id(pid)) {
1444
			TYPE p = DEREF_type(id_class_name_etc_defn(pid));
1445
			if (IS_type_compound(p)) {
1446
				CLASS_TYPE ct =
1447
				    DEREF_ctype(type_compound_defn(p));
1448
				pns = DEREF_nspace(ctype_member(ct));
1449
				if (op == lex_type_Hname) {
1450
					id = DEREF_id(ctype_constr(ct));
1451
					nm = DEREF_hashid(id_name(id));
1452
				} else if (op == lex_destructor_Hname) {
1453
					id = DEREF_id(ctype_destr(ct));
1454
					nm = DEREF_hashid(id_name(id));
1455
				}
1456
			}
1457
		}
1458
		if (IS_NULL_hashid(nm)) {
1459
			nm = KEYWORD(lex_zzzz);
1460
		}
1461
 
1462
		/* Create result identifier */
1463
		MAKE_id_function(nm, dspec_extern, pns, crt_loc, t, NULL_id,
1464
				 id);
1465
		if (c == MANGLE_func_templ) {
1466
			/* Set up template function arguments */
1467
			TYPE form;
1468
			DECL_SPEC ds = (dspec_extern | dspec_instance);
1469
			MAKE_type_token(cv_none, id, crt_unmangle_args, form);
1470
			MAKE_id_function(nm, ds, pns, crt_loc, t, NULL_id, id);
1471
			COPY_type(id_function_form(id), form);
1472
		}
1473
		crt_unmangle_args = NULL_list(TOKEN);
1474
		crt_unmangle_class = NULL_id;
1475
		s = s0;
2 7u83 1476
	}
1477
 
6 7u83 1478
	/* Print identifier to buffer */
1479
	if (IS_NULL_id(id)) {
1480
		bfprintf(bf, "<error>");
1481
		s = NULL;
1482
	} else {
1483
		print_id_desc++;
1484
		IGNORE print_id_long(id, qual_none, bf, 0);
1485
		print_id_desc--;
2 7u83 1486
	}
6 7u83 1487
	return (s);
2 7u83 1488
}
1489
 
1490
 
1491
/*
1492
    INITIALISE UNMANGLING ROUTINES
1493
 
1494
    This routine initialises the unmangling routines.
1495
*/
1496
 
6 7u83 1497
static void
1498
init_unmangle(void)
2 7u83 1499
{
6 7u83 1500
	static int done = 0;
1501
	if (!done) {
1502
		MAKE_type_pre(cv_none, btype_none, qual_none, dummy_ret_type);
1503
		done = 1;
1504
	}
1505
	return;
2 7u83 1506
}
1507
 
1508
 
1509
/*
1510
    END OF LANGUAGE DEPENDENT ROUTINES
1511
 
1512
    The remaining routine is the only one included in the C producer.
1513
*/
1514
 
1515
#endif
1516
 
1517
 
1518
/*
1519
    UNMANGLE A LIST OF IDENTIFIER NAMES
1520
 
1521
    This routine unmangles the list of identifier names p to the file f.
1522
*/
1523
 
6 7u83 1524
void
1525
unmangle_list(LIST(string)p, FILE *f, int pre)
2 7u83 1526
{
1527
#if LANGUAGE_CPP
6 7u83 1528
	init_unmangle();
2 7u83 1529
#endif
6 7u83 1530
	while (!IS_NULL_list(p)) {
1531
		string s = DEREF_string(HEAD_list(p));
1532
		if (s) {
1533
			BUFFER *bf = clear_buffer(&mangle_buff, f);
1534
			if (pre) {
1535
				/* Print mapping information */
1536
				bfprintf(bf, "%s -> ", s);
1537
			}
2 7u83 1538
#if LANGUAGE_CPP
6 7u83 1539
			s = unmangle_name(s, bf);
1540
			if (s && *s) {
1541
				bfprintf(bf, " ?");
1542
			}
2 7u83 1543
#else
6 7u83 1544
			bfputs(bf, s);
2 7u83 1545
#endif
6 7u83 1546
			bfputc(bf, '\n');
1547
			output_buffer(bf, 1);
1548
		}
1549
		p = TAIL_list(p);
2 7u83 1550
	}
6 7u83 1551
	fflush_v(f);
1552
	return;
2 7u83 1553
}