Showing with 65 additions and 4 deletions.
  1. +65 −4 src/core/demangle.d
69 changes: 65 additions & 4 deletions src/core/demangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -357,11 +357,30 @@ private struct Demangle
size_t tlen = 0;
real val = void;

if( 'I' == tok() )
{
match( "INF" );
put( "real.infinity" );
return;
}
if( 'N' == tok() )
{
tbuf[tlen++] = '-';
next();
if( 'I' == tok() )
{
match( "INF" );
put( "-real.infinity" );
return;
}
if( 'A' == tok() )
{
match( "AN" );
put( "real.nan" );
return;
}
tbuf[tlen++] = '-';
}

tbuf[tlen++] = '0';
tbuf[tlen++] = 'X';
if( !isHexDigit( tok() ) )
Expand Down Expand Up @@ -708,6 +727,7 @@ private struct Demangle
}

// FuncAttrs
breakFuncAttrs:
while( 'N' == tok() )
{
next();
Expand Down Expand Up @@ -737,6 +757,13 @@ private struct Demangle
next();
put( "@safe " );
continue;
case 'g':
// NOTE: The inout parameter type is represented as "Ng",
// which makes it look like a FuncAttr. So if we
// see an "Ng" FuncAttr we know we're really in
// the parameter list. Rewind and break.
pos--;
break breakFuncAttrs;
default:
error();
}
Expand Down Expand Up @@ -849,7 +876,9 @@ private struct Demangle
case 'g': // Wild (Ng Type)
next();
// TODO: Anything needed here?
put( "inout(" );
parseType();
put( ")" );
return dst[beg .. len];
case 'e': // TypeNewArray (Ne Type)
next();
Expand Down Expand Up @@ -1062,7 +1091,7 @@ private struct Demangle
E
F
*/
void parseValue( char[] name = null )
void parseValue( char[] name = null, char type = '\0' )
{
debug(trace) printf( "parseValue+\n" );
debug(trace) scope(success) printf( "parseValue-\n" );
Expand Down Expand Up @@ -1115,6 +1144,15 @@ private struct Demangle
put( (cast(char*) &t)[0 .. 1] );
return;
case 'A':
// NOTE: This is kind of a hack. An associative array literal
// [1:2, 3:4] is represented as HiiA2i1i2i3i4, so the type
// is "Hii" and the value is "A2i1i2i3i4". Thus the only
// way to determine that this is an AA value rather than an
// array value is for the caller to supply the type char.
// Hopefully, this will change so that the value is
// "H2i1i2i3i4", rendering this unnecesary.
if( 'H' == type )
goto LassocArray;
// A Number Value...
// An array literal. Value is repeated Number times.
next();
Expand All @@ -1128,6 +1166,23 @@ private struct Demangle
}
put( "]" );
return;
case 'H':
LassocArray:
// H Number Value...
// An associative array literal. Value is repeated 2*Number times.
next();
put( "[" );
auto n = decodeNumber();
foreach( i; 0 .. n )
{
if( i != 0 )
put( ", " );
parseValue();
put(":");
parseValue();
}
put( "]" );
return;
case 'S':
// S Number Value...
// A struct literal. Value is repeated Number times.
Expand Down Expand Up @@ -1181,8 +1236,9 @@ private struct Demangle
// desired in the output it should precede the value
// generated by parseValue, so it is safe to simply
// decrement len and let put/append do its thing.
char t = tok(); // peek at type for parseValue
char[] name; silent( name = parseType() );
parseValue( name );
parseValue( name, t );
continue;
case 'S':
next();
Expand Down Expand Up @@ -1407,7 +1463,12 @@ unittest
["_D8demangle4mainFZv1S3fnDMFZv", "void demangle.main().void S.fnD()"],
["_D8demangle20__T2fnVAiA4i1i2i3i4Z2fnFZv", "void demangle.fn!([1, 2, 3, 4]).fn()"],
["_D8demangle10__T2fnVi1Z2fnFZv", "void demangle.fn!(1).fn()"],
["_D8demangle26__T2fnVS8demangle1SS2i1i2Z2fnFZv", "void demangle.fn!(demangle.S(1, 2)).fn()"]
["_D8demangle26__T2fnVS8demangle1SS2i1i2Z2fnFZv", "void demangle.fn!(demangle.S(1, 2)).fn()"],
["_D8demangle13__T2fnVeeNANZ2fnFZv", "void demangle.fn!(real.nan).fn()"],
["_D8demangle14__T2fnVeeNINFZ2fnFZv", "void demangle.fn!(-real.infinity).fn()"],
["_D8demangle13__T2fnVeeINFZ2fnFZv", "void demangle.fn!(real.infinity).fn()"],
["_D8demangle21__T2fnVHiiA2i1i2i3i4Z2fnFZv", "void demangle.fn!([1:2, 3:4]).fn()"],
["_D8demangle2fnFNgiZNgi", "inout(int) demangle.fn(inout(int))"]
];

foreach( i, name; table )
Expand Down