Add an option to get the native abstraction pattern of a storage decl.

For the most part, code should be working with the as-declared
abstraction pattern of the storage, because that's the pattern
produced by its accessors.  However, in the special case of an
accessor synthesized on demand to satisfy a protocol conformance,
that accessor will use the native abstraction pattern of the
declaration, and so the witness thunk that uses that accessor
must use that pattern when generating its access.

This doesn't matter today because the only on-demand synthesized
accessor is materializeForSet, and witnesses for materializeForSet
don't actually call the synthetic materializeForSet --- in fact,
nothing does.  But the modify accessor uses the otherwise-standard
pattern where the witness modify calls the concrete modify, and
that modify currently uses the native abstraction pattern.
This commit is contained in:
John McCall
2018-08-27 01:45:24 -04:00
parent 2fe4235ee8
commit e312f8ef4a
2 changed files with 18 additions and 8 deletions

View File

@@ -31,15 +31,18 @@
using namespace swift;
using namespace swift::Lowering;
AbstractionPattern TypeConverter::getAbstractionPattern(AbstractStorageDecl *decl) {
AbstractionPattern
TypeConverter::getAbstractionPattern(AbstractStorageDecl *decl,
bool isNonObjC) {
if (auto var = dyn_cast<VarDecl>(decl)) {
return getAbstractionPattern(var);
return getAbstractionPattern(var, isNonObjC);
} else {
return getAbstractionPattern(cast<SubscriptDecl>(decl));
return getAbstractionPattern(cast<SubscriptDecl>(decl), isNonObjC);
}
}
AbstractionPattern TypeConverter::getAbstractionPattern(SubscriptDecl *decl) {
AbstractionPattern
TypeConverter::getAbstractionPattern(SubscriptDecl *decl, bool isNonObjC) {
CanGenericSignature genericSig;
if (auto sig = decl->getGenericSignatureOfContext())
genericSig = sig->getCanonicalSignature();
@@ -67,7 +70,8 @@ static const clang::Type *getClangType(const clang::Decl *decl) {
return cast<clang::ObjCPropertyDecl>(decl)->getType().getTypePtr();
}
AbstractionPattern TypeConverter::getAbstractionPattern(VarDecl *var) {
AbstractionPattern
TypeConverter::getAbstractionPattern(VarDecl *var, bool isNonObjC) {
CanGenericSignature genericSig;
if (auto sig = var->getDeclContext()->getGenericSignatureOfContext())
genericSig = sig->getCanonicalSignature();
@@ -75,6 +79,9 @@ AbstractionPattern TypeConverter::getAbstractionPattern(VarDecl *var) {
CanType swiftType = var->getInterfaceType()
->getCanonicalType();
if (isNonObjC)
return AbstractionPattern(genericSig, swiftType);
if (auto clangDecl = var->getClangDecl()) {
auto clangType = getClangType(clangDecl);
auto contextType = var->getDeclContext()->mapTypeIntoContext(swiftType);