static unsigned getRValueSize(AbstractionPattern pattern, CanType formalType) { if (pattern.isTuple()) { unsigned count = 0; auto formalTupleType = cast<TupleType>(formalType); for (auto i : indices(formalTupleType.getElementTypes())) { count += getRValueSize(pattern.getTupleElementType(i), formalTupleType.getElementType(i)); } return count; } return 1; }
CanType TypeConverter::getBridgedInputType(SILFunctionTypeRepresentation rep, AbstractionPattern pattern, CanType input) { if (auto tuple = dyn_cast<TupleType>(input)) { SmallVector<TupleTypeElt, 4> bridgedFields; bool changed = false; for (unsigned i : indices(tuple->getElements())) { auto &elt = tuple->getElement(i); Type bridged = getLoweredBridgedType(pattern.getTupleElementType(i), elt.getType(), rep, TypeConverter::ForArgument); if (!bridged) { Context.Diags.diagnose(SourceLoc(), diag::could_not_find_bridge_type, elt.getType()); llvm::report_fatal_error("unable to set up the ObjC bridge!"); } CanType canBridged = bridged->getCanonicalType(); if (canBridged != CanType(elt.getType())) { changed = true; bridgedFields.push_back(elt.getWithType(canBridged)); } else { bridgedFields.push_back(elt); } } if (!changed) return input; return CanType(TupleType::get(bridgedFields, input->getASTContext())); } auto loweredBridgedType = getLoweredBridgedType(pattern, input, rep, TypeConverter::ForArgument); if (!loweredBridgedType) { Context.Diags.diagnose(SourceLoc(), diag::could_not_find_bridge_type, input); llvm::report_fatal_error("unable to set up the ObjC bridge!"); } return loweredBridgedType->getCanonicalType(); }
/// Recursively walk into the given formal index type, expanding tuples, /// in order to form the arguments to a subscript accessor. static void translateIndices(SILGenFunction &gen, SILLocation loc, AbstractionPattern pattern, CanType formalType, ArrayRef<ManagedValue> &sourceIndices, RValue &result) { // Expand if the pattern was a tuple. if (pattern.isTuple()) { auto formalTupleType = cast<TupleType>(formalType); for (auto i : indices(formalTupleType.getElementTypes())) { translateIndices(gen, loc, pattern.getTupleElementType(i), formalTupleType.getElementType(i), sourceIndices, result); } return; } assert(!sourceIndices.empty() && "ran out of elements in index!"); ManagedValue value = sourceIndices.front(); sourceIndices = sourceIndices.slice(1); // We're going to build an RValue here, so make sure we translate // indirect arguments to be scalar if we have a loadable type. if (value.getType().isAddress()) { auto &valueTL = gen.getTypeLowering(value.getType()); if (!valueTL.isAddressOnly()) { value = gen.emitLoad(loc, value.forward(gen), valueTL, SGFContext(), IsTake); } } // Reabstract the subscripts from the requirement pattern to the // formal type. value = gen.emitOrigToSubstValue(loc, value, pattern, formalType); // Invoking the accessor will expect a value of the formal type, so // don't reabstract to that here. // Add that to the result, further expanding if necessary. result.addElement(gen, value, formalType, loc); }