Example #1
0
RValue
SILGenFunction::emitPointerToPointer(SILLocation loc,
                                     ManagedValue input,
                                     CanType inputType,
                                     CanType outputType,
                                     SGFContext C) {
  auto converter = getASTContext().getConvertPointerToPointerArgument(nullptr);

  // The generic function currently always requires indirection, but pointers
  // are always loadable.
  auto origBuf = emitTemporaryAllocation(loc, input.getType());
  B.emitStoreValueOperation(loc, input.forward(*this), origBuf,
                            StoreOwnershipQualifier::Init);
  auto origValue = emitManagedBufferWithCleanup(origBuf);
  
  // Invoke the conversion intrinsic to convert to the destination type.
  auto *M = SGM.M.getSwiftModule();
  auto *proto = getPointerProtocol();
  auto firstSubMap = inputType->getContextSubstitutionMap(M, proto);
  auto secondSubMap = outputType->getContextSubstitutionMap(M, proto);

  auto *genericSig = converter->getGenericSignature();
  auto subMap =
    SubstitutionMap::combineSubstitutionMaps(firstSubMap,
                                             secondSubMap,
                                             CombineSubstitutionMaps::AtIndex,
                                             1, 0,
                                             genericSig);
  
  return emitApplyOfLibraryIntrinsic(loc, converter, subMap, origValue, C);
}
Example #2
0
bool FulfillmentMap::searchNominalTypeMetadata(IRGenModule &IGM,
                                               CanType type,
                                               MetadataState metadataState,
                                               unsigned source,
                                               MetadataPath &&path,
                                         const InterestingKeysCallback &keys) {
  // Objective-C generics don't preserve their generic parameters at runtime,
  // so they aren't able to fulfill type metadata requirements.
  if (type.getAnyNominal()->hasClangNode()) {
    return false;
  }
  
  auto *nominal = type.getAnyNominal();
  if (!nominal->isGenericContext() || isa<ProtocolDecl>(nominal)) {
    return false;
  }

  bool hadFulfillment = false;

  GenericTypeRequirements requirements(IGM, nominal);
  requirements.enumerateFulfillments(
      IGM, type->getContextSubstitutionMap(IGM.getSwiftModule(), nominal),
      [&](unsigned reqtIndex, CanType arg,
          Optional<ProtocolConformanceRef> conf) {
    // Skip uninteresting type arguments.
    if (!keys.hasInterestingType(arg))
      return;

    // If the fulfilled value is type metadata, refine the path.
    if (!conf) {
      auto argState = getPresumedMetadataStateForTypeArgument(metadataState);
      MetadataPath argPath = path;
      argPath.addNominalTypeArgumentComponent(reqtIndex);
      hadFulfillment |=
        searchTypeMetadata(IGM, arg, IsExact, argState, source,
                           std::move(argPath), keys);
      return;
    }

    // Otherwise, it's a conformance.

    // Ignore it unless the type itself is interesting.
    if (!keys.isInterestingType(arg))
      return;

    // Refine the path.
    MetadataPath argPath = path;
    argPath.addNominalTypeArgumentConformanceComponent(reqtIndex);

    hadFulfillment |= searchWitnessTable(IGM, arg, conf->getRequirement(),
                                         source, std::move(argPath), keys);
  });

  return hadFulfillment;
}