[dmd-internals] Correction to name mangling doc

Walter Bright walter at digitalmars.com
Wed Sep 1 14:56:51 PDT 2010



Sean Kelly wrote:
> This one is really more of a programming question, but it's mangling related so I figured I'd ask here anyway.  The following function:
>
>     void someFunc(real x)() {}
>     someFunc!(1234.5678);
>
> is mangled as:
>
>     D8demangle34__T8someFuncVde9A522B6AE7D566CFP7Z8someFuncFZv
>
> std.demangle assumes that when it encounters an 'e' in a template parameter list, the next 20 bytes will be a hex representation of an 80 bit floating point value.  The ABI and current mangling behavior is to represent things a bit differently with a variable width hex mantissa and exponent value (HexDigits P Number).  So in this case I have 8 bytes of mantissa (9A 52 2B 6A E7 D5 66 CF) and 1 byte of exponent (7).  I'm having trouble relating the mangled value to 1234.5678 though.  Can someone explain what's going on here, and possibly suggest an appropriate means for converting the mangled value to a textual representation?
>   

The mangling is done with printf's %LA format. scanf should be able to 
reverse it.

void realToMangleBuffer(OutBuffer *buf, real_t value)
{
    /* Rely on %A to get portable mangling.
     * Must munge result to get only identifier characters
     *
     * Possible values from %A  => mangled result
     * NAN                      => NAN
     * -INF                     => NINF
     * INF                      => INF
     * -0X1.1BC18BA997B95P+79   => N11BC18BA997B95P79
     * 0X1.9P+2                 => 19P2
     */

#if 1
    if (Port::isNan(value))
#elif __APPLE__
    if (__inline_isnan(value))
#else
    if (isnan(value))
#endif
        buf->writestring("NAN");        // no -NAN bugs
    else
    {
        char buffer[32];
        int n = sprintf(buffer, "%LA", value);
        assert(n > 0 && n < sizeof(buffer));
        for (int i = 0; i < n; i++)
        {   char c = buffer[i];

            switch (c)
            {
                case '-':
                    buf->writeByte('N');
                    break;

                case '+':
                case 'X':
                case '.':
                    break;

                case '0':
                    if (i < 2)
                        break;          // skip leading 0X
                default:
                    buf->writeByte(c);
                    break;
            }
        }
    }
}



More information about the dmd-internals mailing list