Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/tendra5-amd64/src/producers/common/output/mangle.c – Rev 6

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
/*
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 <limits.h>
63
#include "version.h"
64
#include "system.h"
65
#include "c_types.h"
66
#include "ctype_ops.h"
67
#include "etype_ops.h"
68
#include "exp_ops.h"
69
#include "flt_ops.h"
70
#include "ftype_ops.h"
71
#include "graph_ops.h"
72
#include "hashid_ops.h"
73
#include "id_ops.h"
74
#include "itype_ops.h"
75
#include "nat_ops.h"
76
#include "nspace_ops.h"
77
#include "off_ops.h"
78
#include "tok_ops.h"
79
#include "type_ops.h"
80
#include "error.h"
81
#include "option.h"
82
#include "tdf.h"
83
#include "basetype.h"
84
#include "buffer.h"
85
#include "capsule.h"
86
#include "char.h"
87
#include "chktype.h"
88
#include "class.h"
89
#include "constant.h"
90
#include "copy.h"
91
#include "hash.h"
92
#include "lex.h"
93
#include "literal.h"
94
#include "mangle.h"
95
#include "operator.h"
96
#include "print.h"
97
#include "shape.h"
98
#include "syntax.h"
99
#include "template.h"
100
#include "tok.h"
101
#include "ustring.h"
102
#include "variable.h"
103
#include "xalloc.h"
104
 
105
 
106
/*
107
    MANGLED FORMS OF BASIC TYPES
108
 
109
    This table gives the mangled forms of the built-in types.
110
*/
111
 
6 7u83 112
char mangle_ntype[ORDER_ntype][3] = {
113
	{ MANGLE_error, 0, 0 },			/* ntype_none */
114
	{ MANGLE_char, 0, 0 },			/* ntype_char */
115
	{ MANGLE_signed, MANGLE_char, 0 },	/* ntype_schar */
116
	{ MANGLE_unsigned, MANGLE_char, 0 },	/* ntype_uchar */
117
	{ MANGLE_short, 0, 0 },			/* ntype_sshort */
118
	{ MANGLE_unsigned, MANGLE_short, 0 },	/* ntype_ushort */
119
	{ MANGLE_int, 0, 0 },			/* ntype_sint */
120
	{ MANGLE_unsigned, MANGLE_int, 0 },	/* ntype_uint */
121
	{ MANGLE_long, 0, 0 },			/* ntype_slong */
122
	{ MANGLE_unsigned, MANGLE_long, 0 },	/* ntype_ulong */
123
	{ MANGLE_llong, 0, 0 },			/* ntype_sllong */
124
	{ MANGLE_unsigned, MANGLE_llong, 0 },	/* ntype_ullong */
125
	{ MANGLE_float, 0, 0 },			/* ntype_float */
126
	{ MANGLE_double, 0, 0 },		/* ntype_double */
127
	{ MANGLE_ldouble, 0, 0 },		/* ntype_ldouble */
128
	{ MANGLE_void, 0, 0 },			/* ntype_void */
129
	{ MANGLE_bottom, 0, 0 },		/* ntype_bottom */
130
	{ MANGLE_bool, 0, 0 },			/* ntype_bool */
131
	{ MANGLE_ptrdiff_t, 0, 0 },		/* ntype_ptrdiff_t */
132
	{ MANGLE_size_t, 0, 0 },		/* ntype_size_t */
133
	{ MANGLE_wchar_t, 0, 0 },		/* ntype_wchar_t */
134
	{ MANGLE_ellipsis, 0, 0 }		/* ntype_ellipsis */
135
};
2 7u83 136
 
137
 
138
/*
139
    NAME MANGLING FLAGS
140
 
141
    The following flags are used to control the form of the mangled names.
142
*/
143
 
6 7u83 144
int mangle_objects = 1;
145
int mangle_signature = 1;
146
unsigned long mangle_length = ULONG_MAX;
2 7u83 147
 
148
 
149
/*
150
    FORWARD DECLARATIONS
151
 
152
    A couple of forward declarations are necessary because of the
153
    recursive nature of many of the routines.
154
*/
155
 
6 7u83 156
static int nspace_depth(NAMESPACE);
157
static string mangle_op(int);
158
static string mangle_hashid(HASHID, int *, int);
159
static void mangle_exp(BUFFER *, EXP, int);
160
static void mangle_nat(BUFFER *, NAT, int);
161
static void mangle_nspace(BUFFER *, NAMESPACE, int);
162
static void mangle_ctype(BUFFER *, CLASS_TYPE, int);
163
static void mangle_token(BUFFER *, IDENTIFIER, LIST(TOKEN), int, int);
164
static void mangle_type(BUFFER *, TYPE, int, int);
2 7u83 165
 
166
 
167
/*
168
    CURRENT CLASS TYPE
169
 
170
    This variable is used to hold the parent class of an identifier during
171
    name mangling.
172
*/
173
 
6 7u83 174
static CLASS_TYPE crt_mangle_class = NULL_ctype;
2 7u83 175
 
176
 
177
/*
178
    FIND AN IDENTIFIER DEPTH
179
 
180
    This routine finds the depth of the identifier id.  This is one more
181
    than the depth of the enclosing namespace if id is a simple identifier
182
    and -1 otherwise.
183
*/
184
 
6 7u83 185
static int
186
ident_depth(IDENTIFIER id)
2 7u83 187
{
6 7u83 188
	if (!IS_NULL_id(id)) {
189
		HASHID nm = DEREF_hashid(id_name(id));
190
		if (!IS_hashid_anon(nm)) {
191
			/* Simple identifiers */
192
			NAMESPACE ns = DEREF_nspace(id_parent(id));
193
			int n = nspace_depth(ns);
194
			if (n >= 0) {
195
				return (n + 1);
196
			}
197
		}
2 7u83 198
	}
6 7u83 199
	return (-1);
2 7u83 200
}
201
 
202
 
203
/*
204
    FIND A NAMESPACE DEPTH
205
 
206
    This routine finds the depth of the namespace ns - that is the number
207
    of namespaces lying between it and its enclosing global namespace.
208
    The routine returns -1 if any intermediate namespace is unnamed.
209
*/
210
 
6 7u83 211
static int
212
nspace_depth(NAMESPACE ns)
2 7u83 213
{
6 7u83 214
	if (!IS_NULL_nspace(ns)) {
215
		switch (TAG_nspace(ns)) {
216
		case nspace_named_tag:
217
		case nspace_ctype_tag: {
218
			/* Named and class namespaces */
219
			IDENTIFIER id = DEREF_id(nspace_name(ns));
220
			int n = ident_depth(id);
221
			return (n);
2 7u83 222
		}
6 7u83 223
		case nspace_global_tag: {
224
			/* The global namespace */
225
			return (0);
226
		}
227
		case nspace_unnamed_tag: {
228
			/* Unnamed namespaces */
229
			if (output_all) {
230
				IDENTIFIER id = DEREF_id(nspace_name(ns));
231
				NAMESPACE pns = DEREF_nspace(id_parent(id));
232
				int n = nspace_depth(pns);
233
				if (n >= 0) {
234
					return (n + 1);
235
				}
236
			}
237
			break;
238
		}
239
		}
2 7u83 240
	}
6 7u83 241
	return (-1);
2 7u83 242
}
243
 
244
 
245
/*
246
    NAME MANGLING BUFFER
247
 
248
    This buffer is used to build up the mangled names.
249
*/
250
 
6 7u83 251
BUFFER mangle_buff = NULL_buff;
252
static BUFFER name_buff = NULL_buff;
2 7u83 253
 
254
 
255
/*
256
    ADD A NUMBER TO THE BUFFER
257
 
258
    This routine adds the number n to the buffer position given by bf.
259
*/
260
 
6 7u83 261
static void
262
mangle_number(BUFFER *bf, unsigned long n, int e)
2 7u83 263
{
6 7u83 264
	if (n < 10) {
265
		int d = '0' + (int)n;
266
		bfputc(bf, d);
267
	} else {
268
		if (e > 1) {
269
			bfputc(bf, MANGLE_sep);
270
		}
271
		bfprintf(bf, "%lu", n);
272
		if (e > 0) {
273
			bfputc(bf, MANGLE_sep);
274
		}
275
	}
276
	return;
2 7u83 277
}
278
 
279
 
280
/*
281
    ADD AN IDENTIFIER NAME TO THE BUFFER
282
 
283
    This routine adds the mangled form of the identifier id to the buffer
284
    position given by bf.  d gives the associated identifier depth.
285
*/
286
 
6 7u83 287
static void
288
mangle_id(BUFFER *bf, IDENTIFIER id, int d)
2 7u83 289
{
6 7u83 290
	if (d >= 0) {
291
		int copy = 0;
292
		HASHID nm = DEREF_hashid(id_name(id));
293
		string s = mangle_hashid(nm, &copy, 1);
294
		if (s) {
295
			unsigned long n = (unsigned long)ustrlen(s);
296
			if (d > 1) {
297
				/* Output name qualifier */
298
				NAMESPACE ns = DEREF_nspace(id_parent(id));
299
				bfputc(bf, MANGLE_qual);
300
				mangle_number(bf,(unsigned long)d, 2);
301
				mangle_nspace(bf, ns, d - 1);
302
			}
303
			mangle_number(bf, n, 0);
304
			bfputs(bf, s);
305
		} else {
306
			/* Invalid identifier */
307
			bfputc(bf, MANGLE_error);
308
		}
2 7u83 309
	} else {
6 7u83 310
		/* Invalid identifier */
311
		bfputc(bf, MANGLE_error);
2 7u83 312
	}
6 7u83 313
	return;
2 7u83 314
}
315
 
316
 
317
/*
318
    ADD A NAMESPACE NAME TO THE BUFFER
319
 
320
    This routine adds the mangled form of the name of the namespace ns
321
    to the buffer position given by bf.  d gives the associated namespace
322
    depth.
323
*/
324
 
6 7u83 325
static void
326
mangle_nspace(BUFFER *bf, NAMESPACE ns, int d)
2 7u83 327
{
6 7u83 328
	if (!IS_nspace_global(ns)) {
329
		IDENTIFIER id = DEREF_id(nspace_name(ns));
330
		if (IS_id_class_name(id)) {
331
			TYPE t = DEREF_type(id_class_name_defn(id));
332
			if (IS_type_compound(t)) {
333
				CLASS_TYPE ct =
334
				    DEREF_ctype(type_compound_defn(t));
335
				mangle_ctype(bf, ct, d);
336
				return;
337
			}
338
		}
339
		mangle_id(bf, id, d);
2 7u83 340
	}
6 7u83 341
	return;
2 7u83 342
}
343
 
344
 
345
/*
346
    ADD AN EXPRESSION OPERATION TO THE BUFFER
347
 
348
    This routine adds the binary expression operation 'a op b' to the
349
    buffer position given by bf.
350
*/
351
 
6 7u83 352
static void
353
mangle_exp_op(BUFFER *bf, int op, EXP a, EXP b, int n, int rec)
2 7u83 354
{
6 7u83 355
	string s = mangle_op(op);
356
	bfputc(bf, MANGLE_op);
357
	bfprintf(bf, "%s%d", s + 2, n);
358
	if (!IS_NULL_exp(a)) {
359
		mangle_exp(bf, a, rec);
360
	}
361
	if (!IS_NULL_exp(b)) {
362
		mangle_exp(bf, b, rec);
363
	}
364
	return;
2 7u83 365
}
366
 
367
 
368
/*
369
    ADD AN EXPRESSION TO THE BUFFER
370
 
371
    This routine adds the expression e to the buffer position given by bf.
372
*/
373
 
6 7u83 374
static void
375
mangle_exp(BUFFER *bf, EXP e, int rec)
2 7u83 376
{
6 7u83 377
	if (!IS_NULL_exp(e)) {
378
		ASSERT(ORDER_exp == 88);
379
		switch (TAG_exp(e)) {
380
		case exp_identifier_tag:
381
		case exp_member_tag:
382
		case exp_ambiguous_tag:
383
		case exp_undeclared_tag: {
384
			/* Identifier expressions */
385
			IDENTIFIER id = DEREF_id(exp_identifier_etc_id(e));
386
			int d = ident_depth(id);
387
			bfputc(bf, MANGLE_sep);
388
			mangle_id(bf, id, d);
389
			break;
2 7u83 390
		}
6 7u83 391
		case exp_int_lit_tag: {
392
			/* Integer literals */
393
			NAT n = DEREF_nat(exp_int_lit_nat(e));
394
			mangle_nat(bf, n, rec);
395
			break;
2 7u83 396
		}
6 7u83 397
		case exp_char_lit_tag: {
398
			/* Character literals */
399
			STRING s = DEREF_str(exp_char_lit_str(e));
400
			NAT n = eval_char_lit(s);
401
			mangle_nat(bf, n, rec);
402
			break;
2 7u83 403
		}
6 7u83 404
		case exp_float_lit_tag: {
405
			/* Floating-point literals */
406
			FLOAT flt = DEREF_flt(exp_float_lit_flt(e));
407
			string i = DEREF_string(flt_simple_int_part(flt));
408
			string d = DEREF_string(flt_simple_frac_part(flt));
409
			NAT n = DEREF_nat(flt_simple_exponent(flt));
410
			bfputc(bf, MANGLE_op);
411
			bfprintf(bf, "f%sd%s", i, d);
412
			if (is_zero_nat(n)) {
413
				bfputc(bf, MANGLE_sep);
414
			} else {
415
				bfputc(bf, 'e');
416
				mangle_nat(bf, n, 0);
417
			}
418
			break;
419
		}
420
		case exp_null_tag:
421
		case exp_zero_tag:
422
		case exp_value_tag: {
423
			/* Null pointers */
424
			mangle_nat(bf, small_nat[0], 0);
425
			break;
426
		}
427
		case exp_paren_tag:
428
		case exp_copy_tag: {
429
			/* Parenthesised expressions */
430
			EXP a = DEREF_exp(exp_paren_etc_arg(e));
431
			mangle_exp(bf, a, rec);
432
			break;
433
		}
434
		case exp_indir_tag: {
435
			/* Indirection expressions */
436
			EXP a = DEREF_exp(exp_indir_ptr(e));
437
			mangle_exp(bf, a, rec);
438
			break;
439
		}
440
		case exp_address_tag: {
441
			/* Address expressions */
442
			EXP a = DEREF_exp(exp_address_arg(e));
443
			mangle_exp(bf, a, rec);
444
			break;
445
		}
446
		case exp_address_mem_tag: {
447
			/* Address expressions */
448
			EXP a = DEREF_exp(exp_address_mem_arg(e));
449
			mangle_exp(bf, a, rec);
450
			break;
451
		}
452
		case exp_negate_tag:
453
		case exp_compl_tag:
454
		case exp_not_tag:
455
		case exp_abs_tag: {
456
			/* Unary expressions */
457
			int op = op_token(e, lex_unknown);
458
			EXP a = DEREF_exp(exp_negate_etc_arg(e));
459
			mangle_exp_op(bf, op, a, NULL_exp, 1, rec);
460
			break;
461
		}
462
		case exp_plus_tag:
463
		case exp_minus_tag:
464
		case exp_mult_tag:
465
		case exp_div_tag:
466
		case exp_rem_tag:
467
		case exp_and_tag:
468
		case exp_or_tag:
469
		case exp_xor_tag:
470
		case exp_log_and_tag:
471
		case exp_log_or_tag:
472
		case exp_lshift_tag:
473
		case exp_rshift_tag:
474
		case exp_max_tag:
475
		case exp_min_tag: {
476
			/* Binary expressions */
477
			int op = op_token(e, lex_unknown);
478
			EXP a = DEREF_exp(exp_plus_etc_arg1(e));
479
			EXP b = DEREF_exp(exp_plus_etc_arg2(e));
480
			mangle_exp_op(bf, op, a, b, 2, rec);
481
			break;
482
		}
483
		case exp_test_tag: {
484
			/* Test expressions */
485
			int op = op_token(e, lex_unknown);
486
			EXP a = DEREF_exp(exp_test_arg(e));
487
			mangle_exp_op(bf, op, a, NULL_exp, 1, rec);
488
			break;
489
		}
490
		case exp_compare_tag: {
491
			/* Comparison expressions */
492
			int op = op_token(e, lex_unknown);
493
			EXP a = DEREF_exp(exp_compare_arg1(e));
494
			EXP b = DEREF_exp(exp_compare_arg2(e));
495
			mangle_exp_op(bf, op, a, b, 2, rec);
496
			break;
497
		}
498
		case exp_cast_tag: {
499
			/* Cast expressions */
500
			EXP a = DEREF_exp(exp_cast_arg(e));
501
			mangle_exp(bf, a, rec);
502
			break;
503
		}
504
		case exp_base_cast_tag: {
505
			/* Base cast expressions */
506
			EXP a = DEREF_exp(exp_base_cast_arg(e));
507
			mangle_exp(bf, a, rec);
508
			break;
509
		}
510
		case exp_add_ptr_tag: {
511
			/* Pointer addition */
512
			EXP a = DEREF_exp(exp_add_ptr_ptr(e));
513
			/* NOT YET IMPLEMENTED */
514
			mangle_exp(bf, a, rec);
515
			break;
516
		}
517
		case exp_offset_size_tag: {
518
			/* Offset size */
519
			OFFSET a = DEREF_off(exp_offset_size_off(e));
520
			if (IS_off_type(a)) {
521
				/* Allow for sizeof expressions */
522
				TYPE s = DEREF_type(exp_offset_size_step(e));
523
				if (EQ_type(s, type_char)) {
524
					int op = lex_sizeof;
525
					mangle_exp_op(bf, op, NULL_exp,
526
						      NULL_exp, 1, rec);
527
					s = DEREF_type(off_type_type(a));
528
					mangle_type(bf, s, 2, 1);
529
					break;
530
				}
531
			}
532
			/* NOT YET IMPLEMENTED */
533
			bfputc(bf, MANGLE_error);
534
			break;
535
		}
536
		case exp_comma_tag: {
537
			/* Comma expressions */
538
			LIST(EXP)p = DEREF_list(exp_comma_args(e));
539
			while (!IS_NULL_list(p)) {
540
				EXP a = DEREF_exp(HEAD_list(p));
541
				p = TAIL_list(p);
542
				if (IS_NULL_list(p)) {
543
					mangle_exp(bf, a, rec);
544
				} else {
545
					mangle_exp_op(bf, lex_comma, a,
546
						      NULL_exp, 2, rec);
547
				}
548
			}
549
			break;
550
		}
551
		case exp_if_stmt_tag: {
552
			/* Conditional expressions */
553
			EXP c = DEREF_exp(exp_if_stmt_cond(e));
554
			EXP a = DEREF_exp(exp_if_stmt_true_code(e));
555
			EXP b = DEREF_exp(exp_if_stmt_false_code(e));
556
			mangle_exp_op(bf, lex_cond_Hop, c, a, 3, rec);
557
			mangle_exp(bf, b, rec);
558
			break;
559
		}
560
		case exp_rtti_type_tag: {
561
			/* Run-time type information expressions */
562
			TYPE s = DEREF_type(exp_rtti_type_arg(e));
563
			int op = DEREF_int(exp_rtti_type_op(e));
564
			mangle_exp_op(bf, op, NULL_exp, NULL_exp, 1, rec);
565
			mangle_type(bf, s, 2, 1);
566
			break;
567
		}
568
		case exp_token_tag: {
569
			/* Tokenised expressions */
570
			IDENTIFIER id = DEREF_id(exp_token_tok(e));
571
			LIST(TOKEN)args = DEREF_list(exp_token_args(e));
572
			mangle_token(bf, id, args, -2, 1);
573
			break;
574
		}
575
		case exp_location_tag: {
576
			/* Location expressions */
577
			EXP a = DEREF_exp(exp_location_arg(e));
578
			mangle_exp(bf, a, rec);
579
			break;
580
		}
581
		case exp_dummy_tag: {
582
			/* Dummy expressions */
583
			EXP a = DEREF_exp(exp_dummy_value(e));
584
			mangle_exp(bf, a, rec);
585
			break;
586
		}
587
		default: {
588
			bfputc(bf, MANGLE_error);
589
			break;
590
		}
591
		}
2 7u83 592
	}
6 7u83 593
	return;
2 7u83 594
}
595
 
