Subversion Repositories tendra.SVN

Rev

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

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