STATIC void cpp_scope(symbol *s) { /* scope ::= zname [ scope ] '?' decorated_name [ scope ] '?' lexical_frame [ scope ] '?' '$' template_name [ scope ] */ while (s) { char *p; symbol_debug(s); switch (s->Sclass) { case SCnamespace: cpp_zname(s->Sident); break; case SCstruct: cpp_zname(symbol_ident(s)); break; default: STR("?1?"); // Why? Who knows. cpp_decorated_name(s); break; } #if SCPP || MARS s = s->Sscope; #else break; #endif } }
STATIC void cpp_symbol_name(symbol *s) { char *p; p = s->Sident; #if SCPP if (tyfunc(s->Stype->Tty) && s->Sfunc) { if (s->Sfunc->Fflags & Finstance) { Mangle save = mangle; char *q; int len; p = template_mangle(s, s->Sfunc->Fptal); len = strlen(p); q = (char *)alloca(len + 1); memcpy(q, p, len + 1); mangle = save; p = q; } else if (s->Sfunc->Fflags & Foperator) { // operator_name ::= '?' operator_code //CHAR('?'); // already there STR(p); return; } } #endif #if MARS && 0 //It mangles correctly, but the ABI doesn't match, // leading to copious segfaults. At least with the // wrong mangling you get link errors. if (tyfunc(s->Stype->Tty) && s->Sfunc) { if (s->Sfunc->Fflags & Fctor) { cpp_zname(cpp_name_ct); return; } if (s->Sfunc->Fflags & Fdtor) { cpp_zname(cpp_name_dt); return; } } #endif cpp_zname(p); }
STATIC void cpp_symbol_name(symbol *s) { char *p; p = s->Sident; #if SCPP if (tyfunc(s->Stype->Tty) && s->Sfunc) { if (s->Sfunc->Fflags & Finstance) { Mangle save = mangle; char *q; int len; p = template_mangle(s, s->Sfunc->Fptal); len = strlen(p); q = (char *)alloca(len + 1); memcpy(q, p, len + 1); mangle = save; p = q; } else if (s->Sfunc->Fflags & Foperator) { // operator_name ::= '?' operator_code //CHAR('?'); // already there STR(p); return; } } #endif cpp_zname(p); }
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('@'); }
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_basic_data_type(type *t) { char c; int i; //printf("cpp_basic_data_type(t)\n"); //type_print(t); switch (tybasic(t->Tty)) { case TYschar: c = 'C'; goto dochar; case TYchar: c = 'D'; goto dochar; case TYuchar: c = 'E'; goto dochar; case TYshort: c = 'F'; goto dochar; case TYushort: c = 'G'; goto dochar; case TYint: c = 'H'; goto dochar; case TYuint: c = 'I'; goto dochar; case TYlong: c = 'J'; goto dochar; case TYulong: c = 'K'; goto dochar; case TYfloat: c = 'M'; goto dochar; case TYdouble: c = 'N'; goto dochar; case TYdouble_alias: if (intsize == 4) { c = 'O'; goto dochar; } c = 'Z'; goto dochar2; case TYldouble: if (intsize == 2) { c = 'O'; goto dochar; } c = 'Z'; goto dochar2; dochar: CHAR(c); break; case TYllong: c = 'J'; goto dochar2; case TYullong: c = 'K'; goto dochar2; case TYbool: c = 'N'; goto dochar2; // was 'X' prior to 8.1b8 case TYwchar_t: if (config.flags4 & CFG4nowchar_t) { c = 'G'; goto dochar; // same as TYushort } else { pstate.STflags |= PFLmfc; c = 'Y'; goto dochar2; } // Digital Mars extensions case TYifloat: c = 'R'; goto dochar2; case TYidouble: c = 'S'; goto dochar2; case TYildouble: c = 'T'; goto dochar2; case TYcfloat: c = 'U'; goto dochar2; case TYcdouble: c = 'V'; goto dochar2; case TYcldouble: c = 'W'; goto dochar2; case TYchar16: c = 'X'; goto dochar2; case TYdchar: c = 'Y'; goto dochar2; case TYnullptr: c = 'Z'; goto dochar2; dochar2: CHAR('_'); goto dochar; #if TARGET_SEGMENTED case TYsptr: case TYcptr: case TYf16ptr: case TYfptr: case TYhptr: case TYvptr: #endif #if !MARS case TYmemptr: #endif case TYnptr: c = 'P' + cpp_cvidx(t->Tty); CHAR(c); if(I64) CHAR('E'); // __ptr64 modifier cpp_pointer_type(t); break; case TYstruct: case TYenum: cpp_ecsu_data_type(t); break; case TYarray: i = cpp_cvidx(t->Tty); i |= 1; // always const CHAR('P' + i); cpp_pointer_type(t); break; case TYvoid: c = 'X'; goto dochar; #if !MARS case TYident: if (pstate.STintemplate) { CHAR('V'); // pretend to be a class name cpp_zname(t->Tident); } else { #if SCPP cpperr(EM_no_type,t->Tident); // no type for argument #endif c = 'X'; goto dochar; } break; case TYtemplate: if (pstate.STintemplate) { CHAR('V'); // pretend to be a class name cpp_zname(((typetemp_t *)t)->Tsym->Sident); } else goto Ldefault; break; #endif default: Ldefault: if (tyfunc(t->Tty)) cpp_function_type(t); else { #if SCPP #ifdef DEBUG if (!errcnt) type_print(t); #endif assert(errcnt); #endif } } }
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; }