TypeInfo swift::_getTypeByMangledName(StringRef typeName, SubstGenericParameterFn substGenericParam) { Demangler demangler; NodePointer node; // Check whether this is the convenience syntax "ModuleName.ClassName". size_t dotPos = typeName.find('.'); if (dotPos != llvm::StringRef::npos && typeName.find('.', dotPos + 1) == llvm::StringRef::npos) { // Form a demangle tree for this class. NodePointer classNode = demangler.createNode(Node::Kind::Class); NodePointer moduleNode = demangler.createNode(Node::Kind::Module, typeName.substr(0, dotPos)); NodePointer nameNode = demangler.createNode(Node::Kind::Identifier, typeName.substr(dotPos + 1)); classNode->addChild(moduleNode, demangler); classNode->addChild(nameNode, demangler); node = classNode; } else { // Demangle the type name. node = demangler.demangleType(typeName); if (!node) return TypeInfo(); } DecodedMetadataBuilder builder(demangler, substGenericParam, [](const Metadata *base, StringRef assocType, const ProtocolDescriptor *protocol) -> const Metadata * { // Look for a conformance of the base type to the protocol. auto witnessTable = swift_conformsToProtocol(base, protocol); if (!witnessTable) return nullptr; // Look for the named associated type within the protocol. auto assocTypeReqIndex = findAssociatedTypeByName(protocol, assocType); if (!assocTypeReqIndex) return nullptr; // Call the associated type access function. using AssociatedTypeAccessFn = const Metadata *(*)(const Metadata *base, const WitnessTable *); return ((const AssociatedTypeAccessFn *)witnessTable)[*assocTypeReqIndex] (base, witnessTable); }); auto type = Demangle::decodeMangledType(builder, node); return {type, builder.getOwnership()}; }
/// Produce a Demangler value suitable for resolving runtime type metadata /// strings. static Demangler getDemanglerForRuntimeTypeResolution() { Demangler dem; // Resolve symbolic references to type contexts into the absolute address of // the type context descriptor, so that if we see a symbolic reference in the // mangled name we can immediately find the associated metadata. dem.setSymbolicReferenceResolver([&](int32_t offset, const void *base) -> NodePointer { auto absolute_addr = (uintptr_t)detail::applyRelativeOffset(base, offset); auto reference = dem.createNode(Node::Kind::SymbolicReference, absolute_addr); auto type = dem.createNode(Node::Kind::Type); type->addChild(reference, dem); return type; }); return dem; }