596
 
597
/*
598
    ADD AN INTEGER CONSTANT TO THE BUFFER
599
 
600
    This routine adds the integer constant n to the buffer position given
601
    by bf.
602
*/
603
 
6 7u83 604
static void
605
mangle_nat(BUFFER *bf, NAT n, int rec)
2 7u83 606
{
6 7u83 607
	if (IS_NULL_nat(n)) {
608
		bfputc(bf, MANGLE_sep);
609
	} else {
610
		unsigned tag = TAG_nat(n);
611
		if (tag == nat_neg_tag) {
612
			/* Negative values */
613
			bfputc(bf, MANGLE_neg);
614
			n = DEREF_nat(nat_neg_arg(n));
615
			tag = TAG_nat(n);
2 7u83 616
		}
6 7u83 617
		switch (tag) {
618
		case nat_calc_tag: {
619
			/* Calculated values */
620
			EXP e = DEREF_exp(nat_calc_value(n));
621
			if (rec) {
622
				e = eval_exp(e, 1);
623
			}
624
			mangle_exp(bf, e, 0);
625
			break;
626
		}
627
		case nat_token_tag: {
628
			/* Tokenised values */
629
			IDENTIFIER id = DEREF_id(nat_token_tok(n));
630
			LIST(TOKEN)args = DEREF_list(nat_token_args(n));
631
			mangle_token(bf, id, args, -2, 1);
632
			break;
633
		}
634
		default: {
635
			/* Simple values */
636
			unsigned long v = get_nat_value(n);
637
			if (v == EXTENDED_MAX) {
638
				/* Really large values */
639
				IGNORE print_nat(n, 0, bf, 0);
640
			} else {
641
				mangle_number(bf, v, 0);
642
			}
643
			bfputc(bf, MANGLE_sep);
644
			break;
645
		}
646
		}
2 7u83 647
	}
6 7u83 648
	return;
2 7u83 649
}
650
 
651
 
652
/*
653
    FIND THE MANGLED FORM OF A LITERAL TYPE
654
 
655
    This routine finds the mangled form of the integer literal type it.
656
*/
657
 
6 7u83 658
string
659
mangle_literal(INT_TYPE it)
2 7u83 660
{
6 7u83 661
	static character buff[20];
662
	string s = buff;
663
	int form = DEREF_int(itype_literal_form(it));
664
	int suff = DEREF_int(itype_literal_suff(it));
665
	*(s++) = MANGLE_literal;
666
	if (form == BASE_OCTAL) {
667
		*(s++) = MANGLE_octal;
668
	} else if (form == BASE_HEXADECIMAL) {
669
		*(s++) = MANGLE_hex;
670
	}
671
	if (suff & SUFFIX_U) {
672
		*(s++) = MANGLE_unsigned;
673
	}
674
	if (suff & SUFFIX_L) {
675
		*(s++) = MANGLE_long;
676
	}
677
	if (suff & SUFFIX_LL) {
678
		*(s++) = MANGLE_llong;
679
	}
680
	*s = 0;
681
	return (buff);
2 7u83 682
}
683
 
684
 
685
/*
686
    ADD AN INTEGRAL TYPE TO THE BUFFER
687
 
688
    This routine adds the mangled form of the integral type it to the
689
    buffer position given by bf.
690
*/
691
 
6 7u83 692
static void
693
mangle_itype(BUFFER *bf, INT_TYPE it)
2 7u83 694
{
6 7u83 695
	switch (TAG_itype(it)) {
696
	case itype_basic_tag: {
697
		/* Basic integral types */
698
		BUILTIN_TYPE n = DEREF_ntype(itype_basic_no(it));
699
		bfputs(bf, ustrlit(mangle_ntype[n]));
700
		break;
2 7u83 701
	}
6 7u83 702
	case itype_bitfield_tag: {
703
		/* Bitfield types */
704
		TYPE s = DEREF_type(itype_bitfield_sub(it));
705
		NAT n = DEREF_nat(itype_bitfield_size(it));
706
		BASE_TYPE rep = DEREF_btype(itype_bitfield_rep(it));
707
		bfputc(bf, MANGLE_bitfield);
708
		mangle_nat(bf, n, 1);
709
		if (rep & btype_signed) {
710
			bfputc(bf, MANGLE_signed);
711
			if (rep & btype_char) {
712
				s = type_char;
713
			}
714
		}
715
		mangle_type(bf, s, 2, 1);
716
		break;
2 7u83 717
	}
6 7u83 718
	case itype_promote_tag: {
719
		/* Promotion types */
720
		INT_TYPE is = DEREF_itype(itype_promote_arg(it));
721
		bfputc(bf, MANGLE_promote);
722
		mangle_itype(bf, is);
723
		break;
2 7u83 724
	}
6 7u83 725
	case itype_arith_tag: {
726
		/* Arithmetic types */
727
		INT_TYPE is = DEREF_itype(itype_arith_arg1(it));
728
		INT_TYPE ir = DEREF_itype(itype_arith_arg2(it));
729
		bfputc(bf, MANGLE_arith);
730
		mangle_itype(bf, is);
731
		mangle_itype(bf, ir);
732
		break;
2 7u83 733
	}
6 7u83 734
	case itype_literal_tag: {
735
		/* Literal types */
736
		NAT n = DEREF_nat(itype_literal_nat(it));
737
		string s = mangle_literal(it);
738
		bfputs(bf, s);
739
		mangle_nat(bf, n, 1);
740
		break;
2 7u83 741
	}
6 7u83 742
	case itype_token_tag: {
743
		/* Tokenised types */
744
		BUILTIN_TYPE n = DEREF_ntype(itype_unprom(it));
745
		if (n == ntype_none || n == ntype_ellipsis) {
746
			IDENTIFIER id;
747
			LIST(TOKEN)args;
748
			id = DEREF_id(itype_token_tok(it));
749
			args = DEREF_list(itype_token_args(it));
750
			mangle_token(bf, id, args, -2, 0);
751
		} else {
752
			bfputc(bf, MANGLE_promote);
753
			bfputs(bf, ustrlit(mangle_ntype[n]));
754
		}
755
		break;
2 7u83 756
	}
6 7u83 757
	}
758
	return;
2 7u83 759
}
760
 
761
 
762
/*
763
    ADD A FLOATING TYPE TO THE BUFFER
764
 
765
    This routine adds the mangled form of the floating-point type ft to
766
    the buffer position given by bf.
767
*/
768
 
6 7u83 769
static void
770
mangle_ftype(BUFFER *bf, FLOAT_TYPE ft)
2 7u83 771
{
6 7u83 772
	switch (TAG_ftype(ft)) {
773
	case ftype_basic_tag: {
774
		/* Basic floating types */
775
		BUILTIN_TYPE n = DEREF_ntype(ftype_basic_no(ft));
776
		bfputs(bf, ustrlit(mangle_ntype[n]));
777
		break;
2 7u83 778
	}
6 7u83 779
	case ftype_arg_promote_tag: {
780
		/* Promotion types */
781
		FLOAT_TYPE fs = DEREF_ftype(ftype_arg_promote_arg(ft));
782
		bfputc(bf, MANGLE_promote);
783
		mangle_ftype(bf, fs);
784
		break;
2 7u83 785
	}
6 7u83 786
	case ftype_arith_tag: {
787
		/* Arithmetic types */
788
		FLOAT_TYPE fs = DEREF_ftype(ftype_arith_arg1(ft));
789
		FLOAT_TYPE fr = DEREF_ftype(ftype_arith_arg2(ft));
790
		bfputc(bf, MANGLE_arith);
791
		mangle_ftype(bf, fs);
792
		mangle_ftype(bf, fr);
793
		break;
2 7u83 794
	}
6 7u83 795
	case ftype_token_tag: {
796
		/* Tokenised types */
797
		IDENTIFIER id = DEREF_id(ftype_token_tok(ft));
798
		LIST(TOKEN)args = DEREF_list(ftype_token_args(ft));
799
		mangle_token(bf, id, args, -2, 0);
800
		break;
2 7u83 801
	}
6 7u83 802
	}
803
	return;
2 7u83 804
}
805
 
806
 
807
/*
808
    ADD A CV-QUALIFIER TO THE BUFFER
809
 
810
    This routine adds the mangled form of the cv-qualifiers cv to the
811
    buffer position given by bf.  Note that this mangling scheme maps
812
    'volatile unsigned char *' to 'PVUc' rather than the ARM's 'PUVc'.
813
*/
814
 
6 7u83 815
static void
816
mangle_cv(BUFFER *bf, CV_SPEC cv)
2 7u83 817
{
6 7u83 818
	if (cv & cv_const) {
819
		bfputc(bf, MANGLE_const);
820
	}
821
	if (cv & cv_volatile) {
822
		bfputc(bf, MANGLE_volatile);
823
	}
824
	if (cv & cv_c) {
825
		bfputc(bf, MANGLE_c_lang);
826
	}
827
	return;
2 7u83 828
}
829
 
830
 
831
/*
832
    ADD A TYPE NAME TO THE BUFFER
833
 
834
    This routine adds the mangled form of the name of the type t to the
835
    buffer position given by bf.  The printing of function types (for
836
    example whether the return type is included) is controlled by fn
837
    and that of array types by arr.
838
*/
839
 
6 7u83 840
static void
841
mangle_type(BUFFER *bf, TYPE t, int fn, int arr)
2 7u83 842
{
6 7u83 843
	/* Output cv-qualifier */
844
	CV_SPEC qual = DEREF_cv(type_qual(t));
845
	mangle_cv(bf, qual);
2 7u83 846
 
6 7u83 847
	/* Output main type information */
848
	switch (TAG_type(t)) {
849
	case type_integer_tag: {
850
		/* Integral types */
851
		INT_TYPE it = DEREF_itype(type_integer_rep(t));
852
		mangle_itype(bf, it);
853
		break;
2 7u83 854
	}
6 7u83 855
	case type_floating_tag: {
856
		/* Floating-point types */
857
		FLOAT_TYPE ft = DEREF_ftype(type_floating_rep(t));
858
		mangle_ftype(bf, ft);
859
		break;
2 7u83 860
	}
6 7u83 861
	case type_top_tag: {
862
		/* Top type */
863
		bfputc(bf, MANGLE_void);
864
		break;
2 7u83 865
	}
6 7u83 866
	case type_bottom_tag: {
867
		/* Bottom type */
868
		bfputc(bf, MANGLE_bottom);
869
		break;
2 7u83 870
	}
6 7u83 871
	case type_ptr_tag: {
872
		/* Pointer types */
873
		bfputc(bf, MANGLE_ptr);
874
		t = DEREF_type(type_ptr_sub(t));
875
		mangle_type(bf, t, 2, 1);
876
		break;
2 7u83 877
	}
6 7u83 878
	case type_ref_tag: {
879
		/* Reference types */
880
		bfputc(bf, MANGLE_ref);
881
		t = DEREF_type(type_ref_sub(t));
882
		mangle_type(bf, t, 2, 1);
883
		break;
2 7u83 884
	}
6 7u83 885
	case type_ptr_mem_tag: {
886
		/* Pointer to member types */
887
		CLASS_TYPE ct = DEREF_ctype(type_ptr_mem_of(t));
888
		bfputc(bf, MANGLE_ptr_mem);
889
		mangle_ctype(bf, ct, -2);
890
		t = DEREF_type(type_ptr_mem_sub(t));
891
		mangle_type(bf, t, 2, 1);
892
		break;
2 7u83 893
	}
6 7u83 894
	case type_func_tag: {
895
		/* Function types */
896
		LIST(TYPE)p = DEREF_list(type_func_ptypes(t));
897
		int ell = DEREF_int(type_func_ellipsis(t));
2 7u83 898
 
6 7u83 899
		/* Include any cv-qualifiers */
900
		qual = DEREF_cv(type_func_mqual(t));
901
		mangle_cv(bf, qual);
2 7u83 902
 
6 7u83 903
		/* Include parameter types */
904
		if (fn) {
905
			bfputc(bf, MANGLE_func);
906
		}
907
		if (IS_NULL_list(p)) {
908
			if (fn && !ell) {
909
				bfputc(bf, MANGLE_void);
2 7u83 910
			}
6 7u83 911
		} else {
912
			LIST(TYPE)q = p;
913
			unsigned left = LENGTH_list(q);
914
			while (!IS_NULL_list(q)) {
915
				int worth = 1;
916
				unsigned long n = 0;
917
				TYPE r = DEREF_type(HEAD_list(q));
918
				switch (TAG_type(r)) {
919
				case type_integer_tag:
920
				case type_floating_tag: {
921
					/* Only check for long runs */
922
					if (left > MANGLE_WORTH) {
923
						worth = 0;
924
						goto default_lab;
925
					}
926
					break;
2 7u83 927
				}
6 7u83 928
				case type_top_tag:
929
				case type_bottom_tag:
930
				case type_error_tag: {
931
					/* Don't bother in these cases */
932
					break;
2 7u83 933
				}
6 7u83 934
				default:
935
default_lab: {
936
		     /* Check previous parameter types */
937
		     unsigned long m = 1;
938
		     LIST(TYPE)q1 = p;
939
		     while (!EQ_list(q1, q)) {
940
			     TYPE r1 = DEREF_type(HEAD_list(q1));
941
			     if (eq_type(r1, r)) {
942
				     /* Match found */
943
				     n = m;
944
				     break;
945
			     }
946
			     q1 = TAIL_list(q1);
947
			     m++;
948
		     }
949
		     break;
950
	     }
951
				}
952
				if (n) {
953
					/* Previous match found */
954
					TYPE nr;
955
					unsigned long m = 0;
956
					do {
957
						/* Step over equal parameters */
958
						m++;
959
						left--;
960
						q = TAIL_list(q);
961
						if (IS_NULL_list(q)) {
962
							break;
963
						}
964
						nr = DEREF_type(HEAD_list(q));
965
					} while (eq_type(r, nr));
966
					if (m == 1) {
967
						/* Single equal parameter */
968
						if (worth) {
969
							bfputc(bf,
970
							       MANGLE_repeat);
971
							mangle_number(bf, n, 2);
972
						} else {
973
							mangle_type(bf, r, 2,
974
								    1);
975
						}
976
					} else {
977
						/* Multiple equal parameters */
978
						if (worth || m > MANGLE_WORTH) {
979
							bfputc(bf,
980
							       MANGLE_multi);
981
							mangle_number(bf, m, 2);
982
							mangle_number(bf, n, 1);
983
						} else {
984
							while (m) {
985
								mangle_type(bf, r, 2, 1);
986
								m--;
987
							}
988
						}
989
					}
990
				} else {
991
					/* No previous match found */
992
					mangle_type(bf, r, 2, 1);
993
					left--;
994
					q = TAIL_list(q);
995
				}
2 7u83 996
			}
997
		}
6 7u83 998
		if (ell) {
999
			bfputc(bf, MANGLE_ellipsis);
1000
		}
2 7u83 1001
 
6 7u83 1002
		/* Include return type if necessary */
1003
		if (fn == 2) {
1004
			t = DEREF_type(type_func_ret(t));
1005
			bfputc(bf, MANGLE_sep);
1006
			mangle_type(bf, t, 2, 1);
1007
		}
1008
		break;
2 7u83 1009
	}
6 7u83 1010
	case type_array_tag: {
1011
		/* Array types */
1012
		NAT n = NULL_nat;
1013
		if (arr) {
1014
			n = DEREF_nat(type_array_size(t));
1015
		}
1016
		bfputc(bf, MANGLE_array);
1017
		mangle_nat(bf, n, 1);
1018
		t = DEREF_type(type_array_sub(t));
1019
		mangle_type(bf, t, 2, 1);
1020
		break;
2 7u83 1021
	}
6 7u83 1022
	case type_bitfield_tag: {
1023
		/* Bitfield types */
1024
		INT_TYPE it = DEREF_itype(type_bitfield_defn(t));
1025
		mangle_itype(bf, it);
1026
		break;
2 7u83 1027
	}
6 7u83 1028
	case type_compound_tag: {
1029
		/* Class types */
1030
		CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
1031
		mangle_ctype(bf, ct, -2);
1032
		break;
2 7u83 1033
	}
6 7u83 1034
	case type_enumerate_tag: {
1035
		/* Enumeration types */
1036
		ENUM_TYPE et = DEREF_etype(type_enumerate_defn(t));
2 7u83 1037
#if LANGUAGE_C
6 7u83 1038
		t = DEREF_type(etype_rep(et));
1039
		mangle_type(bf, t, fn, arr);
2 7u83 1040
#else
6 7u83 1041
		IDENTIFIER eid = DEREF_id(etype_name(et));
1042
		int d = ident_depth(eid);
1043
		mangle_id(bf, eid, d);
2 7u83 1044
#endif
6 7u83 1045
		break;
2 7u83 1046
	}
6 7u83 1047
	case type_token_tag: {
1048
		/* Tokenised types */
1049
		IDENTIFIER id = DEREF_id(type_token_tok(t));
1050
		LIST(TOKEN)args = DEREF_list(type_token_args(t));
1051
		mangle_token(bf, id, args, -2, 0);
1052
		break;
2 7u83 1053
	}
6 7u83 1054
	case type_templ_tag: {
1055
		/* Template types */
1056
		t = DEREF_type(type_templ_defn(t));
1057
		mangle_type(bf, t, fn, arr);
1058
		break;
2 7u83 1059
	}
6 7u83 1060
	default: {
1061
		/* Illegal types */
1062
		bfputc(bf, MANGLE_error);
1063
		break;
2 7u83 1064
	}
6 7u83 1065
	}
1066
	return;
2 7u83 1067
}
1068
 
