Commit fa66ced4 by Iain Buclaw Committed by Iain Buclaw

d-demangle.c (dlang_type_modifiers): New function.

libiberty/ChangeLog:

2015-05-16  Iain Buclaw  <ibuclaw@gdcproject.org>

	* d-demangle.c (dlang_type_modifiers): New function.
	(dlang_type_modifier_p): New function.
	(dlang_call_convention_p): Ignore any kind of type modifier.
	(dlang_type): Handle and emit the type modifier after delegate types.
	(dlang_parse_symbol): Handle and emit the type modifier after the symbol.
	* testsuite/d-demangle-expected: Add coverage tests for all valid
	usages of function symbols with type modifiers.

From-SVN: r223242
parent 76b41cad
2015-05-16 Iain Buclaw <ibuclaw@gdcproject.org>
* d-demangle.c (dlang_type_modifiers): New function.
(dlang_type_modifier_p): New function.
(dlang_call_convention_p): Ignore any kind of type modifier.
(dlang_type): Handle and emit the type modifier after delegate types.
(dlang_parse_symbol): Handle and emit the type modifier after the symbol.
* testsuite/d-demangle-expected: Add coverage tests for all valid
usages of function symbols with type modifiers.
2015-05-16 Iain Buclaw <ibuclaw@gdcproject.org>
* d-demangle.c (dlang_call_convention): Return NULL if have reached the
end of the symbol, but expected something to read.
(dlang_attributes): Likewise.
......
......@@ -215,6 +215,44 @@ dlang_call_convention (string *decl, const char *mangled)
return mangled;
}
/* Extract the type modifiers from MANGLED and append them to DECL.
Returns the remaining signature on success or NULL on failure. */
static const char *
dlang_type_modifiers (string *decl, const char *mangled)
{
if (mangled == NULL || *mangled == '\0')
return NULL;
switch (*mangled)
{
case 'x': /* const */
mangled++;
string_append (decl, " const");
return mangled;
case 'y': /* immutable */
mangled++;
string_append (decl, " immutable");
return mangled;
case 'O': /* shared */
mangled++;
string_append (decl, " shared");
return dlang_type_modifiers (decl, mangled);
case 'N':
mangled++;
if (*mangled == 'g') /* wild */
{
mangled++;
string_append (decl, " inout");
return dlang_type_modifiers (decl, mangled);
}
else
return NULL;
default:
return mangled;
}
}
/* Demangle the D function attributes from MANGLED and append it to DECL.
Return the remaining string on success or NULL on failure. */
static const char *
......@@ -476,10 +514,22 @@ dlang_type (string *decl, const char *mangled)
mangled++;
return dlang_parse_symbol (decl, mangled);
case 'D': /* delegate T */
{
string mods;
size_t szmods;
mangled++;
string_init (&mods);
mangled = dlang_type_modifiers (&mods, mangled);
szmods = string_length (&mods);
mangled = dlang_function_type (decl, mangled);
string_append (decl, "delegate");
string_appendn (decl, mods.b, szmods);
string_delete (&mods);
return mangled;
}
case 'B': /* tuple T */
mangled++;
return dlang_parse_tuple (decl, mangled);
......@@ -1135,28 +1185,54 @@ dlang_value (string *decl, const char *mangled, const char *name, char type)
return mangled;
}
/* Extract the type modifiers from MANGLED and return the string
length that it consumes in MANGLED on success or 0 on failure. */
static int
dlang_call_convention_p (const char *mangled)
dlang_type_modifier_p (const char *mangled)
{
size_t i;
int i;
switch (*mangled)
{
case 'F': case 'U': case 'V':
case 'W': case 'R':
case 'x': case 'y':
return 1;
case 'M': /* Prefix for functions needing 'this' */
i = 1;
if (mangled[i] == 'x')
i++;
case 'O':
mangled++;
i = dlang_type_modifier_p (mangled);
return i + 1;
switch (mangled[i])
case 'N':
mangled++;
if (*mangled == 'g')
{
case 'F': case 'U': case 'V':
case 'W': case 'R':
return 1;
mangled++;
i = dlang_type_modifier_p (mangled);
return i + 2;
}
}
return 0;
}
/* Extract the function calling convention from MANGLED and
return 1 on success or 0 on failure. */
static int
dlang_call_convention_p (const char *mangled)
{
/* Prefix for functions needing 'this' */
if (*mangled == 'M')
{
mangled++;
/* Also skip over any type modifiers. */
mangled += dlang_type_modifier_p (mangled);
}
switch (*mangled)
{
case 'F': case 'U': case 'V':
case 'W': case 'R':
return 1;
default:
return 0;
......@@ -1178,11 +1254,16 @@ dlang_parse_symbol (string *decl, const char *mangled)
if (mangled && dlang_call_convention_p (mangled))
{
string mods;
int saved;
/* Skip over 'this' parameter. */
if (*mangled == 'M')
mangled += (mangled[1] == 'x') ? 2 : 1;
mangled++;
/* Save the type modifiers for appending at the end. */
string_init (&mods);
mangled = dlang_type_modifiers (&mods, mangled);
/* Skip over calling convention and attributes in qualified name. */
saved = string_length (decl);
......@@ -1201,6 +1282,10 @@ dlang_parse_symbol (string *decl, const char *mangled)
mangled = dlang_type (decl, mangled);
string_setlength (decl, saved);
}
/* Add any const/immutable/shared modifier. */
string_appendn (decl, mods.b, string_length (&mods));
string_delete (&mods);
}
}
while (mangled && ISDIGIT (*mangled));
......
......@@ -753,6 +753,70 @@ demangle.test!(demangle.S(1, 2))
_D8demangle35__T4testVS8demangle1SS2i1a3_616263Zv
demangle.test!(demangle.S(1, "abc"))
#
--format=dlang
_D8demangle4testMxFZv
demangle.test() const
#
--format=dlang
_D8demangle4testMyFZv
demangle.test() immutable
#
--format=dlang
_D8demangle4testMNgFZv
demangle.test() inout
#
--format=dlang
_D8demangle4testMNgxFZv
demangle.test() inout const
#
--format=dlang
_D8demangle4testMOFZv
demangle.test() shared
#
--format=dlang
_D8demangle4testMOxFZv
demangle.test() shared const
#
--format=dlang
_D8demangle4testMONgFZv
demangle.test() shared inout
#
--format=dlang
_D8demangle4testMONgxFZv
demangle.test() shared inout const
#
--format=dlang
_D8demangle4testFDxFZaZv
demangle.test(char() delegate const)
#
--format=dlang
_D8demangle4testFDyFZaZv
demangle.test(char() delegate immutable)
#
--format=dlang
_D8demangle4testFDNgFZaZv
demangle.test(char() delegate inout)
#
--format=dlang
_D8demangle4testFDNgxFZaZv
demangle.test(char() delegate inout const)
#
--format=dlang
_D8demangle4testFDOFZaZv
demangle.test(char() delegate shared)
#
--format=dlang
_D8demangle4testFDOxFZaZv
demangle.test(char() delegate shared const)
#
--format=dlang
_D8demangle4testFDONgFZaZv
demangle.test(char() delegate shared inout)
#
--format=dlang
_D8demangle4testFDONgxFZaZv
demangle.test(char() delegate shared inout const)
#
# Unittests
#
--format=dlang
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment