SIL: Addressors don't need vtable entries

In the old vtable emission code, IRGen would skip addressors,
but they had entries in the SILVTable. This is still correct
behavior, so skip addressors explicitly in SILVTableVisitor.

We never call addressors dynamically, only inside a getter,
setter or materializeForSet. When a property with addressors
is overridden we provide new getters and setters (which may
or may not statically dispatch to a peer addressor).
This commit is contained in:
Slava Pestov
2017-03-23 18:58:27 -07:00
parent 4c29a63a4b
commit aebf843dda
3 changed files with 69 additions and 10 deletions

View File

@@ -718,7 +718,12 @@ static void synthesizeTrivialGetter(FuncDecl *getter,
getter->setBody(BraceStmt::create(ctx, loc, returnStmt, loc, true));
maybeMarkTransparent(getter, storage, TC);
// Record the getter as an override, which can happen with addressors.
if (auto *baseASD = storage->getOverriddenDecl())
if (baseASD->isAccessibleFrom(storage->getDeclContext()))
getter->setOverriddenDecl(baseASD->getGetter());
// Register the accessor as an external decl if the storage was imported.
if (needsToBeRegisteredAsExternalDecl(storage))
TC.Context.addExternalDecl(getter);
@@ -740,6 +745,15 @@ static void synthesizeTrivialSetter(FuncDecl *setter,
maybeMarkTransparent(setter, storage, TC);
// Record the setter as an override, which can happen with addressors.
if (auto *baseASD = storage->getOverriddenDecl()) {
auto *baseSetter = baseASD->getSetter();
if (baseSetter != nullptr &&
baseASD->isSetterAccessibleFrom(storage->getDeclContext())) {
setter->setOverriddenDecl(baseSetter);
}
}
// Register the accessor as an external decl if the storage was imported.
if (needsToBeRegisteredAsExternalDecl(storage))
TC.Context.addExternalDecl(setter);
@@ -788,12 +802,8 @@ static void addTrivialAccessorsToStorage(AbstractStorageDecl *storage,
if (doesStorageNeedSetter(storage))
setter = createSetterPrototype(storage, setterValueParam, TC);
FuncDecl *materializeForSet = nullptr;
if (setter && DC->getAsNominalTypeOrNominalTypeExtensionContext())
materializeForSet = createMaterializeForSetPrototype(storage, setter, TC);
// Okay, we have both the getter and setter. Set them in VD.
storage->addTrivialAccessors(getter, setter, materializeForSet);
storage->addTrivialAccessors(getter, setter, nullptr);
bool isDynamic = (storage->isDynamic() && storage->isObjC());
if (isDynamic)
@@ -815,8 +825,8 @@ static void addTrivialAccessorsToStorage(AbstractStorageDecl *storage,
addMemberToContextIfNeeded(getter, DC, storage);
if (setter)
addMemberToContextIfNeeded(setter, DC, getter);
if (materializeForSet)
addMemberToContextIfNeeded(materializeForSet, DC, setter);
maybeAddMaterializeForSet(storage, TC);
}
/// Add a trivial setter and materializeForSet to a