예제 #1
0
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()};
}
예제 #2
0
/// 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;
}