Merge remote-tracking branch 'origin/GP-6394-dragonmacher-gnu-demangler-function-qualifiers'

This commit is contained in:
Ryan Kurtz
2026-02-04 11:46:38 -05:00
3 changed files with 75 additions and 17 deletions
@@ -41,7 +41,9 @@ Update January 2026
Fixed a bug seen in older mangled symbols that use an 'F' character for functions. We added a
function to handle this case, isQualifiersAndFunc(). This function called from inside the
demangle_signature() function.
demangle_signature() function. The output also makes use of the added TYPE_QUAL_STATIC define.
cp-demangle.c *
@@ -463,6 +463,7 @@ static int snarf_numeric_literal (const char **, string *);
#define TYPE_QUAL_CONST 0x1
#define TYPE_QUAL_VOLATILE 0x2
#define TYPE_QUAL_RESTRICT 0x4
#define TYPE_QUAL_STATIC 0x8
static int code_for_qualifier (int);
@@ -573,6 +574,9 @@ code_for_qualifier (int c)
case 'C':
return TYPE_QUAL_CONST;
case 'S':
return TYPE_QUAL_STATIC;
case 'V':
return TYPE_QUAL_VOLATILE;
@@ -601,22 +605,34 @@ qualifier_string (int type_quals)
case TYPE_QUAL_CONST:
return "const";
case TYPE_QUAL_STATIC:
return "static";
case TYPE_QUAL_VOLATILE:
return "volatile";
case TYPE_QUAL_RESTRICT:
return "__restrict";
case TYPE_QUAL_CONST | TYPE_QUAL_STATIC:
return "const static";
case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
return "const volatile";
case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
return "const __restrict";
case TYPE_QUAL_STATIC | TYPE_QUAL_VOLATILE:
return "static volatile";
case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
return "volatile __restrict";
case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
case TYPE_QUAL_CONST | TYPE_QUAL_STATIC | TYPE_QUAL_VOLATILE:
return "static const volatile";
case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
return "const volatile __restrict";
default:
@@ -819,33 +835,33 @@ cplus_demangle_name_to_style (const char *name)
return unknown_demangling;
}
/* Scans to see if mangled is a set of optional qualifiers and a function. */
static int /* bool */
isQualifiersAndFunc(const char *mangled)
{
int i = 0;
while (1)
{
switch (mangled[i++])
{
case 'C':
case 'V':
case 'u':
/*qualifier*/
break;
case 'F':
/* function */
return 1;
default:
/* anything else is not a qualifier or function */
return 0;
case 'C':
case 'S':
case 'V':
case 'u':
/* qualifier */
break;
case 'F':
/* function */
return 1;
default:
/* anything else is not a qualifier or function */
return 0;
}
}
}
}
/* char *cplus_demangle (const char *mangled, int options)
If MANGLED is a mangled function name produced by GNU C++, then
@@ -198,6 +198,46 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
assertEquals("undefined Foo::foo(unsigned char,unsigned char)", object.getSignature());
}
@Test
public void testLegacy_DemangedFunctionCharacter_Qualifiers() throws Exception {
// This is only supported in the older v24 demangler. The 'F' character was not being
// correctly demangled along with some qualifier characters. The native demangler was
// updated to fix this.
process = GnuDemanglerNativeProcess
.getDemanglerNativeProcess(GnuDemanglerOptions.GNU_DEMANGLER_V2_24);
//@formatter:off
assertLegacyDemangled("foo__03FooCF",
"Foo::foo(void) const",
"undefined Foo::foo(void)");
assertLegacyDemangled("foo__03FooSF",
"Foo::foo(void) static",
"undefined Foo::foo(void)");
assertLegacyDemangled("foo__03FooSFUcT1",
"Foo::foo(unsigned char, unsigned char) static",
"undefined Foo::foo(unsigned char,unsigned char)");
assertLegacyDemangled("foo__03FooSCFUcT1",
"Foo::foo(unsigned char, unsigned char) static const",
"undefined Foo::foo(unsigned char,unsigned char)");
//@formatter:on
}
private void assertLegacyDemangled(String mangled, String demangledExpected,
String signatureExpected) throws Exception {
String demangledActual = process.demangle(mangled);
assertEquals(demangledExpected, demangledActual);
DemangledObject object = parser.parse(mangled, demangledExpected);
assertType(object, DemangledFunction.class);
assertEquals(signatureExpected, object.getSignature());
}
@Test
public void testTemplates_TemplatedType() throws Exception {
String mangled =