1: // Copyright (C) 1992-1998 by Symantec
2: // Copyright (C) 2000-2009 by Digital Mars
3: // All Rights Reserved
4: // http://www.digitalmars.com
5: // Written by Walter Bright
6: /*
7: * This source file is made available for personal use
8: * only. The license is in /dmd/src/dmd/backendlicense.txt
9: * or /dm/src/dmd/backendlicense.txt
10: * For any other uses, please contact Digital Mars.
11: */
12:
13: #if !SPP
14:
15: #include <stdio.h>
16: #include <ctype.h>
17: #include <string.h>
18: #include <stdlib.h>
19: #include <time.h>
20:
21: #include "cc.h"
22: #include "token.h"
23: #include "global.h"
24: #include "oper.h"
25: #include "el.h"
26: #include "type.h"
27: #include "filespec.h"
28:
29: #if NEWMANGLE
30:
31: static char __file__[] = __FILE__; /* for tassert.h */
32: #include "tassert.h"
33:
34: #define BUFIDMAX (2 * IDMAX)
35:
36: struct Mangle
37: {
38: char buf[BUFIDMAX + 2];
39:
40: char *np; // index into buf[]
41:
42: // Used for compression of redundant znames
43: const char *zname[10];
44: int znamei;
45:
46: type *arg[10]; // argument_replicator
47: int argi; // number used in arg[]
48: };
49:
50: static Mangle mangle;
51:
52: static int mangle_inuse;
53:
54: struct MangleInuse
55: {
56: MangleInuse()
57: {
58: #if 0
59: assert(mangle_inuse == 0);
60: mangle_inuse++;
61: #endif
62: }
63:
64: ~MangleInuse()
65: {
66: #if 0
67: assert(mangle_inuse == 1);
68: mangle_inuse--;
69: #endif
70: }
71: };
72:
73: /* Names for special variables */
74: char cpp_name_new[] = "?2";
75: char cpp_name_delete[] = "?3";
76: char cpp_name_anew[] = "?_P";
77: char cpp_name_adelete[] = "?_Q";
78: char cpp_name_ct[] = "?0";
79: char cpp_name_dt[] = "?1";
80: char cpp_name_as[] = "?4";
81: char cpp_name_vc[] = "?_H";
82: char cpp_name_primdt[] = "?_D";
83: char cpp_name_scaldeldt[] = "?_G";
84: char cpp_name_priminv[] = "?_R";
85:
86: STATIC int cpp_cvidx ( tym_t ty );
87: STATIC int cpp_protection ( symbol *s );
88: STATIC void cpp_decorated_name ( symbol *s );
89: STATIC void cpp_symbol_name ( symbol *s );
90: STATIC void cpp_zname ( const char *p );
91: STATIC void cpp_scope ( symbol *s );
92: STATIC void cpp_type_encoding ( symbol *s );
93: STATIC void cpp_external_function_type(symbol *s);
94: STATIC void cpp_external_data_type ( symbol *s );
95: STATIC void cpp_member_function_type ( symbol *s );
96: STATIC void cpp_static_member_function_type ( symbol *s );
97: STATIC void cpp_static_member_data_type ( symbol *s );
98: STATIC void cpp_local_static_data_type ( symbol *s );
99: STATIC void cpp_vftable_type(symbol *s);
100: STATIC void cpp_adjustor_thunk_type(symbol *s);
101: STATIC void cpp_function_type ( type *t );
102: STATIC void cpp_throw_types ( type *t );
103: STATIC void cpp_ecsu_name ( symbol *s );
104: STATIC void cpp_return_type ( symbol *s );
105: STATIC void cpp_data_type ( type *t );
106: STATIC void cpp_storage_convention ( symbol *s );
107: STATIC void cpp_this_type ( type *t,Classsym *s );
108: STATIC void cpp_vcall_model_type ( void );
109: STATIC void cpp_calling_convention ( type *t );
110: STATIC void cpp_argument_types ( type *t );
111: STATIC void cpp_argument_list ( type *t, int flag );
112: STATIC void cpp_primary_data_type ( type *t );
113: STATIC void cpp_reference_type ( type *t );
114: STATIC void cpp_pointer_type ( type *t );
115: STATIC void cpp_ecsu_data_indirect_type ( type *t );
116: STATIC void cpp_data_indirect_type ( type *t );
117: STATIC void cpp_function_indirect_type ( type *t );
118: STATIC void cpp_basic_data_type ( type *t );
119: STATIC void cpp_ecsu_data_type(type *t);
120: STATIC void cpp_pointer_data_type ( type *t );
121: STATIC void cpp_reference_data_type ( type *t, int flag );
122: STATIC void cpp_enum_name ( symbol *s );
123: STATIC void cpp_dimension ( targ_ullong u );
124: STATIC void cpp_dimension_ld ( targ_ldouble ld );
125: STATIC void cpp_string ( char *s, size_t len );
126:
127: /****************************
128: */
129:
130: struct OPTABLE
131: #if MARS
132: {
133: unsigned char tokn;
134: unsigned char oper;
135: char __near *string;
136: char *pretty;
137: }
138: #endif
139: oparray[] = {
140: { TKnew, OPnew, cpp_name_new, "new" },
141: { TKdelete, OPdelete, cpp_name_delete,"del" },
142: { TKadd, OPadd, "?H", "+" },
143: { TKadd, OPuadd, "?H", "+" },
144: { TKmin, OPmin, "?G", "-" },
145: { TKmin, OPneg, "?G", "-" },
146: { TKstar, OPmul, "?D", "*" },
147: { TKstar, OPind, "?D", "*" },
148: { TKdiv, OPdiv, "?K", "/" },
149: { TKmod, OPmod, "?L", "%" },
150: { TKxor, OPxor, "?T", "^" },
151: { TKand, OPand, "?I", "&" },
152: { TKand, OPaddr, "?I", "&" },
153: { TKor, OPor, "?U", "|" },
154: { TKcom, OPcom, "?S", "~" },
155: { TKnot, OPnot, "?7", "!" },
156: { TKeq, OPeq, cpp_name_as, "=" },
157: { TKeq, OPstreq, "?4", "=" },
158: { TKlt, OPlt, "?M", "<" },
159: { TKgt, OPgt, "?O", ">" },
160: { TKnew, OPanew, cpp_name_anew, "n[]" },
161: { TKdelete, OPadelete, cpp_name_adelete,"d[]" },
162: { TKunord, OPunord, "?_S", "!<>=" },
163: { TKlg, OPlg, "?_T", "<>" },
164: { TKleg, OPleg, "?_U", "<>=" },
165: { TKule, OPule, "?_V", "!>" },
166: { TKul, OPul, "?_W", "!>=" },
167: { TKuge, OPuge, "?_X", "!<" },
168: { TKug, OPug, "?_Y", "!<=" },
169: { TKue, OPue, "?_Z", "!<>" },
170: { TKaddass, OPaddass, "?Y", "+=" },
171: { TKminass, OPminass, "?Z", "-=" },
172: { TKmulass, OPmulass, "?X", "*=" },
173: { TKdivass, OPdivass, "?_0", "/=" },
174: { TKmodass, OPmodass, "?_1", "%=" },
175: { TKxorass, OPxorass, "?_6", "^=" },
176: { TKandass, OPandass, "?_4", "&=" },
177: { TKorass, OPorass, "?_5", "|=" },
178: { TKshl, OPshl, "?6", "<<" },
179: { TKshr, OPshr, "?5", ">>" },
180: { TKshrass, OPshrass, "?_2", ">>=" },
181: { TKshlass, OPshlass, "?_3", "<<=" },
182: { TKeqeq, OPeqeq, "?8", "==" },
183: { TKne, OPne, "?9", "!=" },
184: { TKle, OPle, "?N", "<=" },
185: { TKge, OPge, "?P", ">=" },
186: { TKandand, OPandand, "?V", "&&" },
187: { TKoror, OPoror, "?W", "||" },
188: { TKplpl, OPpostinc, "?E", "++" },
189: { TKplpl, OPpreinc, "?E", "++" },
190: { TKmimi, OPpostdec, "?F", "--" },
191: { TKmimi, OPpredec, "?F", "--" },
192: { TKlpar, OPcall, "?R", "()" },
193: { TKlbra, OPbrack, "?A", "[]" },
194: { TKarrow, OParrow, "?C", "->" },
195: { TKcomma, OPcomma, "?Q", "," },
196: { TKarrowstar, OParrowstar, "?J", "->*" },
197: };
198:
199: /****************************************
200: * Convert from identifier to operator
201: */
202:
203: #if __GNUC__ || _MSC_VER // NOT DONE - FIX
204: char * unmangle_pt(const char **s)
205: {
206: return (char *)*s;
207: }
208: #else
209: #if __cplusplus
210: extern "C"
211: #endif
212: char * __cdecl unmangle_pt(const char **);
213:
214: #endif
215:
216: char *cpp_unmangleident(const char *p)
217: { int i;
warning C4101: 'i' : unreferenced local variable
218: MangleInuse m;
219:
220: //printf("cpp_unmangleident('%s')\n", p);
221: if (*p == '$') // if template name
222: { char *s;
223: const char *q;
224:
225: L1:
226: q = p;
227: s = unmangle_pt(&q);
228: if (s)
229: { if (strlen(s) <= BUFIDMAX)
230: p = strcpy(mangle.buf, s);
warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(105) : see declaration of 'strcpy'
231: free(s);
232: }
233: }
234: else if (*p == '?') // if operator name
235: { int i;
warning C6246: Local declaration of 'i' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '217' of 'c:\projects\extern\d\dmd\src\backend\newman.c': Lines: 217
236:
237: if (NEWTEMPMANGLE && p[1] == '$') // if template name
238: goto L1;
239: for (i = 0; i < arraysize(oparray); i++)
240: { if (strcmp(p,oparray[i].string) == 0)
241: { char *s;
242:
243: strcpy(mangle.buf, "operator ");
warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(105) : see declaration of 'strcpy'
244: switch (oparray[i].oper)
245: { case OPanew:
246: s = "new[]";
247: break;
248: case OPadelete:
249: s = "delete[]";
250: break;
251: case OPdelete:
252: s = "delete";
253: break;
254: default:
255: s = oparray[i].pretty;
256: break;
257: }
258: strcat(mangle.buf,s);
warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(110) : see declaration of 'strcat'
259: p = mangle.buf;
260: break;
261: }
262: }
263: }
264: //printf("-cpp_unmangleident() = '%s'\n", p);
265: return (char *)p;
266: }
267:
268: /****************************************
269: * Find index in oparray[] for operator.
270: * Returns:
271: * index or -1 if not found
272: */
273:
274: int cpp_opidx(int op)
275: { int i;
276:
277: for (i = 0; i < arraysize(oparray); i++)
278: if (oparray[i].oper == op)
279: return i;
280: return -1;
281: }
282:
283: /***************************************
284: * Find identifier string associated with operator.
285: * Returns:
286: * NULL if not found
287: */
288:
289: #if SCPP
290:
291: char *cpp_opident(int op)
292: { int i;
293:
294: i = cpp_opidx(op);
295: return (i == -1) ? NULL : oparray[i].string;
296: }
297:
298: #endif
299:
300: /**********************************
301: * Convert from operator token to name.
302: * Output:
303: * *poper OPxxxx
304: * *pt set to type for user defined conversion
305: * Returns:
306: * pointer to corresponding name
307: */
308:
309: #if SCPP
310:
311: char *cpp_operator(int *poper,type **pt)
312: {
313: int i;
314: type *typ_spec;
315: char *s;
316:
317: *pt = NULL;
318: stoken(); /* skip over operator keyword */
319: for (i = 0; i < arraysize(oparray); i++)
320: { if (oparray[i].tokn == tok.TKval)
321: goto L1;
322: }
323:
324: /* Look for type conversion */
325: if (type_specifier(&typ_spec))
326: { type *t;
327:
328: t = ptr_operator(typ_spec); // parse ptr-operator
329: fixdeclar(t);
330: type_free(typ_spec);
331: *pt = t;
332: return cpp_typetostring(t,"?B");
333: }
334:
335: cpperr(EM_not_overloadable); // that token cannot be overloaded
336: s = "_";
337: goto L2;
338:
339: L1:
340: s = oparray[i].string;
341: *poper = oparray[i].oper;
342: switch (*poper)
343: { case OPcall:
344: if (stoken() != TKrpar)
345: synerr(EM_rpar); /* ')' expected */
346: break;
347:
348: case OPbrack:
349: if (stoken() != TKrbra)
350: synerr(EM_rbra); /* ']' expected */
351: break;
352:
353: case OPnew:
354: if (stoken() != TKlbra)
355: goto Lret;
356: *poper = OPanew; // operator new[]
357: s = cpp_name_anew;
358: goto L3;
359:
360: case OPdelete:
361: if (stoken() != TKlbra)
362: goto Lret;
363: *poper = OPadelete; // operator delete[]
364: s = cpp_name_adelete;
365: L3:
366: if (stoken() != TKrbra)
367: synerr(EM_rbra); // ']' expected
368: if (!(config.flags4 & CFG4anew))
369: { cpperr(EM_enable_anew); // throw -Aa to support this
370: config.flags4 |= CFG4anew;
371: }
372: break;
373: }
374: L2:
375: stoken();
376: Lret:
377: return s;
378: }
379:
380: /******************************************
381: * Alternate version that works on a list of token's.
382: * Input:
383: * to list of tokens
384: * Output:
385: * *pcastoverload 1 if user defined type conversion
386: */
387:
388: char *cpp_operator2(token_t *to, int *pcastoverload)
389: {
390: int i;
391: char *s;
392: token_t *tn;
393: int oper;
394:
395: *pcastoverload = 0;
396: if (!to || !to->TKnext)
397: return NULL;
398:
399: for (i = 0; i < arraysize(oparray); i++)
400: {
401: //printf("[%d] %d, %d\n", i, oparray[i].tokn, tok.TKval);
402: if (oparray[i].tokn == to->TKval)
403: goto L1;
404: }
405:
406: //printf("cpp_operator2(): castoverload\n");
407: *pcastoverload = 1;
408: return NULL;
409:
410: L1:
411: tn = to->TKnext;
412: s = oparray[i].string;
413: oper = oparray[i].oper;
414: switch (oper)
415: { case OPcall:
416: if (tn->TKval != TKrpar)
417: synerr(EM_rpar); // ')' expected
418: break;
419:
420: case OPbrack:
421: if (tn->TKval != TKrbra)
422: synerr(EM_rbra); // ']' expected
423: break;
424:
425: case OPnew:
426: if (tn->TKval != TKlbra)
427: break;
428: oper = OPanew; // operator new[]
429: s = cpp_name_anew;
430: goto L3;
431:
432: case OPdelete:
433: if (tn->TKval != TKlbra)
434: break;
435: oper = OPadelete; // operator delete[]
436: s = cpp_name_adelete;
437: L3:
438: if (tn->TKval != TKrbra)
439: synerr(EM_rbra); // ']' expected
440: if (!(config.flags4 & CFG4anew))
441: { cpperr(EM_enable_anew); // throw -Aa to support this
442: config.flags4 |= CFG4anew;
443: }
444: break;
445: }
446: Lret:
447: return s;
448: }
449:
450: #endif
451:
452: /***********************************
453: * Generate and return a pointer to a string constructed from
454: * the type, appended to the prefix.
455: * Since these generated strings determine the uniqueness of names,
456: * they are also used to determine if two types are the same.
457: * Returns:
458: * pointer to static name[]
459: */
460:
461: char *cpp_typetostring(type *t,char *prefix)
462: { int i;
463:
464: if (prefix)
465: { strcpy(mangle.buf,prefix);
warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(105) : see declaration of 'strcpy'
466: i = strlen(prefix);
467: }
468: else
469: i = 0;
470: //dbg_printf("cpp_typetostring:\n");
471: //type_print(t);
472: MangleInuse m;
473: mangle.znamei = 0;
474: mangle.argi = 0;
475: mangle.np = mangle.buf + i;
476: mangle.buf[BUFIDMAX + 1] = 0x55;
477: cpp_data_type(t);
478: *mangle.np = 0; // 0-terminate mangle.buf[]
479: //dbg_printf("cpp_typetostring: '%s'\n", mangle.buf);
480: assert(strlen(mangle.buf) <= BUFIDMAX);
481: assert(mangle.buf[BUFIDMAX + 1] == 0x55);
482: return mangle.buf;
483: }
484:
485: /********************************
486: * 'Mangle' a name for output.
487: * Returns:
488: * pointer to mangled name (a static buffer)
489: */
490:
491: char *cpp_mangle(symbol *s)
492: {
493: symbol_debug(s);
494: //printf("cpp_mangle(s = %p, '%s')\n", s, s->Sident);
495: //type_print(s->Stype);
496:
497: #if SCPP
498: if (!CPP)
499: return symbol_ident(s);
500: #endif
501:
502: if (type_mangle(s->Stype) != mTYman_cpp)
503: return symbol_ident(s);
504: else
505: {
506: MangleInuse m;
507:
508: mangle.znamei = 0;
509: mangle.argi = 0;
510: mangle.np = mangle.buf;
511: mangle.buf[BUFIDMAX + 1] = 0x55;
512: cpp_decorated_name(s);
513: *mangle.np = 0; // 0-terminate cpp_name[]
514: //dbg_printf("cpp_mangle() = '%s'\n", mangle.buf);
515: assert(strlen(mangle.buf) <= BUFIDMAX);
516: assert(mangle.buf[BUFIDMAX + 1] == 0x55);
517: return mangle.buf;
518: }
519: }
520:
521: ///////////////////////////////////////////////////////
522:
523: /*********************************
524: * Add char into cpp_name[].
525: */
526:
527: STATIC void __inline CHAR(char c)
528: {
529: if (mangle.np < &mangle.buf[BUFIDMAX])
530: *mangle.np++ = c;
531: }
532:
533: /*********************************
534: * Add char into cpp_name[].
535: */
536:
537: STATIC void STR(const char *p)
538: {
539: size_t len;
540:
541: len = strlen(p);
542: if (mangle.np + len <= &mangle.buf[BUFIDMAX])
543: { memcpy(mangle.np,p,len);
544: mangle.np += len;
545: }
546: else
547: for (; *p; p++)
548: CHAR(*p);
549: }
550:
551: /***********************************
552: * Convert const volatile combinations into 0..3
553: */
554:
555: STATIC int cpp_cvidx(tym_t ty)
556: { int i;
557:
558: i = (ty & mTYconst) ? 1 : 0;
559: i |= (ty & mTYvolatile) ? 2 : 0;
560: return i;
561: }
562:
563: /******************************
564: * Turn protection into 0..2
565: */
566:
567: STATIC int cpp_protection(symbol *s)
568: { int i;
569:
570: switch (s->Sflags & SFLpmask)
571: { case SFLprivate: i = 0; break;
572: case SFLprotected: i = 1; break;
573: case SFLpublic: i = 2; break;
574: default:
575: #ifdef DEBUG
576: symbol_print(s);
577: #endif
578: assert(0);
579: }
580: return i;
581: }
582:
583: /***********************************
584: * Create mangled name for template instantiation.
585: */
586:
587: #if SCPP
588:
589: char *template_mangle(symbol *s,param_t *arglist)
590: {
591: /* mangling ::= '$' template_name { type | expr }
592: type ::= "T" mangled type
593: expr ::= integer | string | address | float | double | long_double
594: integer ::= "I" dimension
595: string ::= "S" string
596: address ::= "R" zname
597: float ::= "F" hex_digits
598: double ::= "D" hex_digits
599: long_double ::= "L" hex_digits
600: */
601: param_t *p;
602:
603: assert(s);
604: symbol_debug(s);
605: //assert(s->Sclass == SCtemplate);
606:
607: //printf("\ntemplate_mangle(s = '%s', arglist = %p)\n", s->Sident, arglist);
608: //arglist->print_list();
609:
610: MangleInuse m;
611: mangle.znamei = 0;
612: mangle.argi = 0;
613: mangle.np = mangle.buf;
614: mangle.buf[BUFIDMAX + 1] = 0x55;
615:
616: if (NEWTEMPMANGLE)
617: STR("?$");
618: else
619: CHAR('$');
620:
621: // BUG: this is for templates nested inside class scopes.
622: // Need to check if it creates names that are properly unmanglable.
623: cpp_zname(s->Sident);
624: if (s->Sscope)
625: cpp_scope(s->Sscope);
626:
627: for (p = arglist; p; p = p->Pnext)
628: {
629: if (p->Ptype)
630: { /* Argument is a type */
631: if (!NEWTEMPMANGLE)
632: CHAR('T');
633: cpp_argument_list(p->Ptype, 1);
634: }
635: else if (p->Psym)
636: {
637: CHAR('V'); // this is a 'class' name, but it should be a 'template' name
638: cpp_ecsu_name(p->Psym);
639: }
640: else
641: { /* Argument is an expression */
642: elem *e = p->Pelem;
643: tym_t ty = tybasic(e->ET->Tty);
644: char *p;
645: char a[2];
646: int ni;
647: char c;
648:
649: L2:
650: switch (e->Eoper)
651: { case OPconst:
652: switch (ty)
653: { case TYfloat: ni = FLOATSIZE; c = 'F'; goto L1;
654: case TYdouble_alias:
655: case TYdouble: ni = DOUBLESIZE; c = 'D'; goto L1;
656: case TYldouble: ni = LNGDBLSIZE; c = 'L'; goto L1;
657: L1:
658: if (NEWTEMPMANGLE)
659: CHAR('$');
660: CHAR(c);
661: p = (char *)&e->EV.Vdouble;
662: while (ni--)
663: { char c;
664: #if __GNUC__
665: static char hex[16] =
666: {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
667: #else
668: static char hex[16] = "0123456789ABCDEF";
669: #endif
670:
671: c = *p++;
672: CHAR(hex[c & 15]);
673: CHAR(hex[(c >> 4) & 15]);
674: }
675: break;
676: default:
677: #ifdef DEBUG
678: if (!tyintegral(ty) && !tymptr(ty))
679: elem_print(e);
680: #endif
681: assert(tyintegral(ty) || tymptr(ty));
682: if (NEWTEMPMANGLE)
683: STR("$0");
684: else
685: CHAR('I');
686: cpp_dimension(el_tolongt(e));
687: break;
688: }
689: break;
690: case OPstring:
691: if (NEWTEMPMANGLE)
692: STR("$S");
693: else
694: CHAR('S');
695: if (e->EV.ss.Voffset)
696: synerr(EM_const_init); // constant initializer expected
697: cpp_string(e->EV.ss.Vstring,e->EV.ss.Vstrlen);
698: break;
699: case OPrelconst:
700: if (e->EV.sp.Voffset)
701: synerr(EM_const_init); // constant initializer expected
702: s = e->EV.sp.Vsym;
703: if (NEWTEMPMANGLE)
704: { STR("$1");
705: cpp_decorated_name(s);
706: }
707: else
708: { CHAR('R');
709: cpp_zname(s->Sident);
710: }
711: break;
712: case OPvar:
713: if (e->EV.sp.Vsym->Sflags & SFLvalue &&
714: tybasic(e->ET->Tty) != TYstruct)
715: {
716: e = e->EV.sp.Vsym->Svalue;
717: goto L2;
718: }
719: else if (e->EV.sp.Vsym->Sclass == SCconst /*&&
720: pstate.STintemplate*/)
721: {
722: CHAR('V'); // pretend to be a class name
723: cpp_zname(e->EV.sp.Vsym->Sident);
724: break;
725: }
726: default:
727: #if SCPP
728: #ifdef DEBUG
729: if (!errcnt)
730: elem_print(e);
731: #endif
732: synerr(EM_const_init); // constant initializer expected
733: assert(errcnt);
734: #endif
735: break;
736: }
737: }
738: }
739: *mangle.np = 0;
740: //printf("template_mangle() = '%s'\n", mangle.buf);
741: assert(strlen(mangle.buf) <= BUFIDMAX);
742: assert(mangle.buf[BUFIDMAX + 1] == 0x55);
743: return mangle.buf;
744: }
745:
746: #endif
747:
748: //////////////////////////////////////////////////////
749: // Functions corresponding to the name mangling grammar in the
750: // "Microsoft Object Mapping Specification"
751:
752: STATIC void cpp_string(char *s,size_t len)
753: { char c;
754:
755: for (; --len; s++)
756: { static char special_char[] = ",/\\:. \n\t'-";
757: char *p;
758:
759: c = *s;
760: if (c & 0x80 && isalpha(c & 0x7F))
761: { CHAR('?');
762: c &= 0x7F;
763: }
764: else if (isalnum(c))
warning C6328: 'char' passed as parameter '1' when 'unsigned char' is required in call to 'isalnum'
765: ;
766: else
767: {
768: CHAR('?');
769: if ((p = (char *)strchr(special_char,c)) != NULL)
770: c = '0' + (p - special_char);
771: else
772: {
773: CHAR('$');
774: CHAR('A' + ((c >> 4) & 0x0F));
775: c = 'A' + (c & 0x0F);
776: }
777: }
778: CHAR(c);
779: }
780: CHAR('@');
781: }
782:
783: STATIC void cpp_dimension(targ_ullong u)
784: {
785: if (u && u <= 10)
786: CHAR('0' + (char)u - 1);
787: else
788: { char buffer[sizeof(u) * 2 + 1];
789: char __ss *p;
790:
791: buffer[sizeof(buffer) - 1] = 0;
792: for (p = &buffer[sizeof(buffer) - 1]; u; u >>= 4)
warning C6295: Ill-defined for-loop: 'unsigned __int64' values are always of range '0' to '18446744073709551615'. Loop executes infinitely
793: {
794: *--p = 'A' + (u & 0x0F);
795: }
796: STR(p);
797: CHAR('@');
798: }
799: }
800:
801: #if 0
802: STATIC void cpp_dimension_ld(targ_ldouble ld)
803: { unsigned char ldbuf[sizeof(targ_ldouble)];
804:
805: memcpy(ldbuf,&ld,sizeof(ld));
806: if (u && u <= 10)
807: CHAR('0' + (char)u - 1);
808: else
809: { char buffer[sizeof(u) * 2 + 1];
810: char __ss *p;
811:
812: buffer[sizeof(buffer) - 1] = 0;
813: for (p = &buffer[sizeof(buffer) - 1]; u; u >>= 4)
814: {
815: *--p = 'A' + (u & 0x0F);
816: }
817: STR(p);
818: CHAR('@');
819: }
820: }
821: #endif
822:
823: STATIC void cpp_enum_name(symbol *s)
824: { type *t;
825: char c;
826:
827: t = tsint;
828: switch (tybasic(t->Tty))
829: {
830: case TYschar: c = '0'; break;
831: case TYuchar: c = '1'; break;
832: case TYshort: c = '2'; break;
833: case TYushort: c = '3'; break;
834: case TYint: c = '4'; break;
835: case TYuint: c = '5'; break;
836: case TYlong: c = '6'; break;
837: case TYulong: c = '7'; break;
838: default: assert(0);
839: }
840: CHAR(c);
841: cpp_ecsu_name(s);
842: }
843:
844: STATIC void cpp_reference_data_type(type *t, int flag)
845: {
846: if (tybasic(t->Tty) == TYarray)
847: {
848: int ndim;
849: type *tn;
850: int i;
851:
852: CHAR('Y');
853:
854: // Compute number of dimensions (we have at least one)
855: ndim = 0;
856: tn = t;
857: do
858: { ndim++;
859: tn = tn->Tnext;
860: } while (tybasic(tn->Tty) == TYarray);
861:
862: cpp_dimension(ndim);
863: for (; tybasic(t->Tty) == TYarray; t = t->Tnext)
864: {
865: if (t->Tflags & TFvla)
866: CHAR('X'); // DMC++ extension
867: else
868: cpp_dimension(t->Tdim);
869: }
870:
871: // DMC++ extension
872: if (flag) // if template type argument
873: {
874: i = cpp_cvidx(t->Tty);
875: if (i)
876: { CHAR('_');
877: //CHAR('X' + i - 1); // _X, _Y, _Z
878: CHAR('O' + i - 1); // _O, _P, _Q
879: }
880: }
881:
882: cpp_basic_data_type(t);
883: }
884: else
885: cpp_basic_data_type(t);
886: }
887:
888: STATIC void cpp_pointer_data_type(type *t)
889: {
890: if (tybasic(t->Tty) == TYvoid)
891: CHAR('X');
892: else
893: cpp_reference_data_type(t, 0);
894: }
895:
896: STATIC void cpp_ecsu_data_type(type *t)
897: { char c;
898: symbol *stag;
899: int i;
warning C4101: 'i' : unreferenced local variable
900:
901: type_debug(t);
902: switch (tybasic(t->Tty))
903: {
904: case TYstruct:
905: stag = t->Ttag;
906: switch (stag->Sstruct->Sflags & (STRclass | STRunion))
907: { case 0: c = 'U'; break;
908: case STRunion: c = 'T'; break;
909: case STRclass: c = 'V'; break;
910: default:
911: assert(0);
912: }
913: CHAR(c);
914: cpp_ecsu_name(stag);
915: break;
916: case TYenum:
917: CHAR('W');
918: cpp_enum_name(t->Ttag);
919: break;
920: default:
921: #ifdef DEBUG
922: type_print(t);
923: #endif
924: assert(0);
925: }
926: }
927:
928: STATIC void cpp_basic_data_type(type *t)
929: { char c;
930: int i;
931:
932: //printf("cpp_basic_data_type(t)\n");
933: //type_print(t);
934: switch (tybasic(t->Tty))
935: {
936: case TYschar: c = 'C'; goto dochar;
937: case TYchar: c = 'D'; goto dochar;
938: case TYuchar: c = 'E'; goto dochar;
939: case TYshort: c = 'F'; goto dochar;
940: case TYushort: c = 'G'; goto dochar;
941: case TYint: c = 'H'; goto dochar;
942: case TYuint: c = 'I'; goto dochar;
943: case TYlong: c = 'J'; goto dochar;
944: case TYulong: c = 'K'; goto dochar;
945: case TYfloat: c = 'M'; goto dochar;
946: case TYdouble: c = 'N'; goto dochar;
947:
948: case TYdouble_alias:
949: if (intsize == 4)
950: { c = 'O';
951: goto dochar;
952: }
953: c = 'Z';
954: goto dochar2;
955:
956: case TYldouble:
957: if (intsize == 2)
958: { c = 'O';
959: goto dochar;
960: }
961: c = 'Z';
962: goto dochar2;
963: dochar:
964: CHAR(c);
965: break;
966:
967: case TYllong: c = 'J'; goto dochar2;
968: case TYullong: c = 'K'; goto dochar2;
969: case TYbool: c = 'N'; goto dochar2; // was 'X' prior to 8.1b8
970: case TYwchar_t:
971: if (config.flags4 & CFG4nowchar_t)
972: {
973: c = 'G';
974: goto dochar; // same as TYushort
975: }
976: else
977: {
978: pstate.STflags |= PFLmfc;
979: c = 'Y';
980: goto dochar2;
981: }
982:
983: // Digital Mars extensions
984: case TYifloat: c = 'R'; goto dochar2;
985: case TYidouble: c = 'S'; goto dochar2;
986: case TYildouble: c = 'T'; goto dochar2;
987: case TYcfloat: c = 'U'; goto dochar2;
988: case TYcdouble: c = 'V'; goto dochar2;
989: case TYcldouble: c = 'W'; goto dochar2;
990:
991: case TYchar16: c = 'X'; goto dochar2;
992: case TYdchar: c = 'Y'; goto dochar2;
993: case TYnullptr: c = 'Z'; goto dochar2;
994:
995: dochar2:
996: CHAR('_');
997: goto dochar;
998:
999: case TYsptr:
1000: case TYnptr:
1001: case TYcptr:
1002: case TYf16ptr:
1003: case TYfptr:
1004: case TYhptr:
1005: case TYvptr:
1006: case TYmemptr:
1007: c = 'P' + cpp_cvidx(t->Tty);
1008: CHAR(c);
1009: cpp_pointer_type(t);
1010: break;
1011: case TYstruct:
1012: case TYenum:
1013: cpp_ecsu_data_type(t);
1014: break;
1015: case TYarray:
1016: i = cpp_cvidx(t->Tty);
1017: i |= 1; // always const
1018: CHAR('P' + i);
1019: cpp_pointer_type(t);
1020: break;
1021: case TYvoid:
1022: c = 'X';
1023: goto dochar;
1024: case TYident:
1025: if (pstate.STintemplate)
1026: {
1027: CHAR('V'); // pretend to be a class name
1028: cpp_zname(t->Tident);
1029: }
1030: else
1031: {
1032: #if SCPP
1033: cpperr(EM_no_type,t->Tident); // no type for argument
1034: #endif
1035: c = 'X';
1036: goto dochar;
1037: }
1038: break;
1039: case TYtemplate:
1040: if (pstate.STintemplate)
1041: {
1042: CHAR('V'); // pretend to be a class name
1043: cpp_zname(((typetemp_t *)t)->Tsym->Sident);
1044: }
1045: else
1046: goto Ldefault;
1047: break;
1048:
1049: default:
1050: Ldefault:
1051: if (tyfunc(t->Tty))
1052: cpp_function_type(t);
1053: else
1054: {
1055: #if SCPP
1056: #ifdef DEBUG
1057: if (!errcnt)
1058: type_print(t);
1059: #endif
1060: assert(errcnt);
1061: #endif
1062: }
1063: }
1064: }
1065:
1066: STATIC void cpp_function_indirect_type(type *t)
1067: { int farfunc;
1068:
1069: farfunc = tyfarfunc(t->Tnext->Tty) != 0;
1070: if (tybasic(t->Tty) == TYmemptr)
1071: {
1072: CHAR('8' + farfunc);
1073: cpp_scope(t->Ttag);
1074: CHAR('@');
1075: //cpp_this_type(t->Tnext,t->Ttag); // MSC doesn't do this
1076: }
1077: else
1078: CHAR('6' + farfunc);
1079: }
1080:
1081: STATIC void cpp_data_indirect_type(type *t)
1082: { int i;
1083:
1084: if (tybasic(t->Tty) == TYmemptr) // if pointer to member
1085: {
1086: i = cpp_cvidx(t->Tty);
1087: if (t->Tty & mTYfar)
1088: i += 4;
1089: CHAR('Q' + i);
1090: cpp_scope(t->Ttag);
1091: CHAR('@');
1092: }
1093: else
1094: cpp_ecsu_data_indirect_type(t);
1095: }
1096:
1097: STATIC void cpp_ecsu_data_indirect_type(type *t)
1098: { int i;
1099: tym_t ty;
1100:
1101: i = 0;
1102: if (t->Tnext)
1103: { ty = t->Tnext->Tty & (mTYconst | mTYvolatile);
1104: switch (tybasic(t->Tty))
1105: { case TYfptr:
1106: case TYvptr:
1107: case TYfref:
1108: ty |= mTYfar;
1109: break;
1110: case TYref:
1111: case TYarray:
1112: if (LARGEDATA && !(ty & mTYLINK))
1113: ty |= mTYfar;
1114: break;
1115: case TYhptr:
1116: i += 8;
1117: break;
1118: }
1119: }
1120: else
1121: ty = t->Tty & (mTYLINK | mTYconst | mTYvolatile);
1122: i |= cpp_cvidx(ty);
1123: if (ty & (mTYcs | mTYfar))
1124: i += 4;
1125: CHAR('A' + i);
1126: }
1127:
1128: STATIC void cpp_pointer_type(type *t)
1129: { tym_t ty;
warning C4101: 'ty' : unreferenced local variable
1130:
1131: if (tyfunc(t->Tnext->Tty))
1132: {
1133: cpp_function_indirect_type(t);
1134: cpp_function_type(t->Tnext);
1135: }
1136: else
1137: {
1138: cpp_data_indirect_type(t);
1139: cpp_pointer_data_type(t->Tnext);
1140: }
1141: }
1142:
1143: STATIC void cpp_reference_type(type *t)
1144: {
1145: cpp_data_indirect_type(t);
1146: cpp_reference_data_type(t->Tnext, 0);
1147: }
1148:
1149: STATIC void cpp_primary_data_type(type *t)
1150: {
1151: if (tyref(t->Tty))
1152: {
1153: #if 1
1154: // C++98 8.3.2 says cv-qualified references are ignored
1155: CHAR('A');
1156: #else
1157: switch (t->Tty & (mTYconst | mTYvolatile))
1158: {
1159: case 0: CHAR('A'); break;
1160: case mTYvolatile: CHAR('B'); break;
1161:
1162: // Digital Mars extensions
1163: case mTYconst | mTYvolatile: CHAR('_'); CHAR('L'); break;
1164: case mTYconst: CHAR('_'); CHAR('M'); break;
1165: }
1166: #endif
1167: cpp_reference_type(t);
1168: }
1169: else
1170: cpp_basic_data_type(t);
1171: }
1172:
1173: /*****
1174: * flag: 1 = template argument
1175: */
1176:
1177: STATIC void cpp_argument_list(type *t, int flag)
1178: { int i;
1179: tym_t ty;
1180:
1181: //printf("cpp_argument_list(flag = %d)\n", flag);
1182: // If a data type that encodes only into one character
1183: ty = tybasic(t->Tty);
1184: if (ty <= TYldouble && ty != TYenum
1185: && ty != TYbool // added for versions >= 8.1b9
1186: #if OVERLOAD_CV_PARAM
1187: && !(t->Tty & (mTYconst | mTYvolatile))
1188: #endif
1189: )
1190: {
1191: cpp_primary_data_type(t);
1192: }
1193: else
1194: {
1195: // See if a match with a previously used type
1196: for (i = 0; 1; i++)
1197: {
1198: if (i == mangle.argi) // no match
1199: {
1200: #if OVERLOAD_CV_PARAM
1201: if (ty <= TYcldouble || ty == TYstruct)
1202: {
1203: int cvidx = cpp_cvidx(t->Tty);
1204: if (cvidx)
1205: {
1206: // Digital Mars extensions
1207: CHAR('_');
1208: CHAR('N' + cvidx); // _O, _P, _Q prefix
1209: }
1210: }
1211: #endif
1212: if (flag && tybasic(t->Tty) == TYarray)
1213: {
1214: cpp_reference_data_type(t, flag);
1215: }
1216: else
1217: cpp_primary_data_type(t);
1218: if (mangle.argi < 10)
1219: mangle.arg[mangle.argi++] = t;
1220: break;
1221: }
1222: if (typematch(t,mangle.arg[i],0))
1223: {
1224: CHAR('0' + i); // argument_replicator
1225: break;
1226: }
1227: }
1228: }
1229: }
1230:
1231: STATIC void cpp_argument_types(type *t)
1232: { param_t *p;
1233: char c;
1234:
1235: //printf("cpp_argument_types()\n");
1236: //type_debug(t);
1237: for (p = t->Tparamtypes; p; p = p->Pnext)
1238: cpp_argument_list(p->Ptype, 0);
1239: if (t->Tflags & TFfixed)
1240: c = t->Tparamtypes ? '@' : 'X';
1241: else
1242: c = 'Z';
1243: CHAR(c);
1244: }
1245:
1246: STATIC void cpp_calling_convention(type *t)
1247: { char c;
1248:
1249: switch (tybasic(t->Tty))
1250: {
1251: case TYnfunc:
1252: case TYhfunc:
1253: case TYffunc: c = 'A'; break;
1254: case TYf16func:
1255: case TYnpfunc:
1256: case TYfpfunc: c = 'C'; break;
1257: case TYnsfunc:
1258: case TYfsfunc: c = 'G'; break;
1259: case TYjfunc:
1260: case TYmfunc:
1261: case TYnsysfunc:
1262: case TYfsysfunc: c = 'E'; break;
1263: case TYifunc: c = 'K'; break;
1264: default:
1265: assert(0);
1266: }
1267: CHAR(c);
1268: }
1269:
1270: STATIC void cpp_vcall_model_type()
1271: {
1272: }
1273:
1274: #if SCPP || MARS
1275:
1276: STATIC void cpp_this_type(type *tfunc,Classsym *stag)
1277: { type *t;
1278:
1279: type_debug(tfunc);
1280: symbol_debug(stag);
1281: #if MARS
1282: t = type_allocn(TYnptr, stag->Stype);
1283: t->Tcount++;
1284: #else
1285: t = cpp_thistype(tfunc,stag);
1286: #endif
1287: //cpp_data_indirect_type(t);
1288: cpp_ecsu_data_indirect_type(t);
1289: type_free(t);
1290: }
1291:
1292: #endif
1293:
1294: STATIC void cpp_storage_convention(symbol *s)
1295: { tym_t ty;
1296: type *t = s->Stype;
1297:
1298: ty = t->Tty;
1299: if (LARGEDATA && !(ty & mTYLINK))
1300: t->Tty |= mTYfar;
1301: cpp_data_indirect_type(t);
1302: t->Tty = ty;
1303: }
1304:
1305: STATIC void cpp_data_type(type *t)
1306: {
1307: type_debug(t);
1308: switch (tybasic(t->Tty))
1309: { case TYvoid:
1310: CHAR('X');
1311: break;
1312: case TYstruct:
1313: case TYenum:
1314: CHAR('?');
1315: cpp_ecsu_data_indirect_type(t);
1316: cpp_ecsu_data_type(t);
1317: break;
1318: default:
1319: cpp_primary_data_type(t);
1320: break;
1321: }
1322: }
1323:
1324: STATIC void cpp_return_type(symbol *s)
1325: {
1326: if (s->Sfunc->Fflags & (Fctor | Fdtor)) // if ctor or dtor
1327: CHAR('@'); // no type
1328: else
1329: cpp_data_type(s->Stype->Tnext);
1330: }
1331:
1332: STATIC void cpp_ecsu_name(symbol *s)
1333: {
1334: //printf("cpp_ecsu_name(%s)\n", symbol_ident(s));
1335: cpp_zname(symbol_ident(s));
1336: #if SCPP || MARS
1337: if (s->Sscope)
1338: cpp_scope(s->Sscope);
1339: #endif
1340: CHAR('@');
1341: }
1342:
1343: STATIC void cpp_throw_types(type *t)
1344: {
1345: //cpp_argument_types(?);
1346: CHAR('Z');
1347: }
1348:
1349: STATIC void cpp_function_type(type *t)
1350: { tym_t ty;
1351: type *tn;
1352:
1353: //printf("cpp_function_type()\n");
1354: //type_debug(t);
1355: assert(tyfunc(t->Tty));
1356: cpp_calling_convention(t);
1357: //cpp_return_type(s);
1358: tn = t->Tnext;
1359: ty = tn->Tty;
1360: if (LARGEDATA && (tybasic(ty) == TYstruct || tybasic(ty) == TYenum) &&
1361: !(ty & mTYLINK))
1362: tn->Tty |= mTYfar;
1363: cpp_data_type(tn);
1364: tn->Tty = ty;
1365: cpp_argument_types(t);
1366: cpp_throw_types(t);
1367: }
1368:
1369: STATIC void cpp_adjustor_thunk_type(symbol *s)
1370: {
1371: }
1372:
1373: STATIC void cpp_vftable_type(symbol *s)
1374: {
1375: cpp_ecsu_data_indirect_type(s->Stype);
1376: // vpath_name();
1377: CHAR('@');
1378: }
1379:
1380: STATIC void cpp_local_static_data_type(symbol *s)
1381: {
1382: //cpp_lexical_frame(?);
1383: cpp_external_data_type(s);
1384: }
1385:
1386: STATIC void cpp_static_member_data_type(symbol *s)
1387: {
1388: cpp_external_data_type(s);
1389: }
1390:
1391: STATIC void cpp_static_member_function_type(symbol *s)
1392: {
1393: cpp_function_type(s->Stype);
1394: }
1395:
1396: #if SCPP || MARS
1397: STATIC void cpp_member_function_type(symbol *s)
1398: {
1399: assert(tyfunc(s->Stype->Tty));
1400: cpp_this_type(s->Stype,(Classsym *)s->Sscope);
1401: if (s->Sfunc->Fflags & (Fctor | Fdtor))
1402: { type *t = s->Stype;
1403:
1404: cpp_calling_convention(t);
1405: CHAR('@'); // return_type for ctors & dtors
1406: cpp_argument_types(t);
1407: cpp_throw_types(t);
1408: }
1409: else
1410: cpp_static_member_function_type(s);
1411: }
1412: #endif
1413:
1414: STATIC void cpp_external_data_type(symbol *s)
1415: {
1416: cpp_primary_data_type(s->Stype);
1417: cpp_storage_convention(s);
1418: }
1419:
1420: STATIC void cpp_external_function_type(symbol *s)
1421: {
1422: cpp_function_type(s->Stype);
1423: }
1424:
1425: STATIC void cpp_type_encoding(symbol *s)
1426: { char c;
warning C4101: 'c' : unreferenced local variable
1427:
1428: //printf("cpp_type_encoding()\n");
1429: if (tyfunc(s->Stype->Tty))
1430: { int farfunc;
1431:
1432: farfunc = tyfarfunc(s->Stype->Tty) != 0;
1433: #if SCPP || MARS
1434: if (isclassmember(s))
1435: { // Member function
1436: int protection;
1437: int ftype;
1438:
1439: protection = cpp_protection(s);
1440: if (s->Sfunc->Fthunk && !(s->Sfunc->Fflags & Finstance))
1441: ftype = 3;
1442: else
1443: switch (s->Sfunc->Fflags & (Fvirtual | Fstatic))
1444: { case Fvirtual: ftype = 2; break;
1445: case Fstatic: ftype = 1; break;
1446: case 0: ftype = 0; break;
1447: default: assert(0);
1448: }
1449: CHAR('A' + farfunc + protection * 8 + ftype * 2);
1450: switch (ftype)
1451: { case 0: cpp_member_function_type(s); break;
1452: case 1: cpp_static_member_function_type(s); break;
1453: case 2: cpp_member_function_type(s); break;
1454: case 3: cpp_adjustor_thunk_type(s); break;
1455: }
1456: }
1457: else
1458: #endif
1459: { // Non-member function
1460: CHAR('Y' + farfunc);
1461: cpp_external_function_type(s);
1462: }
1463: }
1464: else
1465: {
1466: #if SCPP || MARS
1467: if (isclassmember(s))
1468: {
1469: { // Static data member
1470: CHAR(cpp_protection(s) + '0');
1471: cpp_static_member_data_type(s);
1472: }
1473: }
1474: else
1475: #endif
1476: {
1477: if (s->Sclass == SCstatic
1478: #if SCPP || MARS
1479: || (s->Sscope &&
1480: s->Sscope->Sclass != SCstruct &&
1481: s->Sscope->Sclass != SCnamespace)
1482: #endif
1483: )
1484: { CHAR('4');
1485: cpp_local_static_data_type(s);
1486: }
1487: else
1488: { CHAR('3');
1489: cpp_external_data_type(s);
1490: }
1491: }
1492: }
1493: }
1494:
1495: STATIC void cpp_scope(symbol *s)
1496: {
1497: /* scope ::=
1498: zname [ scope ]
1499: '?' decorated_name [ scope ]
1500: '?' lexical_frame [ scope ]
1501: '?' '$' template_name [ scope ]
1502: */
1503: while (s)
1504: { char *p;
warning C4101: 'p' : unreferenced local variable
1505:
1506: symbol_debug(s);
1507: switch (s->Sclass)
1508: {
1509: case SCnamespace:
1510: cpp_zname(s->Sident);
1511: break;
1512:
1513: case SCstruct:
1514: cpp_zname(symbol_ident(s));
1515: break;
1516:
1517: default:
1518: STR("?1?"); // Why? Who knows.
1519: cpp_decorated_name(s);
1520: break;
1521: }
1522: #if SCPP || MARS
1523: s = s->Sscope;
1524: #else
1525: break;
1526: #endif
1527: }
1528: }
1529:
1530: STATIC void cpp_zname(const char *p)
1531: {
1532: //printf("cpp_zname(%s)\n", p);
1533: if (*p != '?' || // if not operator_name
1534: (NEWTEMPMANGLE && p[1] == '$')) // ?$ is a template name
1535: {
1536: #if MARS
1537: /* Scan forward past any dots
1538: */
1539: for (const char *q = p; *q; q++)
1540: {
1541: if (*q == '.')
1542: p = q + 1;
1543: }
1544: #endif
1545:
1546: for (int i = 0; i < mangle.znamei; i++)
1547: {
1548: if (strcmp(p,mangle.zname[i]) == 0)
1549: { CHAR('0' + i);
1550: return;
1551: }
1552: }
1553: if (mangle.znamei < 10)
1554: mangle.zname[mangle.znamei++] = p;
1555: STR(p);
1556: CHAR('@');
1557: }
1558: else if (p[1] == 'B')
1559: STR("?B"); // skip return value encoding
1560: else
1561: {
1562: STR(p);
1563: }
1564: }
1565:
1566: STATIC void cpp_symbol_name(symbol *s)
1567: { char *p;
1568:
1569: p = s->Sident;
1570: #if SCPP
1571: if (tyfunc(s->Stype->Tty) && s->Sfunc)
1572: {
1573: if (s->Sfunc->Fflags & Finstance)
1574: {
1575: Mangle save = mangle;
1576: char *q;
1577: int len;
1578:
1579: p = template_mangle(s, s->Sfunc->Fptal);
1580: len = strlen(p);
1581: q = (char *)alloca(len + 1);
1582: memcpy(q, p, len + 1);
1583: mangle = save;
1584: p = q;
1585: }
1586: else if (s->Sfunc->Fflags & Foperator)
1587: { // operator_name ::= '?' operator_code
1588: //CHAR('?'); // already there
1589: STR(p);
1590: return;
1591: }
1592: }
1593: #endif
1594: cpp_zname(p);
1595: }
1596:
1597: STATIC void cpp_decorated_name(symbol *s)
1598: { char *p;
warning C4101: 'p' : unreferenced local variable
1599:
1600: CHAR('?');
1601: cpp_symbol_name(s);
1602: #if SCPP || MARS
1603: if (s->Sscope)
1604: cpp_scope(s->Sscope);
1605: #endif
1606: CHAR('@');
1607: cpp_type_encoding(s);
1608: }
1609:
1610: /*********************************
1611: * Mangle a vtbl or vbtbl name.
1612: * Returns:
1613: * pointer to generated symbol with mangled name
1614: */
1615:
1616: #if SCPP
1617:
1618: symbol *mangle_tbl(
1619: int flag, // 0: vtbl, 1: vbtbl
1620: type *t, // type for symbol
1621: Classsym *stag, // class we're putting tbl in
1622: baseclass_t *b) // base class (NULL if none)
1623: { const char *id;
1624: symbol *s;
1625:
1626: #if 0
1627: dbg_printf("mangle_tbl(stag = '%s', sbase = '%s', parent = '%s')\n",
1628: stag->Sident,b ? b->BCbase->Sident : "NULL", b ? b->parent->Sident : "NULL");
1629: #endif
1630: if (flag == 0)
1631: id = config.flags3 & CFG3rtti ? "?_Q" : "?_7";
1632: else
1633: id = "?_8";
1634: MangleInuse m;
1635: mangle.znamei = 0;
1636: mangle.argi = 0;
1637: mangle.np = mangle.buf;
1638: CHAR('?');
1639: cpp_zname(id);
1640: cpp_scope(stag);
1641: CHAR('@');
1642: CHAR('6' + flag);
1643: cpp_ecsu_data_indirect_type(t);
1644: #if 1
1645: while (b)
1646: {
1647: cpp_scope(b->BCbase);
1648: CHAR('@');
1649: b = b->BCpbase;
1650: }
1651: #else
1652: if (b)
1653: { cpp_scope(b->BCbase);
1654: CHAR('@');
1655: // BUG: what if b is more than one level down?
1656: if (b->parent != stag)
1657: { cpp_scope(b->BCparent);
1658: CHAR('@');
1659: }
1660: }
1661: #endif
1662: CHAR('@');
1663: *mangle.np = 0; // 0-terminate mangle.buf[]
1664: assert(strlen(mangle.buf) <= BUFIDMAX);
1665: s = scope_define(mangle.buf,SCTglobal | SCTnspace | SCTlocal,SCunde);
1666: s->Stype = t;
1667: t->Tcount++;
1668: return s;
1669: }
1670:
1671: #endif
1672:
1673: #endif
1674:
1675: #endif
1676: