Skip to content

Commit f1e8499

Browse files
committed
Demangler: Make symbolic reference resolver part of demangle(Symbol|Type) calls.
This makes for a cleaner and less implicit-context-heavy API, and makes it easier for symbolic reference resolvers to do context-dependent things (like map the in-memory base address back to a remote address in MetadataReader).
1 parent 07bcf5a commit f1e8499

File tree

11 files changed

+91
-70
lines changed

11 files changed

+91
-70
lines changed

include/swift/Demangling/Demangler.h

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -456,9 +456,11 @@ class Demangler : public NodeFactory {
456456
int NumWords;
457457
StringRef Text;
458458
size_t Pos;
459+
std::function<SymbolicReferenceResolver_t> SymbolicReferenceResolver;
459460

460461
public:
461-
DemangleInitRAII(Demangler &Dem, StringRef MangledName);
462+
DemangleInitRAII(Demangler &Dem, StringRef MangledName,
463+
std::function<SymbolicReferenceResolver_t> SymbolicReferenceResolver);
462464
~DemangleInitRAII();
463465
};
464466
friend DemangleInitRAII;
@@ -587,39 +589,35 @@ class Demangler : public NodeFactory {
587589

588590
void clear() override;
589591

590-
/// Install a resolver for symbolic references in a mangled string.
591-
void setSymbolicReferenceResolver(
592-
std::function<SymbolicReferenceResolver_t> resolver) {
593-
SymbolicReferenceResolver = resolver;
594-
}
595-
596-
/// Take the symbolic reference resolver.
597-
std::function<SymbolicReferenceResolver_t> &&
598-
takeSymbolicReferenceResolver() {
599-
return std::move(SymbolicReferenceResolver);
600-
}
601-
602592
/// Demangle the given symbol and return the parse tree.
603593
///
604594
/// \param MangledName The mangled symbol string, which start with the
605595
/// mangling prefix $S.
596+
/// \param SymbolicReferenceResolver A function invoked to resolve symbolic references in
597+
/// the string. If null, then symbolic references will cause the demangle to fail.
606598
///
607599
/// \returns A parse tree for the demangled string - or a null pointer
608600
/// on failure.
609601
/// The lifetime of the returned node tree ends with the lifetime of the
610602
/// Demangler or with a call of clear().
611-
NodePointer demangleSymbol(StringRef MangledName);
603+
NodePointer demangleSymbol(StringRef MangledName,
604+
std::function<SymbolicReferenceResolver_t> SymbolicReferenceResolver
605+
= nullptr);
612606

613607
/// Demangle the given type and return the parse tree.
614608
///
615609
/// \param MangledName The mangled type string, which does _not_ start with
616610
/// the mangling prefix $S.
611+
/// \param SymbolicReferenceResolver A function invoked to resolve symbolic references in
612+
/// the string. If null, then symbolic references will cause the demangle to fail.
617613
///
618614
/// \returns A parse tree for the demangled string - or a null pointer
619615
/// on failure.
620616
/// The lifetime of the returned node tree ends with the lifetime of the
621617
/// Demangler or with a call of clear().
622-
NodePointer demangleType(StringRef MangledName);
618+
NodePointer demangleType(StringRef MangledName,
619+
std::function<SymbolicReferenceResolver_t> SymbolicReferenceResolver
620+
= nullptr);
623621
};
624622

625623
/// A demangler which uses stack space for its initial memory.

include/swift/Reflection/ReflectionContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class ReflectionContext
108108

109109
explicit ReflectionContext(std::shared_ptr<MemoryReader> reader)
110110
: super(std::move(reader)) {
111-
getBuilder().setSymbolicReferenceResolverReader(*this);
111+
getBuilder().setMetadataReader(*this);
112112
}
113113

114114
ReflectionContext(const ReflectionContext &other) = delete;

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,14 +483,27 @@ class TypeRefBuilder {
483483

484484
uint64_t getRemoteAddrOfTypeRefPointer(const void *pointer);
485485

486+
std::function<auto (SymbolicReferenceKind kind,
487+
Directness directness,
488+
int32_t offset, const void *base) -> Demangle::Node *>
489+
SymbolicReferenceResolver;
490+
491+
std::string normalizeReflectionName(StringRef name);
492+
bool reflectionNameMatches(StringRef reflectionName,
493+
StringRef searchName);
494+
495+
Demangle::Node *demangleTypeRef(StringRef mangledName) {
496+
return Dem.demangleType(mangledName, SymbolicReferenceResolver);
497+
}
498+
486499
public:
487500
template<typename Runtime>
488-
void setSymbolicReferenceResolverReader(
501+
void setMetadataReader(
489502
remote::MetadataReader<Runtime, TypeRefBuilder> &reader) {
490503
// Have the TypeRefBuilder demangle symbolic references by reading their
491504
// demangling out of the referenced context descriptors in the target
492505
// process.
493-
Dem.setSymbolicReferenceResolver(
506+
SymbolicReferenceResolver =
494507
[this, &reader](SymbolicReferenceKind kind,
495508
Directness directness,
496509
int32_t offset, const void *base) -> Demangle::Node * {
@@ -531,7 +544,7 @@ class TypeRefBuilder {
531544
}
532545

533546
return nullptr;
534-
});
547+
};
535548

536549
OpaqueUnderlyingTypeReader =
537550
[&reader](const void *descriptor, unsigned ordinal) -> const TypeRef* {

include/swift/Remote/MetadataReader.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,9 +1690,8 @@ class MetadataReader {
16901690
break;
16911691
}
16921692

1693-
// Install our own symbolic reference resolver
1694-
auto oldSymbolicReferenceResolver = dem.takeSymbolicReferenceResolver();
1695-
dem.setSymbolicReferenceResolver([&](SymbolicReferenceKind kind,
1693+
// Symbolic reference resolver for the demangle operation below.
1694+
auto symbolicReferenceResolver = [&](SymbolicReferenceKind kind,
16961695
Directness directness,
16971696
int32_t offset,
16981697
const void *base) ->
@@ -1726,20 +1725,19 @@ class MetadataReader {
17261725
}
17271726

17281727
return nullptr;
1729-
});
1728+
};
17301729

17311730
swift::Demangle::NodePointer result;
17321731
switch (kind) {
17331732
case MangledNameKind::Type:
1734-
result = dem.demangleType(mangledName);
1733+
result = dem.demangleType(mangledName, symbolicReferenceResolver);
17351734
break;
17361735

17371736
case MangledNameKind::Symbol:
1738-
result = dem.demangleSymbol(mangledName);
1737+
result = dem.demangleSymbol(mangledName, symbolicReferenceResolver);
17391738
break;
17401739
}
17411740

1742-
dem.setSymbolicReferenceResolver(std::move(oldSymbolicReferenceResolver));
17431741
return result;
17441742
}
17451743

lib/Demangling/Demangler.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -493,18 +493,21 @@ void Demangler::clear() {
493493
}
494494

495495
Demangler::DemangleInitRAII::DemangleInitRAII(Demangler &Dem,
496-
StringRef MangledName)
496+
StringRef MangledName,
497+
std::function<SymbolicReferenceResolver_t> TheSymbolicReferenceResolver)
497498
// Save the current demangler state so we can restore it.
498499
: Dem(Dem),
499500
NodeStack(Dem.NodeStack), Substitutions(Dem.Substitutions),
500-
NumWords(Dem.NumWords), Text(Dem.Text), Pos(Dem.Pos)
501+
NumWords(Dem.NumWords), Text(Dem.Text), Pos(Dem.Pos),
502+
SymbolicReferenceResolver(std::move(Dem.SymbolicReferenceResolver))
501503
{
502504
// Reset the demangler state for a nested job.
503505
Dem.NodeStack.init(Dem, 16);
504506
Dem.Substitutions.init(Dem, 16);
505507
Dem.NumWords = 0;
506508
Dem.Text = MangledName;
507509
Dem.Pos = 0;
510+
Dem.SymbolicReferenceResolver = std::move(TheSymbolicReferenceResolver);
508511
}
509512

