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: