From 7502203f597bd81366d036188c6bb0cb4872feea Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Sat, 23 Jul 2016 21:06:02 +0200 Subject: [PATCH] implement demangler for back references --- src/core/demangle.d | 54 +++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/src/core/demangle.d b/src/core/demangle.d index 56b2fe3db79..510e7e306f4 100644 --- a/src/core/demangle.d +++ b/src/core/demangle.d @@ -470,7 +470,7 @@ private struct Demangle /* LName: Number Name - + Number % Name: Namestart Namestart Namechars @@ -493,19 +493,37 @@ private struct Demangle debug(trace) scope(success) printf( "parseLName-\n" ); auto n = decodeNumber(); - - if( !n || n > buf.length || n > buf.length - pos ) - error( "LName must be at least 1 character" ); - if( '_' != front && !isAlpha( front ) ) - error( "Invalid character in LName" ); - foreach(char e; buf[pos + 1 .. pos + n] ) - { - if( '_' != e && !isAlpha( e ) && !isDigit( e ) ) - error( "Invalid character in LName" ); - } - - put( buf[pos .. pos + n] ); - pos += n; + if( pos < buf.length && buf[pos] == '%' ) + { + // back reference to LName + if( n >= pos ) + error( "invalid LName back reference" ); + size_t p = n; + n = 0; + while( isDigit( buf[p] ) ) + { + n = n * 10 + buf[p] - '0'; + p++; + } + if( n > pos - p ) + error( "invalid LName length" ); + put( buf[p .. p + n] ); + pos++; + } + else + { + if( !n || n > buf.length || n > buf.length - pos ) + error( "LName must be at least 1 character" ); + if( '_' != front && !isAlpha( front ) ) + error( "Invalid character in LName" ); + foreach(char e; buf[pos + 1 .. pos + n] ) + { + if( '_' != e && !isAlpha( e ) && !isDigit( e ) ) + error( "Invalid character in LName" ); + } + put( buf[pos .. pos + n] ); + pos += n; + } } @@ -715,6 +733,14 @@ private struct Demangle switch( t ) { + case '$': + popFront(); + auto n = decodeNumber(); + auto savePos = pos; + pos = n; + auto ret = parseType(); + pos = savePos; + return ret; case 'O': // Shared (O Type) popFront(); put( "shared(" );