Skip to content

Commit b381baf

Browse files
plafosseclaude
andcommitted
GNU3 demangler: fix multi-level sr scope resolution without N prefix
GCC emits "sr St 6__and_I<T>E 5value" for std::__and_<T>::value in enable_if expressions. The previous sr/else handler assumed exactly one qualifier after the unresolved type, leaving trailing source-name components unread and causing DemangleException in subsequent parsing. Fix: loop over digit-started source names after the initial unresolved type, treating each as an intermediate qualifier when it has template args AND another source name follows, or as the final name otherwise. Operator-name ("on") and destructor-name ("dn") final components fall through to the existing DemangleBaseUnresolvedName() call. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 56e1ae6 commit b381baf

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

demangler/gnu3/demangle_gnu3.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,39 @@ string DemangleGNU3::DemangleExpression()
18431843
else
18441844
{
18451845
out += DemangleUnresolvedType().GetString() + "::";
1846+
// GCC may encode multi-level scoped names without the 'N' qualifier
1847+
// prefix, e.g. "sr St 6__and_I<T>E 5value" for std::__and_<T>::value.
1848+
// Process any digit-started names: if a name has template args AND
1849+
// another source name follows, it is an intermediate qualifier level;
1850+
// otherwise it is the final base-unresolved-name.
1851+
while (isdigit(m_reader.Peek()))
1852+
{
1853+
const string segName = DemangleSourceName();
1854+
if (m_reader.Peek() == 'I')
1855+
{
1856+
vector<string> args;
1857+
m_reader.Consume();
1858+
DemangleTemplateArgs(args);
1859+
if (isdigit(m_reader.Peek()))
1860+
{
1861+
// Another source name follows — intermediate qualifier.
1862+
out += segName + GetTemplateString(args) + "::";
1863+
}
1864+
else
1865+
{
1866+
// No more source names — this template-id is the final name.
1867+
out += segName + GetTemplateString(args);
1868+
return out;
1869+
}
1870+
}
1871+
else
1872+
{
1873+
// Plain source name with no template args — final base name.
1874+
out += segName;
1875+
return out;
1876+
}
1877+
}
1878+
// peek is not a digit: fall back for operator-names ("on") / destructor-names ("dn").
18461879
out += DemangleBaseUnresolvedName().GetString();
18471880
}
18481881
return out;

0 commit comments

Comments
 (0)