Skip to content

Commit f5a7ceb

Browse files
plafosseclaude
andcommitted
GNU3 demangler: ABI tags, operator<=>, multi-digit T-params, cv cast fix
- ABI tags (B<source-name>): consolidate handling after switch in DemangleUnqualifiedName, covering source names and operator names (e.g. operator<=>[abi:ne180100]) - operator<=> (ss): add to GetOperator and DemangleUnqualifiedName - Template param indices: fix DemangleTemplateSubstitution to parse multi-digit decimal indices (T10_, T11_, ...) instead of only single-digit (fixes symbols with 10+ template parameters) - cv cast expression: consume '_' delimiter before calling DemangleExpressionList for the multi-arg form (cv <type> _ <expr>* E), fixing decltype(cm(..., (void)())) return types Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1bbc55d commit f5a7ceb

1 file changed

Lines changed: 22 additions & 2 deletions

File tree

demangler/gnu3/demangle_gnu3.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ static string GetOperator(char elm1, char elm2)
150150
case hash('a','N'): return "&="; // &=
151151
case hash('o','R'): return "|="; // |=
152152
case hash('e','O'): return "^="; // ^=
153+
case hash('s','s'): return "<=>"; // <=>
153154
case hash('d','l'): return "delete"; // delete
154155
case hash('d','a'): return "delete[]"; // delete[]
155156
case hash('n','w'): return "new"; // new
@@ -528,8 +529,10 @@ DemangledTypeNode DemangleGNU3::DemangleTemplateSubstitution()
528529
}
529530
else if (isdigit(elm))
530531
{
531-
m_reader.Consume();
532-
number = elm - '0' + 1;
532+
size_t n = 0;
533+
while (isdigit(m_reader.Peek()))
534+
n = n * 10 + (m_reader.Read() - '0');
535+
number = n + 1;
533536
}
534537
else if (isupper(elm))
535538
{
@@ -1244,6 +1247,7 @@ DemangledTypeNode DemangleGNU3::DemangleUnqualifiedName()
12441247
case hash('a','N'): // &=
12451248
case hash('o','R'): // |=
12461249
case hash('e','O'): // ^=
1250+
case hash('s','s'): // <=>
12471251
outType = CreateUnknownType("operator" + GetOperator(elm1, elm2));
12481252
outType.SetNameType(GetNameType(elm1, elm2));
12491253
break;
@@ -1395,13 +1399,26 @@ DemangledTypeNode DemangleGNU3::DemangleUnqualifiedName()
13951399
string name = DemangleSourceName();
13961400
if (name.size() > 11 && name.substr(0, 11) == "_GLOBAL__N_")
13971401
name = "(anonymous namespace)";
1402+
m_lastName = name;
13981403
outType = CreateUnknownType(name);
13991404
}
14001405
else
14011406
{
14021407
throw DemangleException();
14031408
}
14041409
}
1410+
// Consume ABI tags: B <source-name> => [abi:tagname]
1411+
// Applies to source names, operator names, and unnamed types.
1412+
while (m_reader.Peek() == 'B')
1413+
{
1414+
m_reader.Consume();
1415+
string tag = "[abi:" + DemangleSourceName() + "]";
1416+
auto qn = outType.GetTypeName();
1417+
if (!qn.empty())
1418+
qn.back() += tag;
1419+
outType.SetTypeName(std::move(qn));
1420+
m_lastName = qn.empty() ? tag : qn.back();
1421+
}
14051422
dedent();
14061423
return outType;
14071424
}
@@ -1706,7 +1723,10 @@ string DemangleGNU3::DemangleExpression()
17061723
DemangledTypeNode type = DemangleType();
17071724
out = type.GetString();
17081725
if (m_reader.Peek() == '_')
1726+
{
1727+
m_reader.Consume(); // consume '_' delimiter before expression list
17091728
out += " (" + DemangleExpressionList() + ")";
1729+
}
17101730
else
17111731
out += " (" + DemangleExpression() + ")";
17121732
return out;

0 commit comments

Comments
 (0)