Generalize storage implementations to support generalized accessors.

The storage kind has been replaced with three separate "impl kinds",
one for each of the basic access kinds (read, write, and read/write).
This makes it far easier to mix-and-match implementations of different
accessors, as well as subtleties like implementing both a setter
and an independent read/write operation.

AccessStrategy has become a bit more explicit about how exactly the
access should be implemented.  For example, the accessor-based kinds
now carry the exact accessor intended to be used.  Also, I've shifted
responsibilities slightly between AccessStrategy and AccessSemantics
so that AccessSemantics::Ordinary can be used except in the sorts of
semantic-bypasses that accessor synthesis wants.  This requires
knowing the correct DC of the access when computing the access strategy;
the upshot is that SILGenFunction now needs a DC.

Accessor synthesis has been reworked so that only the declarations are
built immediately; body synthesis can be safely delayed out of the main
decl-checking path.  This caused a large number of ramifications,
especially for lazy properties, and greatly inflated the size of this
patch.  That is... really regrettable.  The impetus for changing this
was necessity: I needed to rework accessor synthesis to end its reliance
on distinctions like Stored vs. StoredWithTrivialAccessors, and those
fixes were exposing serious re-entrancy problems, and fixing that... well.
Breaking the fixes apart at this point would be a serious endeavor.
This commit is contained in:
John McCall
2018-06-27 03:28:39 -04:00
parent aef0253c75
commit 9bee3cac5a
66 changed files with 2721 additions and 1869 deletions

View File

@@ -481,32 +481,63 @@ static const Decl *getDeclForContext(const DeclContext *DC) {
namespace {
struct Accessors {
StorageKind Kind;
uint8_t ReadImpl, WriteImpl, ReadWriteImpl;
SmallVector<AccessorDecl *, 8> Decls;
};
} // end anonymous namespace
static StorageKind getRawStorageKind(AbstractStorageDecl::StorageKindTy kind) {
static uint8_t getRawReadImplKind(swift::ReadImplKind kind) {
switch (kind) {
#define CASE(KIND) case AbstractStorageDecl::KIND: return StorageKind::KIND
CASE(Stored);
CASE(StoredWithTrivialAccessors);
CASE(StoredWithObservers);
CASE(InheritedWithObservers);
CASE(Computed);
CASE(ComputedWithMutableAddress);
CASE(Addressed);
CASE(AddressedWithTrivialAccessors);
CASE(AddressedWithObservers);
#define CASE(KIND) \
case swift::ReadImplKind::KIND: \
return uint8_t(serialization::ReadImplKind::KIND);
CASE(Stored)
CASE(Get)
CASE(Inherited)
CASE(Address)
#undef CASE
}
llvm_unreachable("bad storage kind");
llvm_unreachable("bad kind");
}
static unsigned getRawWriteImplKind(swift::WriteImplKind kind) {
switch (kind) {
#define CASE(KIND) \
case swift::WriteImplKind::KIND: \
return uint8_t(serialization::WriteImplKind::KIND);
CASE(Immutable)
CASE(Stored)
CASE(Set)
CASE(StoredWithObservers)
CASE(InheritedWithObservers)
CASE(MutableAddress)
#undef CASE
}
llvm_unreachable("bad kind");
}
static unsigned getRawReadWriteImplKind(swift::ReadWriteImplKind kind) {
switch (kind) {
#define CASE(KIND) \
case swift::ReadWriteImplKind::KIND: \
return uint8_t(serialization::ReadWriteImplKind::KIND);
CASE(Immutable)
CASE(Stored)
CASE(MaterializeForSet)
CASE(MutableAddress)
CASE(MaterializeToTemporary)
#undef CASE
}
llvm_unreachable("bad kind");
}
static Accessors getAccessors(const AbstractStorageDecl *storage) {
Accessors accessors;
accessors.Kind = getRawStorageKind(storage->getStorageKind());
auto decls = storage->getAllAccessorFunctions();
auto impl = storage->getImplInfo();
accessors.ReadImpl = getRawReadImplKind(impl.getReadImpl());
accessors.WriteImpl = getRawWriteImplKind(impl.getWriteImpl());
accessors.ReadWriteImpl = getRawReadWriteImplKind(impl.getReadWriteImpl());
auto decls = storage->getAllAccessors();
accessors.Decls.append(decls.begin(), decls.end());
return accessors;
}
@@ -3129,7 +3160,9 @@ void Serializer::writeDecl(const Decl *D) {
var->hasNonPatternBindingInit(),
var->isGetterMutating(),
var->isSetterMutating(),
(unsigned) accessors.Kind,
accessors.ReadImpl,
accessors.WriteImpl,
accessors.ReadWriteImpl,
accessors.Decls.size(),
addTypeRef(ty),
addDeclRef(var->getOverriddenDecl()),
@@ -3354,7 +3387,9 @@ void Serializer::writeDecl(const Decl *D) {
subscript->isObjC(),
subscript->isGetterMutating(),
subscript->isSetterMutating(),
(unsigned) accessors.Kind,
accessors.ReadImpl,
accessors.WriteImpl,
accessors.ReadWriteImpl,
accessors.Decls.size(),
addGenericEnvironmentRef(
subscript->getGenericEnvironment()),