1069
 
1070
/*
1071
    ADD A CLASS NAME TO THE BUFFER
1072
 
1073
    This routine adds the mangled form of the class type ct to the
1074
    buffer position given by bf.
1075
*/
1076
 
6 7u83 1077
static void
1078
mangle_ctype(BUFFER *bf, CLASS_TYPE ct, int d)
2 7u83 1079
{
6 7u83 1080
	CLASS_TYPE cs = crt_mangle_class;
1081
	if (!IS_NULL_ctype(cs) && eq_ctype(ct, cs)) {
1082
		bfputc(bf, MANGLE_self);
2 7u83 1083
	} else {
6 7u83 1084
		TYPE t = DEREF_type(ctype_form(ct));
1085
		if (!IS_NULL_type(t) && IS_type_token(t)) {
1086
			IDENTIFIER tid = DEREF_id(type_token_tok(t));
1087
			LIST(TOKEN)args = DEREF_list(type_token_args(t));
1088
			mangle_token(bf, tid, args, d, 0);
1089
		} else {
1090
			IDENTIFIER cid = DEREF_id(ctype_name(ct));
1091
			if (d == -2) {
1092
				d = ident_depth(cid);
1093
			}
1094
			mangle_id(bf, cid, d);
1095
		}
2 7u83 1096
	}
6 7u83 1097
	return;
2 7u83 1098
}
1099
 
1100
 
1101
/*
1102
    ADD A BASE CLASS GRAPH TO THE BUFFER
1103
 
1104
    This routine adds the mangled form of the base class graph gr to the
1105
    buffer bf.  first is true for the top node.
1106
*/
1107
 
6 7u83 1108
static void
1109
mangle_graph(BUFFER *bf, GRAPH gr)
2 7u83 1110
{
6 7u83 1111
	int d = -2;
1112
	GRAPH gu = DEREF_graph(graph_up(gr));
1113
	CLASS_TYPE ct = DEREF_ctype(graph_head(gr));
1114
	if (!IS_NULL_graph(gu)) {
1115
		mangle_graph(bf, gu);
1116
		d = 1;
1117
	}
1118
	mangle_ctype(bf, ct, d);
1119
	return;
2 7u83 1120
}
1121
 
1122
 
1123
/*
1124
    ADD A TOKEN ARGUMENT TO THE BUFFER
1125
 
1126
    This routine adds the mangled form of the token argument tok to the
1127
    buffer position given by bf.
1128
*/
1129
 
6 7u83 1130
static void
1131
mangle_token_arg(BUFFER *bf, TOKEN tok)
2 7u83 1132
{
6 7u83 1133
	if (!IS_NULL_tok(tok)) {
1134
		switch (TAG_tok(tok)) {
1135
		case tok_exp_tag: {
1136
			EXP e = DEREF_exp(tok_exp_value(tok));
1137
			TYPE t = DEREF_type(tok_exp_type(tok));
1138
			mangle_type(bf, t, 2, 1);
1139
			mangle_exp(bf, e, 1);
1140
			break;
1141
		}
1142
		case tok_stmt_tag: {
1143
			EXP e = DEREF_exp(tok_stmt_value(tok));
1144
			bfputc(bf, MANGLE_stmt);
1145
			mangle_exp(bf, e, 1);
1146
			break;
1147
		}
1148
		case tok_nat_tag: {
1149
			NAT n = DEREF_nat(tok_nat_value(tok));
1150
			bfputc(bf, MANGLE_nat);
1151
			mangle_nat(bf, n, 1);
1152
			break;
1153
		}
1154
		case tok_snat_tag: {
1155
			NAT n = DEREF_nat(tok_snat_value(tok));
1156
			bfputc(bf, MANGLE_nat);
1157
			mangle_nat(bf, n, 1);
1158
			break;
1159
		}
1160
		case tok_type_tag: {
1161
			TYPE t = DEREF_type(tok_type_value(tok));
1162
			bfputc(bf, MANGLE_type);
1163
			mangle_type(bf, t, 2, 1);
1164
			break;
1165
		}
1166
		case tok_class_tag: {
1167
			IDENTIFIER id = DEREF_id(tok_class_value(tok));
1168
			int d = ident_depth(id);
1169
			bfputc(bf, MANGLE_type);
1170
			mangle_id(bf, id, d);
1171
			break;
1172
		}
1173
		default: {
1174
			/* NOT YET IMPLEMENTED */
1175
			bfputc(bf, MANGLE_error);
1176
			break;
1177
		}
1178
		}
2 7u83 1179
	}
6 7u83 1180
	return;
2 7u83 1181
}
1182
 
1183
 
1184
/*
1185
    ADD A LIST OF TOKEN ARGUMENT TO THE BUFFER
1186
 
1187
    This routine adds the mangled form of the token arguments args to the
1188
    buffer position given by bf.
1189
*/
1190
 
6 7u83 1191
static void
1192
mangle_token_args(BUFFER *bf, LIST(TOKEN)args)
2 7u83 1193
{
6 7u83 1194
	unsigned m = LENGTH_list(args);
1195
	mangle_number(bf,(unsigned long)m, 2);
1196
	while (!IS_NULL_list(args)) {
1197
		TOKEN tok = DEREF_tok(HEAD_list(args));
1198
		mangle_token_arg(bf, tok);
1199
		args = TAIL_list(args);
1200
	}
1201
	return;
2 7u83 1202
}
1203
 
1204
 
1205
/*
1206
    ADD A TOKEN APPLICATION TO THE BUFFER
1207
 
1208
    This routine adds the token application 'id ( args )' to the buffer
1209
    position given by bf.
1210
*/
1211
 
6 7u83 1212
static void
1213
mangle_token(BUFFER *bf, IDENTIFIER id, LIST(TOKEN)args, int d, int force)
2 7u83 1214
{
6 7u83 1215
	IDENTIFIER alt;
1216
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
1217
	if (IS_id_token(id)) {
1218
		if (!IS_NULL_list(args)) {
1219
			force = 1;
2 7u83 1220
		}
6 7u83 1221
		alt = DEREF_id(id_token_alt(id));
1222
	} else {
1223
		force = 1;
1224
		alt = id;
2 7u83 1225
	}
6 7u83 1226
	if (d == -2) {
1227
		if (ds & dspec_auto) {
1228
			/* Template parameter */
1229
			ulong n = DEREF_ulong(id_no(id));
1230
			if (ds & dspec_register) {
1231
				/* This shouldn't happen */
1232
				n = 0;
1233
			}
1234
			if (ds & dspec_template) {
1235
				/* Template template parameter */
1236
				if (!IS_NULL_list(args)) {
1237
					bfputc(bf, MANGLE_template);
1238
					bfputc(bf, MANGLE_templ_param);
1239
					mangle_number(bf, n, 2);
1240
					mangle_token_args(bf, args);
1241
					return;
1242
				}
1243
			}
1244
			bfputc(bf, MANGLE_templ_param);
1245
			mangle_number(bf, n, 2);
1246
			return;
1247
		}
1248
		d = ident_depth(alt);
1249
	}
1250
	if (force) {
1251
		bfputc(bf, MANGLE_template);
1252
	}
1253
	mangle_id(bf, alt, d);
1254
	if (!IS_NULL_list(args)) {
1255
		/* Token arguments */
1256
		mangle_token_args(bf, args);
1257
	}
1258
	return;
2 7u83 1259
}
1260
 
