Skip to content

Commit 2f0a3f2

Browse files
committed
SILGen: Refactor key path component lowering.
Factor out the code to lower an individual key path component to be independent of overall KeyPathExpr lowering, so that we can soon reuse the same code paths to build property descriptors for resilient properties. NFC intended.
1 parent dc83e87 commit 2f0a3f2

File tree

9 files changed

+322
-223
lines changed

9 files changed

+322
-223
lines changed

include/swift/AST/Expr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4909,7 +4909,7 @@ class KeyPathExpr : public Expr {
49094909
case Kind::OptionalForce:
49104910
case Kind::UnresolvedProperty:
49114911
case Kind::Property:
4912-
llvm_unreachable("no index expr for this kind");
4912+
return nullptr;
49134913
}
49144914
}
49154915

@@ -4942,7 +4942,7 @@ class KeyPathExpr : public Expr {
49424942
case Kind::OptionalForce:
49434943
case Kind::UnresolvedProperty:
49444944
case Kind::Property:
4945-
llvm_unreachable("no hashable conformances for this kind");
4945+
return {};
49464946
}
49474947
}
49484948

lib/SILGen/SILGen.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,53 @@ void SILGenModule::visitVarDecl(VarDecl *vd) {
11581158
if (auto setter = vd->getSetter())
11591159
emitFunction(setter);
11601160
}
1161+
1162+
tryEmitPropertyDescriptor(vd);
1163+
}
1164+
1165+
static bool doesPropertyNeedDescriptor(AbstractStorageDecl *decl) {
1166+
// The storage needs a descriptor if it sits at a module's ABI boundary,
1167+
// meaning it has public linkage.
1168+
1169+
// Any property that's potentially resilient should have accessors
1170+
// synthesized.
1171+
if (!decl->getGetter())
1172+
return false;
1173+
1174+
// TODO: If previous versions of an ABI-stable binary needed the descriptor,
1175+
// then we still do.
1176+
1177+
auto getter = SILDeclRef(decl->getGetter());
1178+
auto getterLinkage = getter.getLinkage(ForDefinition);
1179+
1180+
switch (getterLinkage) {
1181+
case SILLinkage::Public:
1182+
case SILLinkage::PublicNonABI:
1183+
// We may need a descriptor.
1184+
break;
1185+
1186+
case SILLinkage::Shared:
1187+
case SILLinkage::Private:
1188+
case SILLinkage::Hidden:
1189+
// Don't need a public descriptor.
1190+
return false;
1191+
1192+
case SILLinkage::HiddenExternal:
1193+
case SILLinkage::PrivateExternal:
1194+
case SILLinkage::PublicExternal:
1195+
case SILLinkage::SharedExternal:
1196+
llvm_unreachable("should be definition linkage?");
1197+
}
1198+
1199+
// TODO: We might be able to avoid a descriptor if the property is committed
1200+
// to being implemented a certain way, such as if it's promised to remain
1201+
// stored, or is computed with inlinable accessors, and can't change its
1202+
// mutability (because it's already promised to be mutable or fully immutable).
1203+
return true;
1204+
}
1205+
1206+
void SILGenModule::tryEmitPropertyDescriptor(AbstractStorageDecl *decl) {
1207+
// TODO
11611208
}
11621209

11631210
void SILGenModule::emitPropertyBehavior(VarDecl *vd) {

lib/SILGen/SILGen.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,12 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
333333
/// Emit a global initialization.
334334
void emitGlobalInitialization(PatternBindingDecl *initializer, unsigned elt);
335335

336+
SILDeclRef getGetterDeclRef(AbstractStorageDecl *decl);
337+
SILDeclRef getSetterDeclRef(AbstractStorageDecl *decl);
338+
SILDeclRef getAddressorDeclRef(AbstractStorageDecl *decl,
339+
AccessKind accessKind);
340+
SILDeclRef getMaterializeForSetDeclRef(AbstractStorageDecl *decl);
341+
336342
/// Known functions for bridging.
337343
SILDeclRef getStringToNSStringFn();
338344
SILDeclRef getNSStringToStringFn();
@@ -421,6 +427,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
421427
SubstitutionList
422428
getNonMemberVarDeclSubstitutions(VarDecl *var);
423429

430+
/// Emit a property descriptor for the given storage decl if it needs one.
431+
void tryEmitPropertyDescriptor(AbstractStorageDecl *decl);
432+
424433
private:
425434
/// Emit the deallocator for a class that uses the objc allocator.
426435
void emitObjCAllocatorDestructor(ClassDecl *cd, DestructorDecl *dd);

lib/SILGen/SILGenApply.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5015,7 +5015,7 @@ ArgumentSource SILGenFunction::prepareAccessorBaseArg(SILLocation loc,
50155015
return Preparer.prepare();
50165016
}
50175017

5018-
SILDeclRef SILGenFunction::getGetterDeclRef(AbstractStorageDecl *storage) {
5018+
SILDeclRef SILGenModule::getGetterDeclRef(AbstractStorageDecl *storage) {
50195019
auto *getter = storage->getGetter();
50205020
return SILDeclRef(getter, SILDeclRef::Kind::Func)
50215021
.asForeign(requiresForeignEntryPoint(getter));
@@ -5054,7 +5054,7 @@ emitGetAccessor(SILLocation loc, SILDeclRef get,
50545054
return emission.apply(c);
50555055
}
50565056

5057-
SILDeclRef SILGenFunction::getSetterDeclRef(AbstractStorageDecl *storage) {
5057+
SILDeclRef SILGenModule::getSetterDeclRef(AbstractStorageDecl *storage) {
50585058
auto *setter = storage->getSetter();
50595059
return SILDeclRef(setter, SILDeclRef::Kind::Func)
50605060
.asForeign(requiresForeignEntryPoint(setter));
@@ -5120,7 +5120,7 @@ void SILGenFunction::emitSetAccessor(SILLocation loc, SILDeclRef set,
51205120
}
51215121

51225122
SILDeclRef
5123-
SILGenFunction::getMaterializeForSetDeclRef(AbstractStorageDecl *storage) {
5123+
SILGenModule::getMaterializeForSetDeclRef(AbstractStorageDecl *storage) {
51245124
return SILDeclRef(storage->getMaterializeForSetFunc(),
51255125
SILDeclRef::Kind::Func);
51265126
}
@@ -5197,8 +5197,8 @@ emitMaterializeForSetAccessor(SILLocation loc, SILDeclRef materializeForSet,
51975197
optionalCallback, callbackStorage);
51985198
}
51995199

5200-
SILDeclRef SILGenFunction::getAddressorDeclRef(AbstractStorageDecl *storage,
5201-
AccessKind accessKind) {
5200+
SILDeclRef SILGenModule::getAddressorDeclRef(AbstractStorageDecl *storage,
5201+
AccessKind accessKind) {
52025202
FuncDecl *addressorFunc = storage->getAddressorForAccess(accessKind);
52035203
return SILDeclRef(addressorFunc, SILDeclRef::Kind::Func);
52045204
}

0 commit comments

Comments
 (0)