symbol *mangle_tbl( int flag, // 0: vtbl, 1: vbtbl type *t, // type for symbol Classsym *stag, // class we're putting tbl in baseclass_t *b) // base class (NULL if none) { const char *id; symbol *s; #if 0 dbg_printf("mangle_tbl(stag = '%s', sbase = '%s', parent = '%s')\n", stag->Sident,b ? b->BCbase->Sident : "NULL", b ? b->parent->Sident : "NULL"); #endif if (flag == 0) id = config.flags3 & CFG3rtti ? "?_Q" : "?_7"; else id = "?_8"; MangleInuse m; mangle.znamei = 0; mangle.argi = 0; mangle.np = mangle.buf; CHAR('?'); cpp_zname(id); cpp_scope(stag); CHAR('@'); CHAR('6' + flag); cpp_ecsu_data_indirect_type(t); #if 1 while (b) { cpp_scope(b->BCbase); CHAR('@'); b = b->BCpbase; } #else if (b) { cpp_scope(b->BCbase); CHAR('@'); // BUG: what if b is more than one level down? if (b->parent != stag) { cpp_scope(b->BCparent); CHAR('@'); } } #endif CHAR('@'); *mangle.np = 0; // 0-terminate mangle.buf[] assert(strlen(mangle.buf) <= BUFIDMAX); s = scope_define(mangle.buf,SCTglobal | SCTnspace | SCTlocal,SCunde); s->Stype = t; t->Tcount++; return s; }
STATIC void cpp_ecsu_name(symbol *s) { //printf("cpp_ecsu_name(%s)\n", symbol_ident(s)); cpp_zname(symbol_ident(s)); #if SCPP || MARS if (s->Sscope) cpp_scope(s->Sscope); #endif CHAR('@'); }
STATIC void cpp_decorated_name(symbol *s) { char *p; CHAR('?'); cpp_symbol_name(s); #if SCPP || MARS if (s->Sscope) cpp_scope(s->Sscope); #endif CHAR('@'); cpp_type_encoding(s); }
STATIC void cpp_function_indirect_type(type *t) { int farfunc; farfunc = tyfarfunc(t->Tnext->Tty) != 0; if (tybasic(t->Tty) == TYmemptr) { CHAR('8' + farfunc); cpp_scope(t->Ttag); CHAR('@'); //cpp_this_type(t->Tnext,t->Ttag); // MSC doesn't do this } else CHAR('6' + farfunc); }
STATIC void cpp_data_indirect_type(type *t) { int i; if (tybasic(t->Tty) == TYmemptr) // if pointer to member { i = cpp_cvidx(t->Tty); if (t->Tty & mTYfar) i += 4; CHAR('Q' + i); cpp_scope(t->Ttag); CHAR('@'); } else cpp_ecsu_data_indirect_type(t); }
char *template_mangle(symbol *s,param_t *arglist) { /* mangling ::= '$' template_name { type | expr } type ::= "T" mangled type expr ::= integer | string | address | float | double | long_double integer ::= "I" dimension string ::= "S" string address ::= "R" zname float ::= "F" hex_digits double ::= "D" hex_digits long_double ::= "L" hex_digits */ param_t *p; assert(s); symbol_debug(s); //assert(s->Sclass == SCtemplate); //printf("\ntemplate_mangle(s = '%s', arglist = %p)\n", s->Sident, arglist); //arglist->print_list(); MangleInuse m; mangle.znamei = 0; mangle.argi = 0; mangle.np = mangle.buf; mangle.buf[BUFIDMAX + 1] = 0x55; if (NEWTEMPMANGLE) STR("?$"); else CHAR('$'); // BUG: this is for templates nested inside class scopes. // Need to check if it creates names that are properly unmanglable. cpp_zname(s->Sident); if (s->Sscope) cpp_scope(s->Sscope); for (p = arglist; p; p = p->Pnext) { if (p->Ptype) { /* Argument is a type */ if (!NEWTEMPMANGLE) CHAR('T'); cpp_argument_list(p->Ptype, 1); } else if (p->Psym) { CHAR('V'); // this is a 'class' name, but it should be a 'template' name cpp_ecsu_name(p->Psym); } else { /* Argument is an expression */ elem *e = p->Pelem; tym_t ty = tybasic(e->ET->Tty); char *p; char a[2]; int ni; char c; L2: switch (e->Eoper) { case OPconst: switch (ty) { case TYfloat: ni = FLOATSIZE; c = 'F'; goto L1; case TYdouble_alias: case TYdouble: ni = DOUBLESIZE; c = 'D'; goto L1; case TYldouble: ni = LNGDBLSIZE; c = 'L'; goto L1; L1: if (NEWTEMPMANGLE) CHAR('$'); CHAR(c); p = (char *)&e->EV.Vdouble; while (ni--) { char c; #if __GNUC__ static char hex[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; #else static char hex[16] = "0123456789ABCDEF"; #endif c = *p++; CHAR(hex[c & 15]); CHAR(hex[(c >> 4) & 15]); } break; default: #ifdef DEBUG if (!tyintegral(ty) && !tymptr(ty)) elem_print(e); #endif assert(tyintegral(ty) || tymptr(ty)); if (NEWTEMPMANGLE) STR("$0"); else CHAR('I'); cpp_dimension(el_tolongt(e)); break; } break; case OPstring: if (NEWTEMPMANGLE) STR("$S"); else CHAR('S'); if (e->EV.ss.Voffset) synerr(EM_const_init); // constant initializer expected cpp_string(e->EV.ss.Vstring,e->EV.ss.Vstrlen); break; case OPrelconst: if (e->EV.sp.Voffset) synerr(EM_const_init); // constant initializer expected s = e->EV.sp.Vsym; if (NEWTEMPMANGLE) { STR("$1"); cpp_decorated_name(s); } else { CHAR('R'); cpp_zname(s->Sident); } break; case OPvar: if (e->EV.sp.Vsym->Sflags & SFLvalue && tybasic(e->ET->Tty) != TYstruct) { e = e->EV.sp.Vsym->Svalue; goto L2; } else if (e->EV.sp.Vsym->Sclass == SCconst /*&& pstate.STintemplate*/) { CHAR('V'); // pretend to be a class name cpp_zname(e->EV.sp.Vsym->Sident); break; } default: #if SCPP #ifdef DEBUG if (!errcnt) elem_print(e); #endif synerr(EM_const_init); // constant initializer expected assert(errcnt); #endif break; } } } *mangle.np = 0; //printf("template_mangle() = '%s'\n", mangle.buf); assert(strlen(mangle.buf) <= BUFIDMAX); assert(mangle.buf[BUFIDMAX + 1] == 0x55); return mangle.buf; }