1261
 
1262
/*
1263
    FIND A MANGLED OPERATOR NAME
1264
 
1265
    This routine finds the mangled function name for 'operator op'.  Note
1266
    that op will always be in its primary form.
1267
*/
1268
 
6 7u83 1269
static string
1270
mangle_op(int op)
2 7u83 1271
{
6 7u83 1272
	CONST char *s;
1273
	switch (op) {
1274
		/* Standard operator names */
1275
	case lex_abs:
1276
		s = "__ab";
1277
		break;
1278
	case lex_and_H1:
1279
		s = "__ad";
1280
		break;
1281
	case lex_and_Heq_H1:
1282
		s = "__aad";
1283
		break;
1284
	case lex_array_Hop:
1285
		s = "__vc";
1286
		break;
1287
	case lex_arrow:
1288
		s = "__rf";
1289
		break;
1290
	case lex_arrow_Hstar:
1291
		s = "__rm";
1292
		break;
1293
	case lex_assign:
1294
		s = "__as";
1295
		break;
1296
	case lex_comma:
1297
		s = "__cm";
1298
		break;
1299
	case lex_compl_H1:
1300
		s = "__co";
1301
		break;
1302
	case lex_delete:
1303
		s = "__dl";
1304
		break;
1305
	case lex_delete_Harray:
1306
		s = "__vd";
1307
		break;
1308
	case lex_div:
1309
		s = "__dv";
1310
		break;
1311
	case lex_div_Heq:
1312
		s = "__adv";
1313
		break;
1314
	case lex_eq:
1315
		s = "__eq";
1316
		break;
1317
	case lex_func_Hop:
1318
		s = "__cl";
1319
		break;
1320
	case lex_greater:
1321
		s = "__gt";
1322
		break;
1323
	case lex_greater_Heq:
1324
		s = "__ge";
1325
		break;
1326
	case lex_less:
1327
		s = "__lt";
1328
		break;
1329
	case lex_less_Heq:
1330
		s = "__le";
1331
		break;
1332
	case lex_logical_Hand_H1:
1333
		s = "__aa";
1334
		break;
1335
	case lex_logical_Hor_H1:
1336
		s = "__oo";
1337
		break;
1338
	case lex_lshift:
1339
		s = "__ls";
1340
		break;
1341
	case lex_lshift_Heq:
1342
		s = "__als";
1343
		break;
1344
	case lex_max:
1345
		s = "__mx";
1346
		break;
1347
	case lex_min:
1348
		s = "__mn";
1349
		break;
1350
	case lex_minus:
1351
		s = "__mi";
1352
		break;
1353
	case lex_minus_Heq:
1354
		s = "__ami";
1355
		break;
1356
	case lex_minus_Hminus:
1357
		s = "__mm";
1358
		break;
1359
	case lex_new:
1360
		s = "__nw";
1361
		break;
1362
	case lex_new_Harray:
1363
		s = "__vn";
1364
		break;
1365
	case lex_not_H1:
1366
		s = "__nt";
1367
		break;
1368
	case lex_not_Heq_H1:
1369
		s = "__ne";
1370
		break;
1371
	case lex_or_H1:
1372
		s = "__or";
1373
		break;
1374
	case lex_or_Heq_H1:
1375
		s = "__aor";
1376
		break;
1377
	case lex_plus:
1378
		s = "__pl";
1379
		break;
1380
	case lex_plus_Heq:
1381
		s = "__apl";
1382
		break;
1383
	case lex_plus_Hplus:
1384
		s = "__pp";
1385
		break;
1386
	case lex_rem:
1387
		s = "__md";
1388
		break;
1389
	case lex_rem_Heq:
1390
		s = "__amd";
1391
		break;
1392
	case lex_rshift:
1393
		s = "__rs";
1394
		break;
1395
	case lex_rshift_Heq:
1396
		s = "__ars";
1397
		break;
1398
	case lex_star:
1399
		s = "__ml";
1400
		break;
1401
	case lex_star_Heq:
1402
		s = "__aml";
1403
		break;
1404
	case lex_xor_H1:
1405
		s = "__er";
1406
		break;
1407
	case lex_xor_Heq_H1:
1408
		s = "__aer";
1409
		break;
2 7u83 1410
 
1411
	/* Invalid operator names */
6 7u83 1412
	case lex_cond_Hop:
1413
		s = "__cn";
1414
		break;
1415
	case lex_colon:
1416
		s = "__cs";
1417
		break;
1418
	case lex_colon_Hcolon:
1419
		s = "__cc";
1420
		break;
1421
	case lex_dot:
1422
		s = "__df";
1423
		break;
1424
	case lex_dot_Hstar:
1425
		s = "__dm";
1426
		break;
1427
	case lex_sizeof:
1428
		s = "__sz";
1429
		break;
1430
	case lex_typeid:
1431
		s = "__td";
1432
		break;
1433
	case lex_vtable:
1434
		s = "__tb";
1435
		break;
1436
	default:
1437
		s = mangle_ntype[0];
1438
		break;
1439
	}
1440
	return (ustrlit(s));
2 7u83 1441
}
1442
 
1443
 
1444
/*
1445
    MANGLE AN EXTENDED NAME
1446
 
1447
    This routine mangles the extended identifier name s into the buffer
1448
    bf.  It returns true if the result differs from s.
1449
*/
1450
 
6 7u83 1451
static int
1452
mangle_ename(BUFFER *bf, string s)
2 7u83 1453
{
6 7u83 1454
	int u = 0;
1455
	character c;
1456
	while (c = *(s++), c != 0) {
1457
		if (c == char_backslash) {
1458
			c = *(s++);
1459
			bfputc(bf, MANGLE_sep);
1460
			bfputc(bf, MANGLE_sep);
1461
			if (c == char_U) {
1462
				bfputc(bf, MANGLE_unicode8);
1463
			} else {
1464
				bfputc(bf, MANGLE_unicode4);
1465
			}
1466
			u = 1;
1467
			if (c == 0) {
1468
				break;
1469
			}
1470
		} else {
1471
			bfputc(bf,(int)c);
1472
		}
2 7u83 1473
	}
6 7u83 1474
	return (u);
2 7u83 1475
}
1476
 
1477
 
1478
/*
1479
    FIND A MANGLED NAME
1480
 
1481
    This routine returns the mangled form of the identifier name nm.
1482
    For conversion functions and extended names the name is built into
1483
    name_buff and pcopy is set to true.
1484
*/
1485
 
6 7u83 1486
static string
1487
mangle_hashid(HASHID nm, int *pcopy, int force)
2 7u83 1488
{
6 7u83 1489
	string s = NULL;
1490
	switch (TAG_hashid(nm)) {
1491
	case hashid_name_tag: {
1492
		/* Simple identifiers */
1493
		s = DEREF_string(hashid_name_text(nm));
1494
		break;
2 7u83 1495
	}
6 7u83 1496
	case hashid_ename_tag: {
1497
		/* Extended identifiers */
1498
		BUFFER *bf = &name_buff;
1499
		unsigned n = (unsigned)(bf->posn - bf->start);
1500
		s = DEREF_string(hashid_ename_text(nm));
1501
		if (mangle_ename(bf, s)) {
1502
			bfputc(bf, 0);
1503
			s = bf->start + n;
1504
			*pcopy = 1;
1505
		}
1506
		break;
2 7u83 1507
	}
6 7u83 1508
	case hashid_constr_tag: {
1509
		/* Constructor names */
1510
		s = ustrlit("__ct");
1511
		break;
2 7u83 1512
	}
6 7u83 1513
	case hashid_destr_tag: {
1514
		/* Destructor names */
1515
		s = ustrlit("__dt");
1516
		break;
2 7u83 1517
	}
6 7u83 1518
	case hashid_conv_tag: {
1519
		/* Conversion names */
1520
		BUFFER *bf = &name_buff;
1521
		unsigned n = (unsigned)(bf->posn - bf->start);
1522
		TYPE t = DEREF_type(hashid_conv_type(nm));
1523
		bfprintf(bf, "__op");
1524
		mangle_type(bf, t, 2, 1);
1525
		bfputc(bf, 0);
1526
		s = bf->start + n;
1527
		*pcopy = 1;
1528
		break;
2 7u83 1529
	}
6 7u83 1530
	case hashid_op_tag: {
1531
		/* Operator names */
1532
		int op = DEREF_int(hashid_op_lex(nm));
1533
		s = mangle_op(op);
1534
		break;
2 7u83 1535
	}
6 7u83 1536
	case hashid_anon_tag: {
1537
		/* Anonymous names */
1538
		if (force && output_all) {
1539
			s = ustrlit("");
1540
		}
1541
		break;
2 7u83 1542
	}
6 7u83 1543
	}
1544
	return (s);
2 7u83 1545
}
1546
 
1547
 
1548
/*
1549
    FIND THE EXTERNAL NAME OF AN IDENTIFIER
1550
 
1551
    This routine finds the external (mangled) name of the identifier id
1552
    of type v returning the result.  ext determines the treatment of inline
1553
    functions with external linkage.  The null string is returned for local
1554
    identifiers.
1555
*/
1556
 
