Skip to content

Commit ba3ab19

Browse files
committed
Use structured MSVC template backrefs
1 parent 8db9dfb commit ba3ab19

4 files changed

Lines changed: 371 additions & 110 deletions

File tree

demangler/gnu3/demangled_type_node.cpp

Lines changed: 209 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,24 @@ namespace
6363
return out;
6464
}
6565

66+
static void AppendTemplateArgumentList(string& out, const vector<DemangledTypeNode::Param>& args)
67+
{
68+
if (args.empty())
69+
return;
70+
71+
out += '<';
72+
for (size_t i = 0; i < args.size(); i++)
73+
{
74+
if (i > 0)
75+
out += ',';
76+
if (args[i].type)
77+
args[i].type->AppendString(out);
78+
}
79+
if (out.back() == '>')
80+
out += ' ';
81+
out += '>';
82+
}
83+
6684
static size_t ResolveAddressWidth(Architecture* arch, Platform* platform)
6785
{
6886
if (arch)
@@ -256,6 +274,12 @@ DemangledTypeNode DemangledTypeNode::ValueType(const string& value)
256274
}
257275

258276

277+
DemangledTypeNode DemangledTypeNode::NameSegment(const string& name)
278+
{
279+
return ValueType(name);
280+
}
281+
282+
259283
DemangledTypeNode DemangledTypeNode::VarArgsType()
260284
{
261285
DemangledTypeNode n;
@@ -292,6 +316,15 @@ DemangledTypeNode DemangledTypeNode::MemberPointerType(DemangledTypeNode child,
292316
}
293317

294318

319+
DemangledTypeNode DemangledTypeNode::MemberPointerType(
320+
DemangledTypeNode child, vector<DemangledTypeNode> ownerName, bool cnst, bool vltl)
321+
{
322+
DemangledTypeNode n = MemberPointerType(std::move(child), StringList(), cnst, vltl);
323+
n.m_memberPointerOwnerNameNodes = std::move(ownerName);
324+
return n;
325+
}
326+
327+
295328
DemangledTypeNode DemangledTypeNode::ArrayType(DemangledTypeNode child, uint64_t count)
296329
{
297330
DemangledTypeNode n;
@@ -331,6 +364,18 @@ DemangledTypeNode DemangledTypeNode::NamedType(BNNamedTypeReferenceClass cls,
331364
return n;
332365
}
333366

367+
DemangledTypeNode DemangledTypeNode::NamedType(BNNamedTypeReferenceClass cls,
368+
vector<DemangledTypeNode> nameSegments, size_t width, bool isSigned)
369+
{
370+
DemangledTypeNode n;
371+
n.m_typeClass = NamedTypeReferenceClass;
372+
n.m_ntrClass = cls;
373+
n.m_nameSegmentNodes = std::move(nameSegments);
374+
n.m_width = width;
375+
n.m_signed = isSigned;
376+
return n;
377+
}
378+
334379
DemangledTypeNode DemangledTypeNode::NamedTypeWithDefaultIntegerWidth(BNNamedTypeReferenceClass cls,
335380
StringList nameSegments, bool isSigned)
336381
{
@@ -339,6 +384,14 @@ DemangledTypeNode DemangledTypeNode::NamedTypeWithDefaultIntegerWidth(BNNamedTyp
339384
return n;
340385
}
341386

387+
DemangledTypeNode DemangledTypeNode::NamedTypeWithDefaultIntegerWidth(BNNamedTypeReferenceClass cls,
388+
vector<DemangledTypeNode> nameSegments, bool isSigned)
389+
{
390+
DemangledTypeNode n = NamedType(cls, std::move(nameSegments), 0, isSigned);
391+
n.m_widthKind = DefaultIntegerWidth;
392+
return n;
393+
}
394+
342395
uint8_t DemangledTypeNode::PointerSuffixBit(BNPointerSuffix ps)
343396
{
344397
switch (ps)
@@ -374,6 +427,71 @@ size_t DemangledTypeNode::ResolveWidth(Architecture* arch, Platform* platform) c
374427
}
375428

376429

430+
bool DemangledTypeNode::HasTemplateArguments() const
431+
{
432+
if (m_hasTemplateArgs || !m_templateArgs.empty())
433+
return true;
434+
for (const auto& segment: m_nameSegmentNodes)
435+
if (segment.HasTemplateArguments())
436+
return true;
437+
return false;
438+
}
439+
440+
441+
void DemangledTypeNode::SetTemplateArguments(vector<Param> args)
442+
{
443+
m_templateArgs = std::move(args);
444+
m_hasTemplateArgs = true;
445+
}
446+
447+
448+
string DemangledTypeNode::GetNameSegmentBase() const
449+
{
450+
if (m_typeClass == ValueTypeClass)
451+
return m_altName;
452+
if (!m_nameSegments.empty())
453+
return m_nameSegments.back();
454+
if (!m_nameSegmentNodes.empty())
455+
return m_nameSegmentNodes.back().GetNameSegmentBase();
456+
return {};
457+
}
458+
459+
460+
void DemangledTypeNode::SetNameSegmentBase(const string& name)
461+
{
462+
if (m_typeClass == ValueTypeClass)
463+
{
464+
m_altName = name;
465+
return;
466+
}
467+
if (!m_nameSegments.empty())
468+
{
469+
m_nameSegments.back() = name;
470+
return;
471+
}
472+
if (!m_nameSegmentNodes.empty())
473+
{
474+
m_nameSegmentNodes.back().SetNameSegmentBase(name);
475+
return;
476+
}
477+
m_typeClass = ValueTypeClass;
478+
m_altName = name;
479+
}
480+
481+
482+
StringList DemangledTypeNode::RenderTypeNameSegments() const
483+
{
484+
if (m_nameSegmentNodes.empty())
485+
return m_nameSegments;
486+
487+
StringList result;
488+
result.reserve(m_nameSegmentNodes.size());
489+
for (const auto& segment: m_nameSegmentNodes)
490+
result.push_back(segment.GetString());
491+
return result;
492+
}
493+
494+
377495
void DemangledTypeNode::AddPointerSuffixes(TypeBuilder& tb, bool omitPtr64) const
378496
{
379497
if (HAS_POINTER_SUFFIX(DemangledPtr64Bit) && !omitPtr64)
@@ -391,6 +509,13 @@ void DemangledTypeNode::AddPointerSuffixes(TypeBuilder& tb, bool omitPtr64) cons
391509

392510
string DemangledTypeNode::GetTypeNameString() const
393511
{
512+
if (!m_nameSegmentNodes.empty())
513+
{
514+
string result;
515+
AppendTypeName(result);
516+
return result;
517+
}
518+
394519
const auto& segs = m_nameSegments;
395520
size_t n = segs.size();
396521
if (n == 0)
@@ -418,8 +543,31 @@ string DemangledTypeNode::GetTypeNameString() const
418543
size_t DemangledTypeNode::NameStringSize() const
419544
{
420545
size_t total = 0;
421-
for (const auto& s : m_nameSegments)
422-
total += s.size();
546+
if (!m_nameSegmentNodes.empty())
547+
{
548+
for (const auto& s : m_nameSegmentNodes)
549+
total += s.NameStringSize();
550+
if (m_nameSegmentNodes.size() > 1)
551+
total += (m_nameSegmentNodes.size() - 1) * 2;
552+
}
553+
else
554+
{
555+
for (const auto& s : m_nameSegments)
556+
total += s.size();
557+
if (m_nameSegments.size() > 1)
558+
total += (m_nameSegments.size() - 1) * 2;
559+
}
560+
if (m_typeClass == ValueTypeClass)
561+
total += m_altName.size();
562+
if (!m_templateArgs.empty() || (m_hasTemplateArgs && m_typeClass == ValueTypeClass))
563+
{
564+
total += 2;
565+
if (m_templateArgs.size() > 1)
566+
total += m_templateArgs.size() - 1;
567+
for (const auto& arg: m_templateArgs)
568+
if (arg.type)
569+
total += arg.type->NameStringSize();
570+
}
423571
return total;
424572
}
425573

@@ -448,18 +596,70 @@ void DemangledTypeNode::AppendPointerSuffix(string& out) const
448596
}
449597

450598

599+
void DemangledTypeNode::AppendTemplateArguments(string& out) const
600+
{
601+
if (m_templateArgs.empty() && m_hasTemplateArgs && m_typeClass == ValueTypeClass)
602+
{
603+
out += "<>";
604+
return;
605+
}
606+
AppendTemplateArgumentList(out, m_templateArgs);
607+
}
608+
609+
610+
void DemangledTypeNode::AppendNameSegment(string& out) const
611+
{
612+
if (m_typeClass == ValueTypeClass)
613+
{
614+
out += m_altName;
615+
AppendTemplateArguments(out);
616+
return;
617+
}
618+
if (m_typeClass == NamedTypeReferenceClass)
619+
{
620+
AppendTypeName(out);
621+
return;
622+
}
623+
AppendString(out);
624+
}
625+
626+
627+
void DemangledTypeNode::AppendNameSegmentList(string& out, const vector<DemangledTypeNode>& name)
628+
{
629+
if (name.empty())
630+
return;
631+
name[0].AppendNameSegment(out);
632+
for (size_t i = 1; i < name.size(); i++)
633+
{
634+
out += "::";
635+
name[i].AppendNameSegment(out);
636+
}
637+
}
638+
639+
451640
void DemangledTypeNode::AppendTypeName(string& out) const
452641
{
642+
if (!m_nameSegmentNodes.empty())
643+
{
644+
AppendNameSegmentList(out, m_nameSegmentNodes);
645+
AppendTemplateArguments(out);
646+
return;
647+
}
648+
453649
const auto& segs = m_nameSegments;
454650
size_t n = segs.size();
455651
if (n == 0)
652+
{
653+
AppendTemplateArguments(out);
456654
return;
655+
}
457656
out += segs[0];
458657
for (size_t i = 1; i < n; i++)
459658
{
460659
out += "::";
461660
out += segs[i];
462661
}
662+
AppendTemplateArguments(out);
463663
}
464664

465665

@@ -570,7 +770,10 @@ void DemangledTypeNode::AppendBeforeName(string& out, const DemangledTypeNode* p
570770
{
571771
if (!out.empty() && out.back() != ' ' && out.back() != '(')
572772
out += ' ';
573-
out += JoinNameList(m_memberPointerOwnerName);
773+
if (!m_memberPointerOwnerNameNodes.empty())
774+
AppendNameSegmentList(out, m_memberPointerOwnerNameNodes);
775+
else
776+
out += JoinNameList(m_memberPointerOwnerName);
574777
out += "::*";
575778
}
576779
else
@@ -622,6 +825,7 @@ void DemangledTypeNode::AppendBeforeName(string& out, const DemangledTypeNode* p
622825

623826
case ValueTypeClass:
624827
out += m_altName;
828+
AppendTemplateArguments(out);
625829
break;
626830

627831
default:
@@ -853,14 +1057,14 @@ Ref<Type> DemangledTypeNode::Finalize(Architecture* arch, Platform* platform) co
8531057

8541058
case NamedTypeReferenceClass:
8551059
{
856-
QualifiedName name(m_nameSegments);
1060+
QualifiedName name(RenderTypeNameSegments());
8571061
TypeBuilder tb = TypeBuilder::NamedType(
8581062
NamedTypeReference::GenerateAutoDemangledTypeReference(m_ntrClass, name), ResolveWidth(arch, platform), 1);
8591063
tb.SetConst(m_const);
8601064
tb.SetVolatile(m_volatile);
8611065
AddPointerSuffixes(tb);
8621066
tb.SetNameType(m_nameType);
863-
tb.SetHasTemplateArguments(m_hasTemplateArgs);
1067+
tb.SetHasTemplateArguments(HasTemplateArguments());
8641068
return tb.Finalize();
8651069
}
8661070

0 commit comments

Comments
 (0)