510513
Demangler::DemangleInitRAII::~DemangleInitRAII() {
@@ -514,10 +517,13 @@ Demangler::DemangleInitRAII::~DemangleInitRAII() {
514517
Dem.NumWords = NumWords;
515518
Dem.Text = Text;
516519
Dem.Pos = Pos;
520+
Dem.SymbolicReferenceResolver = std::move(SymbolicReferenceResolver);
517521
}
518522

519-
NodePointer Demangler::demangleSymbol(StringRef MangledName) {
520-
DemangleInitRAII state(*this, MangledName);
523+
NodePointer Demangler::demangleSymbol(StringRef MangledName,
524+
std::function<SymbolicReferenceResolver_t> SymbolicReferenceResolver) {
525+
DemangleInitRAII state(*this, MangledName,
526+
std::move(SymbolicReferenceResolver));
521527

522528
// Demangle old-style class and protocol names, which are still used in the
523529
// ObjC metadata.
@@ -561,8 +567,10 @@ NodePointer Demangler::demangleSymbol(StringRef MangledName) {
561567
return topLevel;
562568
}
563569

564-
NodePointer Demangler::demangleType(StringRef MangledName) {
565-
DemangleInitRAII state(*this, MangledName);
570+
NodePointer Demangler::demangleType(StringRef MangledName,
571+
std::function<SymbolicReferenceResolver_t> SymbolicReferenceResolver) {
572+
DemangleInitRAII state(*this, MangledName,
573+
std::move(SymbolicReferenceResolver));
566574

567575
parseAndPushNodes();
568576

@@ -701,6 +709,7 @@ NodePointer Demangler::demangleSymbolicReference(unsigned char rawKind,
701709
NodePointer resolved = nullptr;
702710
if (SymbolicReferenceResolver)
703711
resolved = SymbolicReferenceResolver(kind, direct, value, at);
712+
704713
// With no resolver, or a resolver that failed, refuse to demangle further.
705714
if (!resolved)
706715
return nullptr;

lib/SILOptimizer/Utils/SpecializationMangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class AttributeDemangler : public Demangle::Demangler {
3333
public:
3434
void demangleAndAddAsChildren(StringRef MangledSpecialization,
3535
NodePointer Parent) {
36-
DemangleInitRAII state(*this, MangledSpecialization);
36+
DemangleInitRAII state(*this, MangledSpecialization, nullptr);
3737
if (!parseAndPushNodes()) {
3838
llvm::errs() << "Can't demangle: " << MangledSpecialization << '\n';
3939
abort();

stdlib/public/Reflection/TypeRefBuilder.cpp

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,12 @@ TypeRefBuilder::getRemoteAddrOfTypeRefPointer(const void *pointer) {
5151
TypeRefBuilder::TypeRefBuilder() : TC(*this) {}
5252

5353
/// Normalize a mangled name so it can be matched with string equality.
54-
static std::string normalizeReflectionName(Demangler &dem, StringRef reflectionName) {
54+
std::string
55+
TypeRefBuilder::normalizeReflectionName(StringRef reflectionName) {
5556
reflectionName = dropSwiftManglingPrefix(reflectionName);
5657

5758
// Remangle the reflection name to resolve symbolic references.
58-
if (auto node = dem.demangleType(reflectionName)) {
59+
if (auto node = demangleTypeRef(reflectionName)) {
5960
return mangleNode(node);
6061
}
6162

@@ -64,10 +65,10 @@ static std::string normalizeReflectionName(Demangler &dem, StringRef reflectionN
6465
}
6566

6667
/// Determine whether the given reflection protocol name matches.
67-
static bool reflectionNameMatches(Demangler &dem,
68-
StringRef reflectionName,
69-
StringRef searchName) {
70-
auto normalized = normalizeReflectionName(dem, reflectionName);
68+
bool
69+
TypeRefBuilder::reflectionNameMatches(StringRef reflectionName,
70+
StringRef searchName) {
71+
auto normalized = normalizeReflectionName(reflectionName);
7172
return searchName.equals(normalized);
7273
}
7374

@@ -91,12 +92,12 @@ lookupTypeWitness(const std::string &MangledTypeName,
9192
uint64_t NameOffset = Info.AssociatedType.SectionOffset
9293
- Info.ReflectionString.SectionOffset;
9394
for (const auto &AssocTyDescriptor : Info.AssociatedType.Metadata) {
94-
if (!reflectionNameMatches(Dem,
95+
if (!reflectionNameMatches(
9596
AssocTyDescriptor.getMangledConformingTypeName(TypeRefOffset),
9697
MangledTypeName))
9798
continue;
9899

99-
if (!reflectionNameMatches(Dem,
100+
if (!reflectionNameMatches(
100101
AssocTyDescriptor.getMangledProtocolTypeName(TypeRefOffset),
101102
Protocol))
102103
continue;
@@ -107,7 +108,7 @@ lookupTypeWitness(const std::string &MangledTypeName,
107108

108109
auto SubstitutedTypeName =
109110
AssocTy.getMangledSubstitutedTypeName(TypeRefOffset);
110-
auto Demangled = Dem.demangleType(SubstitutedTypeName);
111+
auto Demangled = demangleTypeRef(SubstitutedTypeName);
111112
auto *TypeWitness = swift::Demangle::decodeMangledType(*this, Demangled);
112113

113114
AssociatedTypeCache.insert(std::make_pair(key, TypeWitness));
@@ -129,7 +130,7 @@ lookupSuperclass(const TypeRef *TR) {
129130

130131
auto TypeRefOffset = FD.second->Field.SectionOffset
131132
- FD.second->TypeReference.SectionOffset;
132-
auto Demangled = Dem.demangleType(FD.first->getSuperclass(TypeRefOffset));
133+
auto Demangled = demangleTypeRef(FD.first->getSuperclass(TypeRefOffset));
133134
auto Unsubstituted = swift::Demangle::decodeMangledType(*this, Demangled);
134135
if (!Unsubstituted)
135136
return nullptr;
@@ -164,7 +165,7 @@ TypeRefBuilder::getFieldTypeInfo(const TypeRef *TR) {
164165
if (!FD.hasMangledTypeName())
165166
continue;
166167
auto CandidateMangledName = FD.getMangledTypeName(TypeRefOffset);
167-
auto NormalizedName = normalizeReflectionName(Dem, CandidateMangledName);
168+
auto NormalizedName = normalizeReflectionName(CandidateMangledName);
168169
FieldTypeInfoCache[NormalizedName] = {&FD, &Info};
169170
Dem.clear();
170171
}
@@ -204,7 +205,7 @@ bool TypeRefBuilder::getFieldTypeRefs(
204205
continue;
205206
}
206207

207-
auto Demangled = Dem.demangleType(Field.getMangledTypeName(TypeRefOffset));
208+
auto Demangled = demangleTypeRef(Field.getMangledTypeName(TypeRefOffset));
208209
auto Unsubstituted = swift::Demangle::decodeMangledType(*this, Demangled);
209210
if (!Unsubstituted)
210211
return false;
@@ -244,7 +245,7 @@ TypeRefBuilder::getBuiltinTypeInfo(const TypeRef *TR) {
244245
continue;
245246
auto CandidateMangledName =
246247
BuiltinTypeDescriptor.getMangledTypeName(TypeRefOffset);
247-
if (!reflectionNameMatches(Dem, CandidateMangledName, MangledName))
248+
if (!reflectionNameMatches(CandidateMangledName, MangledName))
248249
continue;
249250
return &BuiltinTypeDescriptor;
250251
}
@@ -277,7 +278,7 @@ TypeRefBuilder::getClosureContextInfo(const CaptureDescriptor &CD,
277278
const TypeRef *TR = nullptr;
278279
if (i->hasMangledTypeName()) {
279280
auto MangledName = i->getMangledTypeName(TypeRefOffset);
280-
auto DemangleTree = Dem.demangleType(MangledName);
281+
auto DemangleTree = demangleTypeRef(MangledName);
281282
TR = swift::Demangle::decodeMangledType(*this, DemangleTree);
282283
}
283284
Info.CaptureTypes.push_back(TR);
@@ -287,7 +288,7 @@ TypeRefBuilder::getClosureContextInfo(const CaptureDescriptor &CD,
287288
const TypeRef *TR = nullptr;
288289
if (i->hasMangledTypeName()) {
289290
auto MangledName = i->getMangledTypeName(TypeRefOffset);
290-
auto DemangleTree = Dem.demangleType(MangledName);
291+
auto DemangleTree = demangleTypeRef(MangledName);
291292
TR = swift::Demangle::decodeMangledType(*this, DemangleTree);
292293
}
293294

@@ -312,7 +313,7 @@ TypeRefBuilder::getClosureContextInfo(const CaptureDescriptor &CD,
312313
void
313314
TypeRefBuilder::dumpTypeRef(StringRef MangledName,
314315
std::ostream &OS, bool printTypeName) {
315-
auto DemangleTree = Dem.demangleType(MangledName);
316+
auto DemangleTree = demangleTypeRef(MangledName);
316317
auto TypeName = nodeToString(DemangleTree);
317318
OS << TypeName << '\n';
318319
auto TR = swift::Demangle::decodeMangledType(*this, DemangleTree);
@@ -333,7 +334,7 @@ void TypeRefBuilder::dumpFieldSection(std::ostream &OS) {
333334
uint64_t NameOffset = sections.Field.SectionOffset
334335
- sections.ReflectionString.SectionOffset;
335336
for (const auto &descriptor : sections.Field.Metadata) {
336-
auto TypeDemangling = Dem.demangleType(
337+
auto TypeDemangling = demangleTypeRef(
337338
dropSwiftManglingPrefix(descriptor.getMangledTypeName(TypeRefOffset)));
338339
auto TypeName = nodeToString(TypeDemangling);
339340
OS << TypeName << '\n';
@@ -363,10 +364,10 @@ void TypeRefBuilder::dumpAssociatedTypeSection(std::ostream &OS) {
363364
uint64_t NameOffset = sections.AssociatedType.SectionOffset
364365
- sections.ReflectionString.SectionOffset;
365366
for (const auto &descriptor : sections.AssociatedType.Metadata) {
366-
auto conformingTypeNode = Dem.demangleType(
367+
auto conformingTypeNode = demangleTypeRef(
367368
descriptor.getMangledConformingTypeName(TypeRefOffset));
368369
auto conformingTypeName = nodeToString(conformingTypeNode);
369-
auto protocolNode = Dem.demangleType(dropSwiftManglingPrefix(
370+
auto protocolNode = demangleTypeRef(dropSwiftManglingPrefix(
370371
descriptor.getMangledProtocolTypeName(TypeRefOffset)));
371372
auto protocolName = nodeToString(protocolNode);
372373

@@ -388,10 +389,10 @@ void TypeRefBuilder::dumpBuiltinTypeSection(std::ostream &OS) {
388389
uint64_t TypeRefOffset = sections.Builtin.SectionOffset
389390
- sections.TypeReference.SectionOffset;
390391
for (const auto &descriptor : sections.Builtin.Metadata) {
391-
auto typeName =
392-
Demangle::demangleTypeAsString(
392+
auto typeNode = demangleTypeRef(
393393
descriptor.getMangledTypeName(TypeRefOffset));
394-
394+
auto typeName = nodeToString(typeNode);
395+
395396
OS << "\n- " << typeName << ":\n";
396397
OS << "Size: " << descriptor.Size << "\n";
397398
OS << "Alignment: " << descriptor.getAlignment() << "\n";

stdlib/public/runtime/Casting.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,6 @@ static void _buildNameForMetadata(const Metadata *type,
9999
// Use the remangler to generate a mangled name from the type metadata.
100100

101101
Demangle::Demangler Dem;
102-
// We want to resolve symbolic references to a user-comprehensible
103-
// representation of the referenced context.
104-
Dem.setSymbolicReferenceResolver(ResolveToDemanglingForContext(Dem));
105-
106102
auto demangling = _swift_buildDemanglingForMetadata(type, Dem);
107103
if (demangling == nullptr) {
108104
result = "<<< invalid type >>>";

stdlib/public/runtime/Demangle.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ swift::_buildDemanglingForContext(const ContextDescriptor *context,
8080
case ContextDescriptorKind::Extension: {
8181
auto extension = llvm::cast<ExtensionContextDescriptor>(component);
8282
// Demangle the extension self type.
83-
auto selfType = Dem.demangleType(extension->getMangledExtendedContext());
83+
auto selfType = Dem.demangleType(extension->getMangledExtendedContext(),
84+
ResolveToDemanglingForContext(Dem));
8485
if (selfType->getKind() == Node::Kind::Type)
8586
selfType = selfType->getChild(0);
8687

0 commit comments

Comments
 (0)