6 7u83 1557
string
1558
mangle_name(IDENTIFIER id, int v, int ext)
2 7u83 1559
{
6 7u83 1560
	int d;
1561
	string s;
1562
	HASHID nm;
1563
	BUFFER *bf;
1564
	int copy = 0;
1565
	NAMESPACE ns;
1566
	string pre = NULL;
1567
	TYPE t = NULL_type;
1568
	TYPE f = NULL_type;
1569
	CLASS_TYPE cs = NULL_ctype;
2 7u83 1570
 
6 7u83 1571
	/* Check for internal linkage */
1572
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
1573
	if (!(ds & dspec_extern)) {
1574
		if (ds & dspec_static) {
1575
			if (!output_all) {
1576
				return (NULL);
1577
			}
1578
		} else if (IS_id_enumerator(id)) {
1579
			if (!output_all) {
1580
				return (NULL);
1581
			}
1582
		} else {
1583
			return (NULL);
1584
		}
2 7u83 1585
	}
6 7u83 1586
	if ((ds & dspec_instance) && !is_exported(id)) {
1587
		/* Non-exported templates */
1588
		if (!output_all) {
1589
			return (NULL);
1590
		}
1591
	}
1592
	if (output_all)ext = 1;
2 7u83 1593
 
6 7u83 1594
	/* Find the basic name */
1595
	name_buff.posn = name_buff.start;
1596
	nm = DEREF_hashid(id_name(id));
1597
	s = mangle_hashid(nm, &copy, 0);
1598
	if (s == NULL) {
1599
		return (NULL);
1600
	}
2 7u83 1601
 
6 7u83 1602
	/* Find the namespace depth */
1603
	ns = DEREF_nspace(id_parent(id));
1604
	d = nspace_depth(ns);
2 7u83 1605
 
6 7u83 1606
	/* Find any type qualifier */
1607
	switch (TAG_id(id)) {
1608
	case id_variable_tag: {
1609
		/* Simple variables */
1610
		if (ds & dspec_c) {
1611
			/* C linkage */
1612
			if (d > 0 || !anon_c_linkage) {
1613
				d = 0;
1614
			}
1615
		} else if (mangle_objects) {
1616
			/* C++ linkage */
1617
			t = DEREF_type(id_variable_type(id));
1618
		}
1619
		break;
2 7u83 1620
	}
6 7u83 1621
	case id_stat_member_tag: {
1622
		/* Static data members */
1623
		if (mangle_objects) {
1624
			t = DEREF_type(id_stat_member_type(id));
1625
			cs = parent_class(id);
1626
		}
1627
		break;
2 7u83 1628
	}
6 7u83 1629
	case id_function_tag: {
1630
		/* Simple functions */
1631
		if ((ds & dspec_inline) && !ext) {
1632
			/* Inline functions */
1633
			d = -1;
1634
		} else if (ds & dspec_main) {
1635
			/* The main function */
1636
#if LANGUAGE_CPP && (TDF_major < 4)
1637
			s = ustrlit("__MAIN__");
2 7u83 1638
#endif
6 7u83 1639
			d = 0;
1640
		} else if (ds & dspec_c) {
1641
			/* C linkage */
1642
			if (d > 0 || !anon_c_linkage)d = 0;
1643
		} else {
1644
			/* C++ linkage */
1645
			t = DEREF_type(id_function_type(id));
1646
			f = DEREF_type(id_function_form(id));
1647
		}
1648
		break;
2 7u83 1649
	}
6 7u83 1650
	case id_mem_func_tag:
1651
	case id_stat_mem_func_tag: {
1652
		/* Member functions */
1653
		if ((ds & dspec_implicit) && !output_all) {
1654
			/* Implicitly defined functions */
1655
			d = -1;
1656
		} else if ((ds & dspec_inline) && !ext) {
1657
			/* Inline functions */
1658
			d = -1;
1659
		} else {
1660
			t = DEREF_type(id_function_etc_type(id));
1661
			f = DEREF_type(id_function_etc_form(id));
1662
			cs = parent_class(id);
1663
		}
1664
		break;
2 7u83 1665
	}
6 7u83 1666
	case id_member_tag: {
1667
		/* Data members */
1668
		pre = ustrlit("~cpp.mem.");
1669
		t = DEREF_type(id_member_type(id));
1670
		cs = parent_class(id);
1671
		break;
2 7u83 1672
	}
6 7u83 1673
	case id_enumerator_tag: {
1674
		/* Enumerators */
1675
		t = DEREF_type(id_enumerator_etype(id));
1676
		break;
2 7u83 1677
	}
6 7u83 1678
	}
2 7u83 1679
 
6 7u83 1680
	/* Check for the simple cases */
1681
	if (d < 0) {
1682
		return (NULL);
2 7u83 1683
	}
6 7u83 1684
	if (d == 0 && IS_NULL_type(t) && pre == NULL) {
1685
		if (copy) {
1686
			if (ustrchr(s, MANGLE_error)) {
1687
				return (NULL);
1688
			}
1689
			s = xustrcpy(s);
1690
		}
1691
		return (s);
1692
	}
2 7u83 1693
 
6 7u83 1694
	/* Deal with the complex case */
1695
	bf = clear_buffer(&mangle_buff, NIL(FILE));
1696
	if (pre) {
1697
		bfputs(bf, pre);
1698
	}
1699
	bfputs(bf, s);
1700
	if (v == VAR_token) {
1701
		bfputc(bf, MANGLE_dot);
1702
	} else {
1703
		bfputc(bf, MANGLE_sep);
1704
		bfputc(bf, MANGLE_sep);
1705
	}
1706
	if (d) {
1707
		mangle_nspace(bf, ns, d);
1708
	}
1709
	if (!IS_NULL_type(f) && IS_type_token(f)) {
1710
		/* Check for template functions */
1711
		if (mangle_signature) {
1712
			IDENTIFIER fid = DEREF_id(type_token_tok(f));
1713
			LIST(TOKEN)args = DEREF_list(type_token_args(f));
1714
			if (!IS_id_token(fid)) {
1715
				if (IS_id_function_etc(fid)) {
1716
					/* Use template function type */
1717
					t = DEREF_type(id_function_etc_type(fid));
1718
				}
1719
				bfputc(bf, MANGLE_func_templ);
1720
				mangle_token_args(bf, args);
1721
				bfputc(bf, MANGLE_sep);
1722
			}
2 7u83 1723
		}
1724
	}
6 7u83 1725
	if (!IS_NULL_type(t)) {
1726
		/* Output function type */
1727
		int fn = 1;
1728
		if (!IS_hashid_name_etc(nm)) {
1729
			fn = 0;
1730
		}
1731
		if (v == VAR_token) {
1732
			bfputc(bf, MANGLE_dot);
1733
		}
1734
		crt_mangle_class = cs;
1735
		mangle_type(bf, t, fn, 0);
1736
		crt_mangle_class = NULL_ctype;
1737
	}
1738
	bfputc(bf, 0);
2 7u83 1739
 
6 7u83 1740
	/* Check for illegal names */
1741
	s = bf->start;
1742
	if (ustrchr(s, MANGLE_error)) {
1743
		return (NULL);
1744
	}
1745
	s = xustrcpy(s);
1746
	return (s);
2 7u83 1747
}
1748
 
1749
 
1750
/*
1751
    COMMON TAG COUNTER
1752
 
1753
    This variable is used by mangle_common to ensure that each call
1754
    generates a unique name.
1755
*/
1756
 
6 7u83 1757
ulong common_no = 0;
2 7u83 1758
 
1759
 
1760
/*
1761
    CREATE A LOCAL STATIC NAME
1762
 
1763
    This routine creates a mangled name for the local static variable id
1764
    from the function with mangled name s.
1765
*/
1766
 
6 7u83 1767
string
1768
mangle_common(string s, IDENTIFIER id)
2 7u83 1769
{
6 7u83 1770
	string t = NULL;
1771
	if (s) {
1772
		BUFFER *bf = clear_buffer(&mangle_buff, NIL(FILE));
1773
		bfprintf(bf, "__v_");
1774
		if (!IS_NULL_id(id)) {
1775
			int copy = 0;
1776
			HASHID nm = DEREF_hashid(id_name(id));
1777
			name_buff.posn = name_buff.start;
1778
			t = mangle_hashid(nm, &copy, 0);
1779
			bfputs(bf, t);
1780
		}
1781
		bfprintf(bf, "%lu", common_no++);
1782
		bfputc(bf, MANGLE_sep);
1783
		bfputc(bf, MANGLE_sep);
1784
		bfputs(bf, s);
1785
		t = bf->start;
1786
		if (ustrchr(t, MANGLE_error)) {
1787
			return (NULL);
1788
		}
1789
		t = xustrcpy(t);
2 7u83 1790
	}
6 7u83 1791
	return (t);
2 7u83 1792
}
1793
 
1794
 
1795
/*
1796
    CREATE A VIRTUAL FUNCTION TABLE NAME
1797
 
1798
    This routine creates a mangled name for the virtual function table
1799
    associated with the base class graph gr.
1800
*/
1801
 
