Skip to content

Commit d4952d5

Browse files
committed
Add Runtime Demangling for Extended Existentials
1 parent 1628798 commit d4952d5

File tree

1 file changed

+90
-42
lines changed

1 file changed

+90
-42
lines changed

stdlib/public/runtime/Demangle.cpp

Lines changed: 90 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,48 @@ _buildDemanglingForNominalType(const Metadata *type, Demangle::Demangler &Dem) {
316316
return _buildDemanglingForContext(description, demangledGenerics, Dem);
317317
}
318318

319+
static Demangle::NodePointer
320+
_buildDemanglingForProtocolDescriptor(ProtocolDescriptorRef protocol,
321+
Demangle::Demangler &Dem) {
322+
#if SWIFT_OBJC_INTEROP
323+
if (protocol.isObjC()) {
324+
// The protocol name is mangled as a type symbol, with the _Tt prefix.
325+
StringRef ProtoName(protocol.getName());
326+
NodePointer protocolNode = Dem.demangleSymbol(ProtoName);
327+
328+
// ObjC protocol names aren't mangled.
329+
if (!protocolNode) {
330+
auto module = Dem.createNode(Node::Kind::Module, MANGLING_MODULE_OBJC);
331+
auto node = Dem.createNode(Node::Kind::Protocol);
332+
node->addChild(module, Dem);
333+
node->addChild(Dem.createNode(Node::Kind::Identifier, ProtoName), Dem);
334+
auto typeNode = Dem.createNode(Node::Kind::Type);
335+
typeNode->addChild(node, Dem);
336+
return typeNode;
337+
}
338+
339+
// Dig out the protocol node.
340+
// Global -> (Protocol|TypeMangling)
341+
protocolNode = protocolNode->getChild(0);
342+
if (protocolNode->getKind() == Node::Kind::TypeMangling) {
343+
protocolNode = protocolNode->getChild(0); // TypeMangling -> Type
344+
protocolNode = protocolNode->getChild(0); // Type -> ProtocolList
345+
protocolNode = protocolNode->getChild(0); // ProtocolList -> TypeList
346+
protocolNode = protocolNode->getChild(0); // TypeList -> Type
347+
348+
assert(protocolNode->getKind() == Node::Kind::Type);
349+
assert(protocolNode->getChild(0)->getKind() == Node::Kind::Protocol);
350+
} else {
351+
assert(protocolNode->getKind() == Node::Kind::Protocol);
352+
}
353+
354+
return protocolNode;
355+
}
356+
#endif
357+
358+
return _buildDemanglingForContext(protocol.getSwiftProtocol(), {}, Dem);
359+
}
360+
319361
// Build a demangled type tree for a type.
320362
//
321363
// FIXME: This should use MetadataReader.h.
@@ -361,48 +403,7 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
361403
// its canonical ordering of protocols.
362404

363405
for (auto protocol : protocols) {
364-
#if SWIFT_OBJC_INTEROP
365-
if (protocol.isObjC()) {
366-
// The protocol name is mangled as a type symbol, with the _Tt prefix.
367-
StringRef ProtoName(protocol.getName());
368-
NodePointer protocolNode = Dem.demangleSymbol(ProtoName);
369-
370-
// ObjC protocol names aren't mangled.
371-
if (!protocolNode) {
372-
auto module = Dem.createNode(Node::Kind::Module,
373-
MANGLING_MODULE_OBJC);
374-
auto node = Dem.createNode(Node::Kind::Protocol);
375-
node->addChild(module, Dem);
376-
node->addChild(Dem.createNode(Node::Kind::Identifier, ProtoName),
377-
Dem);
378-
auto typeNode = Dem.createNode(Node::Kind::Type);
379-
typeNode->addChild(node, Dem);
380-
type_list->addChild(typeNode, Dem);
381-
continue;
382-
}
383-
384-
// Dig out the protocol node.
385-
// Global -> (Protocol|TypeMangling)
386-
protocolNode = protocolNode->getChild(0);
387-
if (protocolNode->getKind() == Node::Kind::TypeMangling) {
388-
protocolNode = protocolNode->getChild(0); // TypeMangling -> Type
389-
protocolNode = protocolNode->getChild(0); // Type -> ProtocolList
390-
protocolNode = protocolNode->getChild(0); // ProtocolList -> TypeList
391-
protocolNode = protocolNode->getChild(0); // TypeList -> Type
392-
393-
assert(protocolNode->getKind() == Node::Kind::Type);
394-
assert(protocolNode->getChild(0)->getKind() == Node::Kind::Protocol);
395-
} else {
396-
assert(protocolNode->getKind() == Node::Kind::Protocol);
397-
}
398-
399-
type_list->addChild(protocolNode, Dem);
400-
continue;
401-
}
402-
#endif
403-
404-
auto protocolNode =
405-
_buildDemanglingForContext(protocol.getSwiftProtocol(), { }, Dem);
406+
auto protocolNode = _buildDemanglingForProtocolDescriptor(protocol, Dem);
406407
if (!protocolNode)
407408
return nullptr;
408409

@@ -443,6 +444,53 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
443444
// Just a simple composition of protocols.
444445
return proto_list;
445446
}
447+
case MetadataKind::ExtendedExistential: {
448+
auto exis = static_cast<const ExtendedExistentialTypeMetadata *>(type);
449+
auto genSig = exis->Shape->getGeneralizationSignature();
450+
const unsigned selfParamIdx = genSig.getParams().size();
451+
auto node = Dem.createNode(Node::Kind::ParameterizedProtocol);
452+
for (const auto &reqt :
453+
exis->Shape->getRequirementSignature().getRequirements()) {
454+
if (reqt.getKind() != GenericRequirementKind::Protocol) {
455+
continue;
456+
}
457+
458+
if (!reqt.Flags.hasKeyArgument()) {
459+
continue;
460+
}
461+
462+
auto lhsTypeNode = Dem.demangleType(reqt.getParam());
463+
if (!lhsTypeNode || lhsTypeNode->getKind() != Node::Kind::Type ||
464+
!lhsTypeNode->hasChildren() ||
465+
lhsTypeNode->getChild(0)->getKind() !=
466+
Node::Kind::DependentGenericParamType ||
467+
lhsTypeNode->getChild(0)->getNumChildren() != 2) {
468+
continue;
469+
}
470+
auto index = lhsTypeNode->getChild(0)->getChild(1)->getIndex();
471+
if (index + 1 != selfParamIdx)
472+
continue;
473+
474+
auto *protocolNode =
475+
_buildDemanglingForProtocolDescriptor(reqt.getProtocol(), Dem);
476+
if (!protocolNode)
477+
continue;
478+
479+
node->addChild(protocolNode, Dem);
480+
}
481+
482+
const unsigned shapeArgumentCount =
483+
exis->Shape->getGenSigArgumentLayoutSizeInWords();
484+
auto type_list = Dem.createNode(Node::Kind::TypeList);
485+
for (unsigned i = 0; i < shapeArgumentCount; ++i) {
486+
auto genArg = exis->getGeneralizationArguments()[i];
487+
auto eltType =
488+
_swift_buildDemanglingForMetadata((const Metadata *)genArg, Dem);
489+
type_list->addChild(eltType, Dem);
490+
}
491+
node->addChild(type_list, Dem);
492+
return node;
493+
}
446494
case MetadataKind::ExistentialMetatype: {
447495
auto metatype = static_cast<const ExistentialMetatypeMetadata *>(type);
448496
auto instance = _swift_buildDemanglingForMetadata(metatype->InstanceType,

0 commit comments

Comments
 (0)