mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #84180 from meg-gupta/borrowandmutatepr
Add preliminary support for borrow accessors
This commit is contained in:
@@ -2283,6 +2283,46 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// A physical component which involves calling borrow accessors.
|
||||
class BorrowAccessorComponent
|
||||
: public AccessorBasedComponent<PhysicalPathComponent> {
|
||||
public:
|
||||
BorrowAccessorComponent(AbstractStorageDecl *decl, SILDeclRef accessor,
|
||||
bool isSuper, bool isDirectAccessorUse,
|
||||
SubstitutionMap substitutions, CanType baseFormalType,
|
||||
LValueTypeData typeData,
|
||||
ArgumentList *argListForDiagnostics,
|
||||
PreparedArguments &&indices, bool isOnSelfParameter)
|
||||
: AccessorBasedComponent(BorrowMutateKind, decl, accessor, isSuper,
|
||||
isDirectAccessorUse, substitutions,
|
||||
baseFormalType, typeData, argListForDiagnostics,
|
||||
std::move(indices), isOnSelfParameter) {}
|
||||
|
||||
using AccessorBasedComponent::AccessorBasedComponent;
|
||||
|
||||
ManagedValue project(SILGenFunction &SGF, SILLocation loc,
|
||||
ManagedValue base) &&
|
||||
override {
|
||||
assert(SGF.isInFormalEvaluationScope() &&
|
||||
"offsetting l-value for modification without writeback scope");
|
||||
|
||||
ManagedValue result;
|
||||
|
||||
auto args = std::move(*this).prepareAccessorArgs(SGF, loc, base, Accessor);
|
||||
auto value = SGF.emitBorrowAccessor(
|
||||
loc, Accessor, Substitutions, std::move(args.base), IsSuper,
|
||||
IsDirectAccessorUse, std::move(args.Indices), IsOnSelfParameter);
|
||||
return value;
|
||||
}
|
||||
|
||||
void dump(raw_ostream &OS, unsigned indent) const override {
|
||||
printBase(OS, indent, "BorrowAccessorComponent");
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
static ManagedValue
|
||||
makeBaseConsumableMaterializedRValue(SILGenFunction &SGF,
|
||||
SILLocation loc, ManagedValue base) {
|
||||
@@ -3220,7 +3260,8 @@ LValue SILGenLValue::visitRec(Expr *e, SGFAccessKind accessKind,
|
||||
// a `borrow x` operator, the operator is used on the base here), we want to
|
||||
// apply the lvalue within a formal access to the original value instead of
|
||||
// an actual loaded copy.
|
||||
if (SILGenBorrowedBaseVisitor::isNonCopyableBaseBorrow(SGF, e)) {
|
||||
if (SILGenBorrowedBaseVisitor::isNonCopyableBaseBorrow(SGF, e) ||
|
||||
options.NeedsBorrow) {
|
||||
SILGenBorrowedBaseVisitor visitor(*this, SGF, orig);
|
||||
auto accessKind = SGFAccessKind::BorrowedObjectRead;
|
||||
assert(!e->getType()->is<LValueType>()
|
||||
@@ -3344,6 +3385,14 @@ namespace {
|
||||
AccessKind, FormalRValueType);
|
||||
return asImpl().emitUsingInitAccessor(accessor, isDirect, typeData);
|
||||
}
|
||||
case AccessorKind::Borrow: {
|
||||
auto typeData = getPhysicalStorageTypeData(
|
||||
SGF.getTypeExpansionContext(), SGF.SGM, AccessKind, Storage, Subs,
|
||||
FormalRValueType);
|
||||
return asImpl().emitUsingBorrowAccessor(accessor, isDirect, typeData);
|
||||
}
|
||||
case AccessorKind::Mutate:
|
||||
llvm_unreachable("mutate accessor is not yet implemented");
|
||||
}
|
||||
|
||||
llvm_unreachable("bad kind");
|
||||
@@ -3435,6 +3484,11 @@ void LValue::addNonMemberVarComponent(
|
||||
PreparedArguments(), /*isOnSelfParameter*/ false);
|
||||
}
|
||||
|
||||
void emitUsingBorrowAccessor(SILDeclRef accessor, bool isDirect,
|
||||
LValueTypeData typeData) {
|
||||
llvm_unreachable("borrow accessor is not implemented");
|
||||
}
|
||||
|
||||
void emitUsingGetterSetter(SILDeclRef accessor,
|
||||
bool isDirect,
|
||||
LValueTypeData typeData) {
|
||||
@@ -4116,6 +4170,14 @@ struct MemberStorageAccessEmitter : AccessEmitter<Impl, StorageType> {
|
||||
ArgListForDiagnostics, std::move(Indices), IsOnSelfParameter);
|
||||
}
|
||||
|
||||
void emitUsingBorrowAccessor(SILDeclRef accessor, bool isDirect,
|
||||
LValueTypeData typeData) {
|
||||
assert(!ActorIso);
|
||||
LV.add<BorrowAccessorComponent>(
|
||||
Storage, accessor, IsSuper, isDirect, Subs, BaseFormalType, typeData,
|
||||
ArgListForDiagnostics, std::move(Indices), IsOnSelfParameter);
|
||||
}
|
||||
|
||||
void emitUsingGetterSetter(SILDeclRef accessor,
|
||||
bool isDirect,
|
||||
LValueTypeData typeData) {
|
||||
@@ -5599,6 +5661,26 @@ ManagedValue SILGenFunction::emitBorrowedLValue(SILLocation loc,
|
||||
return value;
|
||||
}
|
||||
|
||||
std::optional<ManagedValue>
|
||||
SILGenFunction::tryEmitProjectedLValue(SILLocation loc, LValue &&src,
|
||||
TSanKind tsanKind) {
|
||||
assert(src.getAccessKind() == SGFAccessKind::BorrowedAddressRead ||
|
||||
src.getAccessKind() == SGFAccessKind::BorrowedObjectRead);
|
||||
ManagedValue base;
|
||||
PathComponent &&component =
|
||||
drillToLastComponent(loc, std::move(src), base, tsanKind);
|
||||
|
||||
if (component.getKind() != PathComponent::BorrowMutateKind &&
|
||||
component.getKind() != PathComponent::StructElementKind &&
|
||||
component.getKind() != PathComponent::TupleElementKind) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto value =
|
||||
drillIntoComponent(*this, loc, std::move(component), base, tsanKind);
|
||||
ASSERT(!value.hasCleanup());
|
||||
return value;
|
||||
}
|
||||
|
||||
ManagedValue SILGenFunction::emitConsumedLValue(SILLocation loc, LValue &&src,
|
||||
TSanKind tsanKind) {
|
||||
assert(isConsumeAccess(src.getAccessKind()));
|
||||
|
||||
Reference in New Issue
Block a user