Skip to content

Commit 598f116

Browse files
committed
Handle explicit GNU template parameter pack declarations
Parse Ty, Tn, Tt, and Tp declarations before their template argument, preserving the argument or pack's template substitution slot. Apply the existing nesting limit to recursive declarations and qualified arguments.
1 parent 08fc7a9 commit 598f116

2 files changed

Lines changed: 37 additions & 8 deletions

File tree

‎demangler/gnu3/demangle_gnu3.cpp‎

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,8 +2236,39 @@ bool DemangleGNU3::AppendTemplateParamPackExpansion(ParamList& params, NodeRef e
22362236
}
22372237

22382238

2239+
void DemangleGNU3::DemangleTemplateParamDecl()
2240+
{
2241+
NestingGuard nestingGuard(m_nestingDepth);
2242+
// <template-param-decl> ::= Ty # type parameter
2243+
// ::= Tn <type> # non-type parameter
2244+
// ::= Tt <template-param-decl>* E # template parameter
2245+
// ::= Tp <template-param-decl> # parameter pack
2246+
if (!m_reader.ConsumeIf('T'))
2247+
throw DemangleException();
2248+
2249+
switch (m_reader.Read())
2250+
{
2251+
case 'y':
2252+
return;
2253+
case 'n':
2254+
DemangleType();
2255+
return;
2256+
case 't':
2257+
while (!m_reader.ConsumeIf('E'))
2258+
DemangleTemplateParamDecl();
2259+
return;
2260+
case 'p':
2261+
DemangleTemplateParamDecl();
2262+
return;
2263+
default:
2264+
throw DemangleException();
2265+
}
2266+
}
2267+
2268+
22392269
bool DemangleGNU3::DemangleTemplateArg(ParamList& args, bool* hadNonTypeArg)
22402270
{
2271+
NestingGuard nestingGuard(m_nestingDepth);
22412272
DemangledTypeNode tmp;
22422273
NodeRef tmpRef;
22432274
bool tmpValid = false;
@@ -2294,18 +2325,15 @@ bool DemangleGNU3::DemangleTemplateArg(ParamList& args, bool* hadNonTypeArg)
22942325
break;
22952326
}
22962327
case 'T':
2297-
if (m_reader.ConsumeIf('n'))
2328+
if (const char kind = m_reader.PeekOr(); kind == 'y' || kind == 'n' || kind == 't' || kind == 'p')
22982329
{
22992330
// <template-arg> ::= <template-param-decl> <template-arg>
2300-
// <template-param-decl> ::= Tn <type> # non-type parameter
2301-
//
2302-
// The declaration names a synthetic non-type template parameter
2303-
// for the following argument. Binary Ninja does not print those
2304-
// synthetic parameter names, so consume the declaration type and
2305-
// keep only the actual following template argument.
2331+
// Only the following argument contributes to the printed name and
2332+
// template substitution table; the declaration describes its parameter.
2333+
m_reader.UnRead();
23062334
topLevel = m_topLevel;
23072335
m_topLevel = false;
2308-
DemangleType();
2336+
DemangleTemplateParamDecl();
23092337
m_topLevel = topLevel;
23102338
return DemangleTemplateArg(args, hadNonTypeArg);
23112339
}

‎demangler/gnu3/demangle_gnu3.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ class DemangleGNU3
146146
void DemangleCVQualifiers(bool& cnst, bool& vltl, bool& rstrct);
147147
DemangledTypeNode DemangleSubstitution(NodeRef* outTypeRef = nullptr);
148148
DemangledTypeNode DemangleTemplateSubstitution(NodeRef* outTypeRef = nullptr);
149+
void DemangleTemplateParamDecl();
149150
bool DemangleTemplateArg(ParamList& args, bool* hadNonTypeArg = nullptr);
150151
void DemangleTemplateArgs(ParamList& args, bool* hadNonTypeArg = nullptr);
151152
DemangledTypeNode DemangleFunction(bool cnst, bool vltl);

0 commit comments

Comments
 (0)