[SILGen] NFC: Make adding new ReferenceStorageTypes easier

Failing at compile time is better than at runtime.
This commit is contained in:
David Zarzycki
2017-08-12 09:31:42 -04:00
parent 037ab30455
commit ac89b14700

View File

@@ -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,