mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[SILGen] NFC: Make adding new ReferenceStorageTypes easier
Failing at compile time is better than at runtime.
This commit is contained in:
@@ -2846,50 +2846,55 @@ static void emitUnloweredStoreOfCopy(SILGenBuilder &B, SILLocation loc,
|
||||
SILValue SILGenFunction::emitConversionToSemanticRValue(SILLocation loc,
|
||||
SILValue src,
|
||||
const TypeLowering &valueTL) {
|
||||
// Weak storage types are handled with their underlying type.
|
||||
assert(!src->getType().is<WeakStorageType>() &&
|
||||
"weak pointers are always the right optional types");
|
||||
auto storageType = src->getType();
|
||||
auto swiftStorageType = storageType.castTo<ReferenceStorageType>();
|
||||
|
||||
// For @unowned(safe) types, we need to generate a strong retain and
|
||||
// strip the unowned box.
|
||||
if (auto unownedType = src->getType().getAs<UnownedStorageType>()) {
|
||||
switch (swiftStorageType->getOwnership()) {
|
||||
case Ownership::Weak:
|
||||
// Weak storage types are handled with their underlying type.
|
||||
llvm_unreachable("weak pointers are always the right optional types");
|
||||
case Ownership::Strong:
|
||||
llvm_unreachable("strong reference storage type should be impossible");
|
||||
case Ownership::Unowned: {
|
||||
// For @unowned(safe) types, we need to generate a strong retain and
|
||||
// strip the unowned box.
|
||||
auto unownedType = storageType.castTo<UnownedStorageType>();
|
||||
assert(unownedType->isLoadable(ResilienceExpansion::Maximal));
|
||||
(void) unownedType;
|
||||
|
||||
return B.createCopyUnownedValue(loc, src);
|
||||
}
|
||||
|
||||
// For @unowned(unsafe) types, we need to strip the unmanaged box
|
||||
// and then do an (unsafe) retain.
|
||||
if (auto unmanagedType = src->getType().getAs<UnmanagedStorageType>()) {
|
||||
case Ownership::Unmanaged: {
|
||||
// For @unowned(unsafe) types, we need to strip the unmanaged box
|
||||
// and then do an (unsafe) retain.
|
||||
auto unmanagedType = storageType.castTo<UnmanagedStorageType>();
|
||||
auto result = B.createUnmanagedToRef(loc, src,
|
||||
SILType::getPrimitiveObjectType(unmanagedType.getReferentType()));
|
||||
// SEMANTIC ARC TODO: Does this need a cleanup?
|
||||
return B.createCopyValue(loc, result);
|
||||
}
|
||||
|
||||
llvm_unreachable("unexpected storage type that differs from type-of-rvalue");
|
||||
}
|
||||
}
|
||||
|
||||
ManagedValue SILGenFunction::emitConversionToSemanticRValue(
|
||||
SILLocation loc, ManagedValue src, const TypeLowering &valueTL) {
|
||||
// Weak storage types are handled with their underlying type.
|
||||
assert(!src.getType().is<WeakStorageType>() &&
|
||||
"weak pointers are always the right optional types");
|
||||
auto swiftStorageType = src.getType().castTo<ReferenceStorageType>();
|
||||
|
||||
// For @unowned(safe) types, we need to generate a strong retain and
|
||||
// strip the unowned box.
|
||||
if (src.getType().is<UnownedStorageType>()) {
|
||||
switch (swiftStorageType->getOwnership()) {
|
||||
case Ownership::Weak:
|
||||
// Weak storage types are handled with their underlying type.
|
||||
llvm_unreachable("weak pointers are always the right optional types");
|
||||
case Ownership::Strong:
|
||||
llvm_unreachable("strong reference storage type should be impossible");
|
||||
case Ownership::Unowned:
|
||||
// For @unowned(safe) types, we need to generate a strong retain and
|
||||
// strip the unowned box.
|
||||
return B.createCopyUnownedValue(loc, src);
|
||||
}
|
||||
|
||||
// For @unowned(unsafe) types, we need to strip the unmanaged box
|
||||
// and then do an (unsafe) retain.
|
||||
if (src.getType().is<UnmanagedStorageType>()) {
|
||||
case Ownership::Unmanaged:
|
||||
// For @unowned(unsafe) types, we need to strip the unmanaged box
|
||||
// and then do an (unsafe) retain.
|
||||
return B.createUnsafeCopyUnownedValue(loc, src);
|
||||
}
|
||||
|
||||
llvm_unreachable("unexpected storage type that differs from type-of-rvalue");
|
||||
}
|
||||
|
||||
/// Given that the type-of-rvalue differs from the type-of-storage,
|
||||
@@ -2900,15 +2905,18 @@ static SILValue emitLoadOfSemanticRValue(SILGenFunction &SGF,
|
||||
SILValue src,
|
||||
const TypeLowering &valueTL,
|
||||
IsTake_t isTake) {
|
||||
SILType storageType = src->getType();
|
||||
auto storageType = src->getType();
|
||||
auto swiftStorageType = storageType.castTo<ReferenceStorageType>();
|
||||
|
||||
// For @weak types, we need to create an Optional<T>.
|
||||
// Optional<T> is currently loadable, but it probably won't be forever.
|
||||
if (storageType.is<WeakStorageType>())
|
||||
switch (swiftStorageType->getOwnership()) {
|
||||
case Ownership::Weak: {
|
||||
// For @weak types, we need to create an Optional<T>.
|
||||
// Optional<T> is currently loadable, but it probably won't be forever.
|
||||
return SGF.B.createLoadWeak(loc, src, isTake);
|
||||
|
||||
// For @unowned(safe) types, we need to strip the unowned box.
|
||||
if (auto unownedType = storageType.getAs<UnownedStorageType>()) {
|
||||
}
|
||||
case Ownership::Unowned: {
|
||||
// For @unowned(safe) types, we need to strip the unowned box.
|
||||
auto unownedType = storageType.castTo<UnownedStorageType>();
|
||||
if (!unownedType->isLoadable(ResilienceExpansion::Maximal)) {
|
||||
return SGF.B.createLoadUnowned(loc, src, isTake);
|
||||
}
|
||||
@@ -2928,17 +2936,18 @@ static SILValue emitLoadOfSemanticRValue(SILGenFunction &SGF,
|
||||
SGF.B.createDestroyValue(loc, unownedValue);
|
||||
return strongValue;
|
||||
}
|
||||
|
||||
// For @unowned(unsafe) types, we need to strip the unmanaged box.
|
||||
if (auto unmanagedType = src->getType().getAs<UnmanagedStorageType>()) {
|
||||
case Ownership::Unmanaged: {
|
||||
// For @unowned(unsafe) types, we need to strip the unmanaged box.
|
||||
auto unmanagedType = storageType.castTo<UnmanagedStorageType>();
|
||||
auto value = SGF.B.createLoad(loc, src, LoadOwnershipQualifier::Trivial);
|
||||
auto result = SGF.B.createUnmanagedToRef(loc, value,
|
||||
SILType::getPrimitiveObjectType(unmanagedType.getReferentType()));
|
||||
// SEMANTIC ARC TODO: Does this need a cleanup?
|
||||
return SGF.B.createCopyValue(loc, result);
|
||||
}
|
||||
|
||||
llvm_unreachable("unexpected storage type that differs from type-of-rvalue");
|
||||
case Ownership::Strong:
|
||||
llvm_unreachable("strong reference storage type should be impossible");
|
||||
}
|
||||
}
|
||||
|
||||
/// Given that the type-of-rvalue differs from the type-of-storage,
|
||||
@@ -2951,20 +2960,22 @@ static void emitStoreOfSemanticRValue(SILGenFunction &SGF,
|
||||
const TypeLowering &valueTL,
|
||||
IsInitialization_t isInit) {
|
||||
auto storageType = dest->getType();
|
||||
auto swiftStorageType = storageType.castTo<ReferenceStorageType>();
|
||||
|
||||
// For @weak types, we need to break down an Optional<T> and then
|
||||
// emit the storeWeak ourselves.
|
||||
if (storageType.is<WeakStorageType>()) {
|
||||
switch (swiftStorageType->getOwnership()) {
|
||||
case Ownership::Weak: {
|
||||
// For @weak types, we need to break down an Optional<T> and then
|
||||
// emit the storeWeak ourselves.
|
||||
SGF.B.createStoreWeak(loc, value, dest, isInit);
|
||||
|
||||
// store_weak doesn't take ownership of the input, so cancel it out.
|
||||
SGF.B.emitDestroyValueOperation(loc, value);
|
||||
return;
|
||||
}
|
||||
|
||||
// For @unowned(safe) types, we need to enter the unowned box by
|
||||
// turning the strong retain into an unowned retain.
|
||||
if (auto unownedType = storageType.getAs<UnownedStorageType>()) {
|
||||
case Ownership::Unowned: {
|
||||
// For @unowned(safe) types, we need to enter the unowned box by
|
||||
// turning the strong retain into an unowned retain.
|
||||
auto unownedType = storageType.castTo<UnownedStorageType>();
|
||||
// FIXME: resilience
|
||||
if (!unownedType->isLoadable(ResilienceExpansion::Maximal)) {
|
||||
SGF.B.createStoreUnowned(loc, value, dest, isInit);
|
||||
@@ -2981,18 +2992,18 @@ static void emitStoreOfSemanticRValue(SILGenFunction &SGF,
|
||||
SGF.B.emitDestroyValueOperation(loc, value);
|
||||
return;
|
||||
}
|
||||
|
||||
// For @unowned(unsafe) types, we need to enter the unmanaged box and
|
||||
// release the strong retain.
|
||||
if (storageType.is<UnmanagedStorageType>()) {
|
||||
case Ownership::Unmanaged: {
|
||||
// For @unowned(unsafe) types, we need to enter the unmanaged box and
|
||||
// release the strong retain.
|
||||
auto unmanagedValue =
|
||||
SGF.B.createRefToUnmanaged(loc, value, storageType.getObjectType());
|
||||
emitUnloweredStoreOfCopy(SGF.B, loc, unmanagedValue, dest, isInit);
|
||||
SGF.B.emitDestroyValueOperation(loc, value);
|
||||
return;
|
||||
}
|
||||
|
||||
llvm_unreachable("unexpected storage type that differs from type-of-rvalue");
|
||||
case Ownership::Strong:
|
||||
llvm_unreachable("strong reference storage type should be impossible");
|
||||
}
|
||||
}
|
||||
|
||||
/// Load a value of the type-of-rvalue out of the given address as a
|
||||
@@ -3069,11 +3080,16 @@ SILValue SILGenFunction::emitConversionFromSemanticValue(SILLocation loc,
|
||||
if (semanticValue->getType() == storageType) {
|
||||
return semanticValue;
|
||||
}
|
||||
|
||||
// @weak types are never loadable, so we don't need to handle them here.
|
||||
|
||||
// For @unowned types, place into an unowned box.
|
||||
if (auto unownedType = storageType.getAs<UnownedStorageType>()) {
|
||||
|
||||
auto swiftStorageType = storageType.castTo<ReferenceStorageType>();
|
||||
switch (swiftStorageType->getOwnership()) {
|
||||
case Ownership::Weak:
|
||||
llvm_unreachable("weak types are never loadable");
|
||||
case Ownership::Strong:
|
||||
llvm_unreachable("strong reference storage type should be impossible");
|
||||
case Ownership::Unowned: {
|
||||
// For @unowned types, place into an unowned box.
|
||||
auto unownedType = storageType.castTo<UnownedStorageType>();
|
||||
assert(unownedType->isLoadable(ResilienceExpansion::Maximal));
|
||||
(void) unownedType;
|
||||
|
||||
@@ -3082,16 +3098,14 @@ SILValue SILGenFunction::emitConversionFromSemanticValue(SILLocation loc,
|
||||
B.emitDestroyValueOperation(loc, semanticValue);
|
||||
return unowned;
|
||||
}
|
||||
|
||||
// For @unmanaged types, place into an unmanaged box.
|
||||
if (storageType.is<UnmanagedStorageType>()) {
|
||||
case Ownership::Unmanaged: {
|
||||
// For @unmanaged types, place into an unmanaged box.
|
||||
SILValue unmanaged =
|
||||
B.createRefToUnmanaged(loc, semanticValue, storageType);
|
||||
B.emitDestroyValueOperation(loc, semanticValue);
|
||||
return unmanaged;
|
||||
}
|
||||
|
||||
llvm_unreachable("unexpected storage type that differs from type-of-rvalue");
|
||||
}
|
||||
}
|
||||
|
||||
static void emitTsanInoutAccess(SILGenFunction &SGF, SILLocation loc,
|
||||
|
||||
Reference in New Issue
Block a user