mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Update SILFunctionType for borrow accessors
This commit is contained in:
@@ -298,6 +298,24 @@ public:
|
|||||||
IndirectSILResultFilter(silConv.loweredAddresses));
|
IndirectSILResultFilter(silConv.loweredAddresses));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasGuaranteedResults() const {
|
||||||
|
for (auto result : funcTy->getResults()) {
|
||||||
|
if (result.getConvention() == ResultConvention::Guaranteed) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasGuaranteedAddressResults() const {
|
||||||
|
for (auto result : funcTy->getResults()) {
|
||||||
|
if (result.getConvention() == ResultConvention::GuaranteedAddress) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
struct SILResultTypeFunc;
|
struct SILResultTypeFunc;
|
||||||
|
|
||||||
// Gratuitous template parameter is to delay instantiating `mapped_iterator`
|
// Gratuitous template parameter is to delay instantiating `mapped_iterator`
|
||||||
|
|||||||
@@ -1373,16 +1373,20 @@ class DestructureResults {
|
|||||||
SmallVectorImpl<SILResultInfo> &Results;
|
SmallVectorImpl<SILResultInfo> &Results;
|
||||||
TypeExpansionContext context;
|
TypeExpansionContext context;
|
||||||
bool hasSendingResult;
|
bool hasSendingResult;
|
||||||
|
bool isBorrowOrMutateAccessor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DestructureResults(TypeExpansionContext context, TypeConverter &TC,
|
DestructureResults(TypeExpansionContext context, TypeConverter &TC,
|
||||||
const Conventions &conventions,
|
const Conventions &conventions,
|
||||||
SmallVectorImpl<SILResultInfo> &results,
|
SmallVectorImpl<SILResultInfo> &results,
|
||||||
bool hasSendingResult)
|
bool hasSendingResult, bool isBorrowOrMutateAccessor)
|
||||||
: TC(TC), Convs(conventions), Results(results), context(context),
|
: TC(TC), Convs(conventions), Results(results), context(context),
|
||||||
hasSendingResult(hasSendingResult) {}
|
hasSendingResult(hasSendingResult),
|
||||||
|
isBorrowOrMutateAccessor(isBorrowOrMutateAccessor) {}
|
||||||
|
|
||||||
void destructure(AbstractionPattern origType, CanType substType) {
|
void destructure(AbstractionPattern origType, CanType substType) {
|
||||||
|
bool hasAddressOnlyReturn = false;
|
||||||
|
|
||||||
// Recur into tuples.
|
// Recur into tuples.
|
||||||
if (origType.isTuple()) {
|
if (origType.isTuple()) {
|
||||||
origType.forEachTupleElement(substType,
|
origType.forEachTupleElement(substType,
|
||||||
@@ -1394,6 +1398,11 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isBorrowOrMutateAccessor) {
|
||||||
|
llvm_unreachable(
|
||||||
|
"Returning packs from borrow/mutate accessor is not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
// If the original element type is a pack expansion, build a
|
// If the original element type is a pack expansion, build a
|
||||||
// lowered pack type for the substituted components it expands to.
|
// lowered pack type for the substituted components it expands to.
|
||||||
auto origExpansionType = elt.getOrigType();
|
auto origExpansionType = elt.getOrigType();
|
||||||
@@ -1427,8 +1436,18 @@ public:
|
|||||||
ResultConvention convention;
|
ResultConvention convention;
|
||||||
if (isFormallyReturnedIndirectly(origType, substType,
|
if (isFormallyReturnedIndirectly(origType, substType,
|
||||||
substResultTLForConvention)) {
|
substResultTLForConvention)) {
|
||||||
convention = ResultConvention::Indirect;
|
hasAddressOnlyReturn = true;
|
||||||
|
if (Convs.getResult(substResultTLForConvention) ==
|
||||||
|
ResultConvention::Guaranteed) {
|
||||||
|
convention = ResultConvention::GuaranteedAddress;
|
||||||
|
} else {
|
||||||
|
convention = ResultConvention::Indirect;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (isBorrowOrMutateAccessor && hasAddressOnlyReturn) {
|
||||||
|
llvm_unreachable("Returning a tuple with address-only and loadable "
|
||||||
|
"types is not supported in borrow/mutate accessor");
|
||||||
|
}
|
||||||
convention = Convs.getResult(substResultTLForConvention);
|
convention = Convs.getResult(substResultTLForConvention);
|
||||||
|
|
||||||
// Reduce conventions for trivial types to an unowned convention.
|
// Reduce conventions for trivial types to an unowned convention.
|
||||||
@@ -2338,6 +2357,17 @@ getAsCoroutineAccessor(std::optional<SILDeclRef> constant) {
|
|||||||
return accessor;
|
return accessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isBorrowOrMutateAccessor(std::optional<SILDeclRef> constant) {
|
||||||
|
if (!constant || !constant->hasDecl())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto accessor = dyn_cast<AccessorDecl>(constant->getDecl());
|
||||||
|
if (!accessor)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return accessor->isBorrowAccessor() || accessor->isMutateAccessor();
|
||||||
|
}
|
||||||
|
|
||||||
static void destructureYieldsForReadAccessor(TypeConverter &TC,
|
static void destructureYieldsForReadAccessor(TypeConverter &TC,
|
||||||
TypeExpansionContext expansion,
|
TypeExpansionContext expansion,
|
||||||
AbstractionPattern origType,
|
AbstractionPattern origType,
|
||||||
@@ -2707,12 +2737,13 @@ static CanSILFunctionType getSILFunctionType(
|
|||||||
destructureYieldsForCoroutine(TC, expansionContext, constant,
|
destructureYieldsForCoroutine(TC, expansionContext, constant,
|
||||||
coroutineOrigYieldType, coroutineSubstYieldType,
|
coroutineOrigYieldType, coroutineSubstYieldType,
|
||||||
yields, coroutineKind);
|
yields, coroutineKind);
|
||||||
|
|
||||||
// Destructure the result tuple type.
|
// Destructure the result tuple type.
|
||||||
SmallVector<SILResultInfo, 8> results;
|
SmallVector<SILResultInfo, 8> results;
|
||||||
{
|
{
|
||||||
DestructureResults destructurer(expansionContext, TC, conventions, results,
|
DestructureResults destructurer(expansionContext, TC, conventions, results,
|
||||||
hasSendingResult);
|
hasSendingResult,
|
||||||
|
isBorrowOrMutateAccessor(constant));
|
||||||
destructurer.destructure(origResultType, substFormalResultType);
|
destructurer.destructure(origResultType, substFormalResultType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3252,11 +3283,17 @@ static CanSILFunctionType getNativeSILFunctionType(
|
|||||||
if (constant) {
|
if (constant) {
|
||||||
if (constant->isSetter()) {
|
if (constant->isSetter()) {
|
||||||
return getSILFunctionTypeForConventions(DefaultSetterConventions());
|
return getSILFunctionTypeForConventions(DefaultSetterConventions());
|
||||||
} else if (constant->isInitAccessor()) {
|
}
|
||||||
|
if (constant->isInitAccessor()) {
|
||||||
return getSILFunctionTypeForInitAccessor(
|
return getSILFunctionTypeForInitAccessor(
|
||||||
TC, context, origType, substInterfaceType, extInfoBuilder,
|
TC, context, origType, substInterfaceType, extInfoBuilder,
|
||||||
DefaultSetterConventions(), *constant);
|
DefaultSetterConventions(), *constant);
|
||||||
}
|
}
|
||||||
|
if (constant->isBorrowAccessor()) {
|
||||||
|
return getSILFunctionTypeForConventions(
|
||||||
|
DefaultConventions(NormalParameterConvention::Guaranteed,
|
||||||
|
ResultConvention::Guaranteed));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return getSILFunctionTypeForConventions(
|
return getSILFunctionTypeForConventions(
|
||||||
DefaultConventions(NormalParameterConvention::Guaranteed));
|
DefaultConventions(NormalParameterConvention::Guaranteed));
|
||||||
|
|||||||
Reference in New Issue
Block a user