mirror of
https://github.com/dlang/phobos.git
synced 2025-04-30 07:00:37 +03:00
tabs
This commit is contained in:
parent
8e67f7a22f
commit
f5f14dd469
1 changed files with 364 additions and 364 deletions
728
std/demangle.d
728
std/demangle.d
|
@ -7,18 +7,18 @@
|
||||||
/****
|
/****
|
||||||
* Demangle D mangled names.
|
* Demangle D mangled names.
|
||||||
* Macros:
|
* Macros:
|
||||||
* WIKI = Phobos/StdDemangle
|
* WIKI = Phobos/StdDemangle
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Authors:
|
/* Authors:
|
||||||
* Walter Bright, Digital Mars, www.digitalmars.com
|
* Walter Bright, Digital Mars, www.digitalmars.com
|
||||||
* Thomas Kuehne
|
* Thomas Kuehne
|
||||||
* Frits van Bommel
|
* Frits van Bommel
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module std.demangle;
|
module std.demangle;
|
||||||
|
|
||||||
//debug=demangle; // uncomment to turn on debugging printf's
|
//debug=demangle; // uncomment to turn on debugging printf's
|
||||||
|
|
||||||
private import std.ctype;
|
private import std.ctype;
|
||||||
private import std.string;
|
private import std.string;
|
||||||
|
@ -32,7 +32,7 @@ private class MangleException : Exception
|
||||||
{
|
{
|
||||||
this()
|
this()
|
||||||
{
|
{
|
||||||
super("MangleException");
|
super("MangleException");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +41,8 @@ private class MangleException : Exception
|
||||||
*
|
*
|
||||||
* If it is not a D mangled name, it returns its argument name.
|
* If it is not a D mangled name, it returns its argument name.
|
||||||
* Example:
|
* Example:
|
||||||
* This program reads standard in and writes it to standard out,
|
* This program reads standard in and writes it to standard out,
|
||||||
* pretty-printing any found D mangled names.
|
* pretty-printing any found D mangled names.
|
||||||
-------------------
|
-------------------
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
import std.ctype;
|
import std.ctype;
|
||||||
|
@ -55,28 +55,28 @@ int main()
|
||||||
|
|
||||||
while ((c = fgetc(stdin)) != EOF)
|
while ((c = fgetc(stdin)) != EOF)
|
||||||
{
|
{
|
||||||
if (inword)
|
if (inword)
|
||||||
{
|
{
|
||||||
if (c == '_' || isalnum(c))
|
if (c == '_' || isalnum(c))
|
||||||
buffer ~= cast(char) c;
|
buffer ~= cast(char) c;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
inword = false;
|
inword = false;
|
||||||
writef(demangle(buffer), cast(char) c);
|
writef(demangle(buffer), cast(char) c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ if (c == '_' || isalpha(c))
|
{ if (c == '_' || isalpha(c))
|
||||||
{ inword = true;
|
{ inword = true;
|
||||||
buffer.length = 0;
|
buffer.length = 0;
|
||||||
buffer ~= cast(char) c;
|
buffer ~= cast(char) c;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
writef(cast(char) c);
|
writef(cast(char) c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (inword)
|
if (inword)
|
||||||
writef(demangle(buffer));
|
writef(demangle(buffer));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
-------------------
|
-------------------
|
||||||
|
@ -89,401 +89,401 @@ string demangle(string name)
|
||||||
|
|
||||||
static void error()
|
static void error()
|
||||||
{
|
{
|
||||||
//writefln("error()");
|
//writefln("error()");
|
||||||
throw new MangleException();
|
throw new MangleException();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ubyte ascii2hex(char c)
|
static ubyte ascii2hex(char c)
|
||||||
{
|
{
|
||||||
if (!isxdigit(c))
|
if (!isxdigit(c))
|
||||||
error();
|
error();
|
||||||
return cast(ubyte)
|
return cast(ubyte)
|
||||||
( (c >= 'a') ? c - 'a' + 10 :
|
( (c >= 'a') ? c - 'a' + 10 :
|
||||||
(c >= 'A') ? c - 'A' + 10 :
|
(c >= 'A') ? c - 'A' + 10 :
|
||||||
c - '0'
|
c - '0'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t parseNumber()
|
size_t parseNumber()
|
||||||
{
|
{
|
||||||
//writefln("parseNumber() %d", ni);
|
//writefln("parseNumber() %d", ni);
|
||||||
size_t result;
|
size_t result;
|
||||||
|
|
||||||
while (ni < name.length && isdigit(name[ni]))
|
while (ni < name.length && isdigit(name[ni]))
|
||||||
{ int i = name[ni] - '0';
|
{ int i = name[ni] - '0';
|
||||||
if (result > (size_t.max - i) / 10)
|
if (result > (size_t.max - i) / 10)
|
||||||
error();
|
error();
|
||||||
result = result * 10 + i;
|
result = result * 10 + i;
|
||||||
ni++;
|
ni++;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
string parseSymbolName()
|
string parseSymbolName()
|
||||||
{
|
{
|
||||||
//writefln("parseSymbolName() %d", ni);
|
//writefln("parseSymbolName() %d", ni);
|
||||||
size_t i = parseNumber();
|
size_t i = parseNumber();
|
||||||
if (ni + i > name.length)
|
if (ni + i > name.length)
|
||||||
error();
|
error();
|
||||||
string result;
|
string result;
|
||||||
if (i >= 5 &&
|
if (i >= 5 &&
|
||||||
name[ni] == '_' &&
|
name[ni] == '_' &&
|
||||||
name[ni + 1] == '_' &&
|
name[ni + 1] == '_' &&
|
||||||
name[ni + 2] == 'T')
|
name[ni + 2] == 'T')
|
||||||
{
|
{
|
||||||
size_t nisave = ni;
|
size_t nisave = ni;
|
||||||
bool err;
|
bool err;
|
||||||
ni += 3;
|
ni += 3;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = fparseTemplateInstanceName();
|
result = fparseTemplateInstanceName();
|
||||||
if (ni != nisave + i)
|
if (ni != nisave + i)
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
catch (MangleException me)
|
catch (MangleException me)
|
||||||
{
|
{
|
||||||
err = true;
|
err = true;
|
||||||
}
|
}
|
||||||
ni = nisave;
|
ni = nisave;
|
||||||
if (err)
|
if (err)
|
||||||
goto L1;
|
goto L1;
|
||||||
goto L2;
|
goto L2;
|
||||||
}
|
}
|
||||||
L1:
|
L1:
|
||||||
result = name[ni .. ni + i];
|
result = name[ni .. ni + i];
|
||||||
L2:
|
L2:
|
||||||
ni += i;
|
ni += i;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
string parseQualifiedName()
|
string parseQualifiedName()
|
||||||
{
|
{
|
||||||
//writefln("parseQualifiedName() %d", ni);
|
//writefln("parseQualifiedName() %d", ni);
|
||||||
string result;
|
string result;
|
||||||
|
|
||||||
while (ni < name.length && isdigit(name[ni]))
|
while (ni < name.length && isdigit(name[ni]))
|
||||||
{
|
{
|
||||||
if (result.length)
|
if (result.length)
|
||||||
result ~= ".";
|
result ~= ".";
|
||||||
result ~= parseSymbolName();
|
result ~= parseSymbolName();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
string parseType(string identifier = null)
|
string parseType(string identifier = null)
|
||||||
{
|
{
|
||||||
//writefln("parseType() %d", ni);
|
//writefln("parseType() %d", ni);
|
||||||
int isdelegate = 0;
|
int isdelegate = 0;
|
||||||
bool hasthisptr = false; /// For function/delegate types: expects a 'this' pointer as last argument
|
bool hasthisptr = false; /// For function/delegate types: expects a 'this' pointer as last argument
|
||||||
Lagain:
|
Lagain:
|
||||||
if (ni >= name.length)
|
if (ni >= name.length)
|
||||||
error();
|
error();
|
||||||
string p;
|
string p;
|
||||||
switch (name[ni++])
|
switch (name[ni++])
|
||||||
{
|
{
|
||||||
case 'v': p = "void"; goto L1;
|
case 'v': p = "void"; goto L1;
|
||||||
case 'b': p = "bool"; goto L1;
|
case 'b': p = "bool"; goto L1;
|
||||||
case 'g': p = "byte"; goto L1;
|
case 'g': p = "byte"; goto L1;
|
||||||
case 'h': p = "ubyte"; goto L1;
|
case 'h': p = "ubyte"; goto L1;
|
||||||
case 's': p = "short"; goto L1;
|
case 's': p = "short"; goto L1;
|
||||||
case 't': p = "ushort"; goto L1;
|
case 't': p = "ushort"; goto L1;
|
||||||
case 'i': p = "int"; goto L1;
|
case 'i': p = "int"; goto L1;
|
||||||
case 'k': p = "uint"; goto L1;
|
case 'k': p = "uint"; goto L1;
|
||||||
case 'l': p = "long"; goto L1;
|
case 'l': p = "long"; goto L1;
|
||||||
case 'm': p = "ulong"; goto L1;
|
case 'm': p = "ulong"; goto L1;
|
||||||
case 'f': p = "float"; goto L1;
|
case 'f': p = "float"; goto L1;
|
||||||
case 'd': p = "double"; goto L1;
|
case 'd': p = "double"; goto L1;
|
||||||
case 'e': p = "real"; goto L1;
|
case 'e': p = "real"; goto L1;
|
||||||
case 'o': p = "ifloat"; goto L1;
|
case 'o': p = "ifloat"; goto L1;
|
||||||
case 'p': p = "idouble"; goto L1;
|
case 'p': p = "idouble"; goto L1;
|
||||||
case 'j': p = "ireal"; goto L1;
|
case 'j': p = "ireal"; goto L1;
|
||||||
case 'q': p = "cfloat"; goto L1;
|
case 'q': p = "cfloat"; goto L1;
|
||||||
case 'r': p = "cdouble"; goto L1;
|
case 'r': p = "cdouble"; goto L1;
|
||||||
case 'c': p = "creal"; goto L1;
|
case 'c': p = "creal"; goto L1;
|
||||||
case 'a': p = "char"; goto L1;
|
case 'a': p = "char"; goto L1;
|
||||||
case 'u': p = "wchar"; goto L1;
|
case 'u': p = "wchar"; goto L1;
|
||||||
case 'w': p = "dchar"; goto L1;
|
case 'w': p = "dchar"; goto L1;
|
||||||
|
|
||||||
case 'A': // dynamic array
|
case 'A': // dynamic array
|
||||||
p = parseType() ~ "[]";
|
p = parseType() ~ "[]";
|
||||||
goto L1;
|
goto L1;
|
||||||
|
|
||||||
case 'P': // pointer
|
case 'P': // pointer
|
||||||
p = parseType() ~ "*";
|
p = parseType() ~ "*";
|
||||||
goto L1;
|
goto L1;
|
||||||
|
|
||||||
case 'G': // static array
|
case 'G': // static array
|
||||||
{ size_t ns = ni;
|
{ size_t ns = ni;
|
||||||
parseNumber();
|
parseNumber();
|
||||||
size_t ne = ni;
|
size_t ne = ni;
|
||||||
p = parseType() ~ "[" ~ name[ns .. ne] ~ "]";
|
p = parseType() ~ "[" ~ name[ns .. ne] ~ "]";
|
||||||
goto L1;
|
goto L1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'H': // associative array
|
case 'H': // associative array
|
||||||
p = parseType();
|
p = parseType();
|
||||||
p = parseType() ~ "[" ~ p ~ "]";
|
p = parseType() ~ "[" ~ p ~ "]";
|
||||||
goto L1;
|
goto L1;
|
||||||
|
|
||||||
case 'D': // delegate
|
case 'D': // delegate
|
||||||
isdelegate = 1;
|
isdelegate = 1;
|
||||||
goto Lagain;
|
goto Lagain;
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
hasthisptr = true;
|
hasthisptr = true;
|
||||||
goto Lagain;
|
goto Lagain;
|
||||||
|
|
||||||
case 'y':
|
case 'y':
|
||||||
p = "immutable(" ~ parseType() ~ ")";
|
p = "immutable(" ~ parseType() ~ ")";
|
||||||
goto L1;
|
goto L1;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
p = "const(" ~ parseType() ~ ")";
|
p = "const(" ~ parseType() ~ ")";
|
||||||
goto L1;
|
goto L1;
|
||||||
|
|
||||||
case 'O':
|
case 'O':
|
||||||
p = "shared(" ~ parseType() ~ ")";
|
p = "shared(" ~ parseType() ~ ")";
|
||||||
goto L1;
|
goto L1;
|
||||||
|
|
||||||
case 'F': // D function
|
case 'F': // D function
|
||||||
case 'U': // C function
|
case 'U': // C function
|
||||||
case 'W': // Windows function
|
case 'W': // Windows function
|
||||||
case 'V': // Pascal function
|
case 'V': // Pascal function
|
||||||
case 'R': // C++ function
|
case 'R': // C++ function
|
||||||
{ char mc = name[ni - 1];
|
{ char mc = name[ni - 1];
|
||||||
string args;
|
string args;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (ni >= name.length)
|
if (ni >= name.length)
|
||||||
error();
|
error();
|
||||||
char c = name[ni];
|
char c = name[ni];
|
||||||
if (c == 'Z')
|
if (c == 'Z')
|
||||||
break;
|
break;
|
||||||
if (c == 'X')
|
if (c == 'X')
|
||||||
{
|
{
|
||||||
if (!args.length) error();
|
if (!args.length) error();
|
||||||
args ~= " ...";
|
args ~= " ...";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (args.length)
|
if (args.length)
|
||||||
args ~= ", ";
|
args ~= ", ";
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'J':
|
case 'J':
|
||||||
args ~= "out ";
|
args ~= "out ";
|
||||||
ni++;
|
ni++;
|
||||||
goto default;
|
goto default;
|
||||||
|
|
||||||
case 'K':
|
case 'K':
|
||||||
args ~= "inout ";
|
args ~= "inout ";
|
||||||
ni++;
|
ni++;
|
||||||
goto default;
|
goto default;
|
||||||
|
|
||||||
case 'L':
|
case 'L':
|
||||||
args ~= "lazy ";
|
args ~= "lazy ";
|
||||||
ni++;
|
ni++;
|
||||||
goto default;
|
goto default;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
args ~= parseType();
|
args ~= parseType();
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'Y':
|
case 'Y':
|
||||||
args ~= "...";
|
args ~= "...";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ni++;
|
ni++;
|
||||||
if (!isdelegate && identifier.length)
|
if (!isdelegate && identifier.length)
|
||||||
{
|
{
|
||||||
switch (mc)
|
switch (mc)
|
||||||
{
|
{
|
||||||
case 'F': p = null; break; // D function
|
case 'F': p = null; break; // D function
|
||||||
case 'U': p = "extern (C) "; break; // C function
|
case 'U': p = "extern (C) "; break; // C function
|
||||||
case 'W': p = "extern (Windows) "; break; // Windows function
|
case 'W': p = "extern (Windows) "; break; // Windows function
|
||||||
case 'V': p = "extern (Pascal) "; break; // Pascal function
|
case 'V': p = "extern (Pascal) "; break; // Pascal function
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
}
|
}
|
||||||
p ~= parseType() ~ " " ~ identifier ~ "(" ~ args ~ ")";
|
p ~= parseType() ~ " " ~ identifier ~ "(" ~ args ~ ")";
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
p = parseType() ~
|
p = parseType() ~
|
||||||
(isdelegate ? " delegate(" : " function(") ~
|
(isdelegate ? " delegate(" : " function(") ~
|
||||||
args ~ ")";
|
args ~ ")";
|
||||||
isdelegate = 0;
|
isdelegate = 0;
|
||||||
goto L1;
|
goto L1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'C': p = "class "; goto L2;
|
case 'C': p = "class "; goto L2;
|
||||||
case 'S': p = "struct "; goto L2;
|
case 'S': p = "struct "; goto L2;
|
||||||
case 'E': p = "enum "; goto L2;
|
case 'E': p = "enum "; goto L2;
|
||||||
case 'T': p = "typedef "; goto L2;
|
case 'T': p = "typedef "; goto L2;
|
||||||
|
|
||||||
L2: p ~= parseQualifiedName();
|
L2: p ~= parseQualifiedName();
|
||||||
goto L1;
|
goto L1;
|
||||||
|
|
||||||
L1:
|
L1:
|
||||||
if (isdelegate)
|
if (isdelegate)
|
||||||
error(); // 'D' must be followed by function
|
error(); // 'D' must be followed by function
|
||||||
if (identifier.length)
|
if (identifier.length)
|
||||||
p ~= " " ~ identifier;
|
p ~= " " ~ identifier;
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
size_t i = ni - 1;
|
size_t i = ni - 1;
|
||||||
ni = name.length;
|
ni = name.length;
|
||||||
p = name[i .. length];
|
p = name[i .. length];
|
||||||
goto L1;
|
goto L1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string parseTemplateInstanceName()
|
string parseTemplateInstanceName()
|
||||||
{
|
{
|
||||||
auto result = parseSymbolName() ~ "!(";
|
auto result = parseSymbolName() ~ "!(";
|
||||||
int nargs;
|
int nargs;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{ size_t i;
|
{ size_t i;
|
||||||
|
|
||||||
if (ni >= name.length)
|
if (ni >= name.length)
|
||||||
error();
|
error();
|
||||||
if (nargs && name[ni] != 'Z')
|
if (nargs && name[ni] != 'Z')
|
||||||
result ~= ", ";
|
result ~= ", ";
|
||||||
nargs++;
|
nargs++;
|
||||||
switch (name[ni++])
|
switch (name[ni++])
|
||||||
{
|
{
|
||||||
case 'T':
|
case 'T':
|
||||||
result ~= parseType();
|
result ~= parseType();
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'V':
|
case 'V':
|
||||||
|
|
||||||
void getReal()
|
void getReal()
|
||||||
{ real r;
|
{ real r;
|
||||||
ubyte *p = cast(ubyte *)&r;
|
ubyte *p = cast(ubyte *)&r;
|
||||||
|
|
||||||
if (ni + 10 * 2 > name.length)
|
if (ni + 10 * 2 > name.length)
|
||||||
error();
|
error();
|
||||||
for (i = 0; i < 10; i++)
|
for (i = 0; i < 10; i++)
|
||||||
{ ubyte b;
|
{ ubyte b;
|
||||||
|
|
||||||
b = cast(ubyte)
|
b = cast(ubyte)
|
||||||
(
|
(
|
||||||
(ascii2hex(name[ni + i * 2]) << 4) +
|
(ascii2hex(name[ni + i * 2]) << 4) +
|
||||||
ascii2hex(name[ni + i * 2 + 1])
|
ascii2hex(name[ni + i * 2 + 1])
|
||||||
);
|
);
|
||||||
p[i] = b;
|
p[i] = b;
|
||||||
}
|
}
|
||||||
result ~= format(r);
|
result ~= format(r);
|
||||||
ni += 10 * 2;
|
ni += 10 * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
result ~= parseType() ~ " ";
|
result ~= parseType() ~ " ";
|
||||||
if (ni >= name.length)
|
if (ni >= name.length)
|
||||||
error();
|
error();
|
||||||
switch (name[ni++])
|
switch (name[ni++])
|
||||||
{
|
{
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
i = ni - 1;
|
i = ni - 1;
|
||||||
while (ni < name.length && isdigit(name[ni]))
|
while (ni < name.length && isdigit(name[ni]))
|
||||||
ni++;
|
ni++;
|
||||||
result ~= name[i .. ni];
|
result ~= name[i .. ni];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'N':
|
case 'N':
|
||||||
i = ni;
|
i = ni;
|
||||||
while (ni < name.length && isdigit(name[ni]))
|
while (ni < name.length && isdigit(name[ni]))
|
||||||
ni++;
|
ni++;
|
||||||
if (i == ni)
|
if (i == ni)
|
||||||
error();
|
error();
|
||||||
result ~= "-" ~ name[i .. ni];
|
result ~= "-" ~ name[i .. ni];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
result ~= "null";
|
result ~= "null";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
getReal();
|
getReal();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
getReal();
|
getReal();
|
||||||
result ~= '+';
|
result ~= '+';
|
||||||
getReal();
|
getReal();
|
||||||
result ~= 'i';
|
result ~= 'i';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'w':
|
case 'w':
|
||||||
case 'd':
|
case 'd':
|
||||||
{ char m = name[ni - 1];
|
{ char m = name[ni - 1];
|
||||||
if (m == 'a')
|
if (m == 'a')
|
||||||
m = 'c';
|
m = 'c';
|
||||||
size_t n = parseNumber();
|
size_t n = parseNumber();
|
||||||
if (ni >= name.length || name[ni++] != '_' ||
|
if (ni >= name.length || name[ni++] != '_' ||
|
||||||
ni + n * 2 > name.length)
|
ni + n * 2 > name.length)
|
||||||
error();
|
error();
|
||||||
result ~= '"';
|
result ~= '"';
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
{ char c;
|
{ char c;
|
||||||
|
|
||||||
c = (ascii2hex(name[ni + i * 2]) << 4) +
|
c = (ascii2hex(name[ni + i * 2]) << 4) +
|
||||||
ascii2hex(name[ni + i * 2 + 1]);
|
ascii2hex(name[ni + i * 2 + 1]);
|
||||||
result ~= c;
|
result ~= c;
|
||||||
}
|
}
|
||||||
ni += n * 2;
|
ni += n * 2;
|
||||||
result ~= '"';
|
result ~= '"';
|
||||||
result ~= m;
|
result ~= m;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error();
|
error();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
result ~= parseSymbolName();
|
result ~= parseSymbolName();
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'Z':
|
case 'Z':
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error();
|
error();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result ~= ")";
|
result ~= ")";
|
||||||
return assumeUnique(result);
|
return assumeUnique(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name.length < 3 ||
|
if (name.length < 3 ||
|
||||||
name[0] != '_' ||
|
name[0] != '_' ||
|
||||||
name[1] != 'D' ||
|
name[1] != 'D' ||
|
||||||
!isdigit(name[2]))
|
!isdigit(name[2]))
|
||||||
{
|
{
|
||||||
goto Lnot;
|
goto Lnot;
|
||||||
}
|
}
|
||||||
|
|
||||||
fparseTemplateInstanceName = &parseTemplateInstanceName;
|
fparseTemplateInstanceName = &parseTemplateInstanceName;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto result = parseQualifiedName();
|
auto result = parseQualifiedName();
|
||||||
result = parseType(result);
|
result = parseType(result);
|
||||||
while(ni < name.length){
|
while(ni < name.length){
|
||||||
result ~= " . " ~ parseType(parseQualifiedName());
|
result ~= " . " ~ parseType(parseQualifiedName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ni != name.length)
|
if (ni != name.length)
|
||||||
goto Lnot;
|
goto Lnot;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch (MangleException e)
|
catch (MangleException e)
|
||||||
{
|
{
|
||||||
|
@ -501,27 +501,27 @@ unittest
|
||||||
|
|
||||||
static string[2][] table =
|
static string[2][] table =
|
||||||
[
|
[
|
||||||
[ "printf", "printf" ],
|
[ "printf", "printf" ],
|
||||||
[ "_foo", "_foo" ],
|
[ "_foo", "_foo" ],
|
||||||
[ "_D88", "_D88" ],
|
[ "_D88", "_D88" ],
|
||||||
[ "_D4test3fooAa", "char[] test.foo"],
|
[ "_D4test3fooAa", "char[] test.foo"],
|
||||||
[ "_D8demangle8demangleFAaZAa", "char[] demangle.demangle(char[])" ],
|
[ "_D8demangle8demangleFAaZAa", "char[] demangle.demangle(char[])" ],
|
||||||
[ "_D6object6Object8opEqualsFC6ObjectZi", "int object.Object.opEquals(class Object)" ],
|
[ "_D6object6Object8opEqualsFC6ObjectZi", "int object.Object.opEquals(class Object)" ],
|
||||||
[ "_D4test2dgDFiYd", "double delegate(int, ...) test.dg" ],
|
[ "_D4test2dgDFiYd", "double delegate(int, ...) test.dg" ],
|
||||||
[ "_D4test58__T9factorialVde67666666666666860140VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, char[5] \"hello\"c, void* null).factorial" ],
|
[ "_D4test58__T9factorialVde67666666666666860140VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, char[5] \"hello\"c, void* null).factorial" ],
|
||||||
[ "_D4test101__T9factorialVde67666666666666860140Vrc9a999999999999d9014000000000000000c00040VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, cdouble 6.8+3i, char[5] \"hello\"c, void* null).factorial" ],
|
[ "_D4test101__T9factorialVde67666666666666860140Vrc9a999999999999d9014000000000000000c00040VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, cdouble 6.8+3i, char[5] \"hello\"c, void* null).factorial" ],
|
||||||
[ "_D4test34__T3barVG3uw3_616263VG3wd3_646566Z1xi", "int test.bar!(wchar[3] \"abc\"w, dchar[3] \"def\"d).x" ],
|
[ "_D4test34__T3barVG3uw3_616263VG3wd3_646566Z1xi", "int test.bar!(wchar[3] \"abc\"w, dchar[3] \"def\"d).x" ],
|
||||||
[ "_D8demangle4testFLC6ObjectLDFLiZiZi", "int demangle.test(lazy class Object, lazy int delegate(lazy int))"],
|
[ "_D8demangle4testFLC6ObjectLDFLiZiZi", "int demangle.test(lazy class Object, lazy int delegate(lazy int))"],
|
||||||
[ "_D8demangle4testFAiXi", "int demangle.test(int[] ...)"],
|
[ "_D8demangle4testFAiXi", "int demangle.test(int[] ...)"],
|
||||||
[ "_D8demangle4testFLAiXi", "int demangle.test(lazy int[] ...)"],
|
[ "_D8demangle4testFLAiXi", "int demangle.test(lazy int[] ...)"],
|
||||||
[ "_D6plugin8generateFiiZAya", "immutable(char)[] plugin.generate(int, int)"],
|
[ "_D6plugin8generateFiiZAya", "immutable(char)[] plugin.generate(int, int)"],
|
||||||
[ "_D6plugin8generateFiiZAxa", "const(char)[] plugin.generate(int, int)"],
|
[ "_D6plugin8generateFiiZAxa", "const(char)[] plugin.generate(int, int)"],
|
||||||
[ "_D6plugin8generateFiiZAOa", "shared(char)[] plugin.generate(int, int)"]
|
[ "_D6plugin8generateFiiZAOa", "shared(char)[] plugin.generate(int, int)"]
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach (i, name; table)
|
foreach (i, name; table)
|
||||||
{
|
{
|
||||||
string r = demangle(name[0]);
|
string r = demangle(name[0]);
|
||||||
assert(r == name[1],
|
assert(r == name[1],
|
||||||
"table entry #" ~ to!string(i) ~ ": '" ~ name[0]
|
"table entry #" ~ to!string(i) ~ ": '" ~ name[0]
|
||||||
~ "' demangles as '" ~ r ~ "' but is expected to be '"
|
~ "' demangles as '" ~ r ~ "' but is expected to be '"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue