Beispiel #1
0
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
    }
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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('@');
}
Beispiel #5
0
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;
}
Beispiel #6
0
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
            }
    }
}
Beispiel #7
0
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;
}