6 7u83 1802
string
1803
mangle_vtable(CONST char *pre, GRAPH gr)
2 7u83 1804
{
6 7u83 1805
	string s;
1806
	BUFFER *bf = clear_buffer(&mangle_buff, NIL(FILE));
1807
	name_buff.posn = name_buff.start;
1808
	bfputs(bf, ustrlit(pre));
1809
	mangle_graph(bf, gr);
1810
	bfputc(bf, 0);
1811
	s = bf->start;
1812
	if (ustrchr(s, MANGLE_error)) {
1813
		return (NULL);
1814
	}
1815
	s = xustrcpy(s);
1816
	return (s);
2 7u83 1817
}
1818
 
1819
 
1820
/*
1821
    CREATE A TYPE INFORMATION STRUCTURE NAME
1822
 
1823
    This routine creates a mangled name for the type information structure
1824
    associated with the polymorphic class type ct.
1825
*/
1826
 
6 7u83 1827
string
1828
mangle_typeid(CONST char *pre, CLASS_TYPE ct)
2 7u83 1829
{
6 7u83 1830
	string s;
1831
	BUFFER *bf = clear_buffer(&mangle_buff, NIL(FILE));
1832
	name_buff.posn = name_buff.start;
1833
	bfputs(bf, ustrlit(pre));
1834
	mangle_ctype(bf, ct, -2);
1835
	bfputc(bf, 0);
1836
	s = bf->start;
1837
	if (ustrchr(s, MANGLE_error)) {
1838
		return (NULL);
1839
	}
1840
	s = xustrcpy(s);
1841
	return (s);
2 7u83 1842
}
1843
 
1844
 
1845
/*
1846
    CREATE A TYPE TOKEN NAME
1847
 
1848
    This routine creates a mangled name for the type token name associated
1849
    with the type t.
1850
*/
1851
 
6 7u83 1852
string
1853
mangle_tname(CONST char *pre, TYPE t)
2 7u83 1854
{
6 7u83 1855
	string s;
1856
	BUFFER *bf = clear_buffer(&mangle_buff, NIL(FILE));
1857
	name_buff.posn = name_buff.start;
1858
	bfputs(bf, ustrlit(pre));
1859
	mangle_type(bf, t, 2, 1);
1860
	bfputc(bf, 0);
1861
	s = bf->start;
1862
	if (ustrchr(s, MANGLE_error)) {
1863
		return (NULL);
1864
	}
1865
	s = xustrcpy(s);
1866
	return (s);
2 7u83 1867
}
1868
 
1869
 
1870
/*
1871
    CREATE AN INITIALISER FUNCTION NAME
1872
 
1873
    This routine creates a dynamic initialiser function name.  For TDF 4.0
1874
    and later this can be the null string since there is direct support
1875
    for dynamic initialisation.
1876
*/
1877
 
6 7u83 1878
string
1879
mangle_init(void)
2 7u83 1880
{
6 7u83 1881
#if (TDF_major >= 4)
1882
	return (NULL);
2 7u83 1883
#else
6 7u83 1884
	char buff[50];
1885
	output_init = 1;
1886
	sprintf_v(buff, "_GLOBAL_$I$%s", uniq_string);
1887
	return (xustrcpy(ustrlit(buff)));
2 7u83 1888
#endif
1889
}
1890
 
1891
 
1892
/*
1893
    CREATE A UNIQUE IDENTIFIER NAME
1894
 
1895
    This routine creates a unique identifier name distinct from every other
1896
    identifier name.
1897
*/
1898
 
6 7u83 1899
string
1900
mangle_anon(void)
2 7u83 1901
{
6 7u83 1902
	char buff[50];
1903
	static unsigned long anon_no = 0;
1904
	sprintf_v(buff, "__%lu_%s", anon_no++, uniq_string);
1905
	return (xustrcpy(ustrlit(buff)));
2 7u83 1906
}
1907
 
1908
 
1909
/*
1910
    ADD A DIAGNOSTIC NAME QUALIFIER TO THE BUFFER
1911
 
1912
    This routine adds the name of the namespace ns to the buffer bf.
1913
*/
1914
 
6 7u83 1915
static void
1916
mangle_diag_nspace(BUFFER *bf, NAMESPACE ns)
2 7u83 1917
{
6 7u83 1918
	if (!IS_NULL_nspace(ns)) {
1919
		switch (TAG_nspace(ns)) {
1920
		case nspace_named_tag:
1921
		case nspace_ctype_tag: {
1922
			int copy = 0;
1923
			IDENTIFIER id = DEREF_id(nspace_name(ns));
1924
			HASHID nm = DEREF_hashid(id_name(id));
1925
			string s = mangle_hashid(nm, &copy, 0);
1926
			ns = DEREF_nspace(id_parent(id));
1927
			mangle_diag_nspace(bf, ns);
1928
			if (s) {
1929
				bfputs(bf, s);
1930
			}
1931
			bfputc(bf, MANGLE_sep);
1932
			bfputc(bf, MANGLE_sep);
1933
			break;
1934
		}
1935
		case nspace_unnamed_tag: {
1936
			IDENTIFIER id = DEREF_id(nspace_name(ns));
1937
			ns = DEREF_nspace(id_parent(id));
1938
			mangle_diag_nspace(bf, ns);
1939
			break;
1940
		}
1941
		}
2 7u83 1942
	}
6 7u83 1943
	return;
2 7u83 1944
}
1945
 
1946
 
1947
/*
1948
    FIND THE DIAGNOSTIC NAME FOR AN IDENTIFIER
1949
 
1950
    This routine creates the name used for the identifier id in the
1951
    diagnostic output.  If q is false then no qualifiers are output.
1952
*/
1953
 
6 7u83 1954
string
1955
mangle_diag(IDENTIFIER id, int q)
2 7u83 1956
{
6 7u83 1957
	int fn = 0;
1958
	TYPE t = NULL_type;
1959
	HASHID nm = DEREF_hashid(id_name(id));
1960
	unsigned tag = TAG_hashid(nm);
1961
	BUFFER *bf = clear_buffer(&mangle_buff, NIL(FILE));
1962
	name_buff.posn = name_buff.start;
1963
	if (q) {
1964
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
1965
		if (ds & dspec_c) {
1966
			/* Ignore C linkage objects */
1967
			/* EMPTY */
1968
		} else if ((ds & dspec_main) && tag == hashid_name_tag) {
1969
			/* Ignore main function */
1970
			/* EMPTY */
1971
		} else {
1972
			/* Namespace qualifiers */
1973
			NAMESPACE ns = DEREF_nspace(id_parent(id));
1974
			mangle_diag_nspace(bf, ns);
1975
			if (IS_id_function_etc(id)) {
1976
				t = DEREF_type(id_function_etc_type(id));
1977
			}
1978
		}
2 7u83 1979
	}
6 7u83 1980
	switch (tag) {
1981
	case hashid_name_tag: {
1982
		string s = DEREF_string(hashid_name_text(nm));
1983
		bfputs(bf, s);
1984
		fn = 1;
1985
		break;
2 7u83 1986
	}
6 7u83 1987
	case hashid_ename_tag: {
1988
		if (EQ_KEYWORD(nm, lex_this_Hname)) {
1989
			bfprintf(bf, "this");
1990
		} else {
1991
			string s = DEREF_string(hashid_ename_text(nm));
1992
			IGNORE mangle_ename(bf, s);
1993
		}
1994
		fn = 1;
1995
		break;
2 7u83 1996
	}
6 7u83 1997
	case hashid_constr_tag: {
1998
		bfprintf(bf, "1");
1999
		break;
2 7u83 2000
	}
6 7u83 2001
	case hashid_destr_tag: {
2002
		bfprintf(bf, "0");
2003
		break;
2 7u83 2004
	}
6 7u83 2005
	case hashid_conv_tag: {
2006
		t = DEREF_type(hashid_conv_type(nm));
2007
		bfprintf(bf, "operator__T");
2008
		mangle_type(bf, t, 2, 1);
2009
		t = NULL_type;
2010
		break;
2 7u83 2011
	}
6 7u83 2012
	case hashid_op_tag: {
2013
		int op = DEREF_int(hashid_op_lex(nm));
2014
		string s = mangle_op(op);
2015
		bfprintf(bf, "operator");
2016
		if (s) {
2017
			bfputs(bf, s);
2018
		}
2019
		break;
2 7u83 2020
	}
6 7u83 2021
	case hashid_anon_tag: {
2022
		ulong u = DEREF_ulong(hashid_anon_uniq(nm));
2023
		bfprintf(bf, "__anon%lu", u);
2024
		fn = 1;
2025
		break;
2 7u83 2026
	}
6 7u83 2027
	}
2028
	if (!IS_NULL_type(t)) {
2029
		/* Mangled function type */
2030
		bfputc(bf, MANGLE_sep);
2031
		bfputc(bf, MANGLE_sep);
2032
		mangle_type(bf, t, fn, 0);
2033
	}
2034
	bfputc(bf, 0);
2035
	return (bf->start);
2 7u83 2036
}