Skip to content

Commit 013c4f1

Browse files
authored
Requestify whether a decl is an ABI compatible override (#27524)
Requestify whether a decl is an ABI compatible override
2 parents 078ef80 + 934d4d1 commit 013c4f1

File tree

5 files changed

+59
-58
lines changed

5 files changed

+59
-58
lines changed

Diff for: include/swift/AST/Decl.h

+2-18
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,7 @@ class alignas(1 << DeclAlignInBits) Decl {
340340
IsUserAccessible : 1
341341
);
342342

343-
SWIFT_INLINE_BITFIELD(AbstractStorageDecl, ValueDecl, 1+1+1,
344-
/// Whether a keypath component can directly reference this storage,
345-
/// or if it must use the overridden declaration instead.
346-
HasComputedValidKeyPathComponent : 1,
347-
ValidKeyPathComponent : 1,
348-
343+
SWIFT_INLINE_BITFIELD(AbstractStorageDecl, ValueDecl, 1,
349344
/// Whether this property is a type property (currently unfortunately
350345
/// called 'static').
351346
IsStatic : 1
@@ -4535,8 +4530,6 @@ class AbstractStorageDecl : public ValueDecl {
45354530
Bits.AbstractStorageDecl.IsStatic = IsStatic;
45364531
}
45374532

4538-
void computeIsValidKeyPathComponent();
4539-
45404533
OpaqueTypeDecl *OpaqueReturn = nullptr;
45414534

45424535
public:
@@ -4779,18 +4772,9 @@ class AbstractStorageDecl : public ValueDecl {
47794772
/// property from the given module?
47804773
bool isResilient(ModuleDecl *M, ResilienceExpansion expansion) const;
47814774

4782-
void setIsValidKeyPathComponent(bool value) {
4783-
Bits.AbstractStorageDecl.HasComputedValidKeyPathComponent = true;
4784-
Bits.AbstractStorageDecl.ValidKeyPathComponent = value;
4785-
}
4786-
47874775
/// True if the storage can be referenced by a keypath directly.
47884776
/// Otherwise, its override must be referenced.
4789-
bool isValidKeyPathComponent() const {
4790-
if (!Bits.AbstractStorageDecl.HasComputedValidKeyPathComponent)
4791-
const_cast<AbstractStorageDecl *>(this)->computeIsValidKeyPathComponent();
4792-
return Bits.AbstractStorageDecl.ValidKeyPathComponent;
4793-
}
4777+
bool isValidKeyPathComponent() const;
47944778

47954779
/// True if the storage exports a property descriptor for key paths in
47964780
/// other modules.

Diff for: include/swift/AST/TypeCheckRequests.h

+17
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,23 @@ class EnumRawValuesRequest :
12561256
void cacheResult(bool value) const;
12571257
};
12581258

1259+
class IsABICompatibleOverrideRequest
1260+
: public SimpleRequest<IsABICompatibleOverrideRequest, bool(ValueDecl *),
1261+
CacheKind::Cached> {
1262+
public:
1263+
using SimpleRequest::SimpleRequest;
1264+
1265+
private:
1266+
friend SimpleRequest;
1267+
1268+
// Evaluation.
1269+
llvm::Expected<bool> evaluate(Evaluator &evaluator, ValueDecl *decl) const;
1270+
1271+
public:
1272+
// Caching.
1273+
bool isCached() const { return true; }
1274+
};
1275+
12591276
// Allow AnyValue to compare two Type values, even though Type doesn't
12601277
// support ==.
12611278
template<>

Diff for: include/swift/AST/TypeCheckerTypeIDZone.def

+2
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,5 @@ SWIFT_REQUEST(TypeChecker, UnderlyingTypeRequest, Type(TypeAliasDecl *),
142142
SeparatelyCached, NoLocationInfo)
143143
SWIFT_REQUEST(TypeChecker, USRGenerationRequest, std::string(const ValueDecl *),
144144
Cached, NoLocationInfo)
145+
SWIFT_REQUEST(TypeChecker, IsABICompatibleOverrideRequest,
146+
bool(ValueDecl *), Cached, NoLocationInfo)

Diff for: lib/AST/Decl.cpp

+19-40
Original file line numberDiff line numberDiff line change
@@ -2141,32 +2141,15 @@ bool AbstractStorageDecl::isResilient(ModuleDecl *M,
21412141
llvm_unreachable("bad resilience expansion");
21422142
}
21432143

2144-
static bool isValidKeyPathComponent(AbstractStorageDecl *decl) {
2145-
// If this property or subscript is not an override, we can reference it
2146-
// from a keypath component.
2147-
auto base = decl->getOverriddenDecl();
2148-
if (!base)
2149-
return true;
2150-
2151-
// Otherwise, we can only reference it if the type is not ABI-compatible
2152-
// with the type of the base.
2153-
//
2154-
// If the type is ABI compatible with the type of the base, we have to
2155-
// reference the base instead.
2156-
auto baseInterfaceTy = base->getInterfaceType();
2157-
auto derivedInterfaceTy = decl->getInterfaceType();
2158-
2159-
auto selfInterfaceTy = decl->getDeclContext()->getDeclaredInterfaceType();
2160-
2161-
auto overrideInterfaceTy = selfInterfaceTy->adjustSuperclassMemberDeclType(
2162-
base, decl, baseInterfaceTy);
2163-
2164-
return !derivedInterfaceTy->matches(overrideInterfaceTy,
2165-
TypeMatchFlags::AllowABICompatible);
2166-
}
2167-
2168-
void AbstractStorageDecl::computeIsValidKeyPathComponent() {
2169-
setIsValidKeyPathComponent(::isValidKeyPathComponent(this));
2144+
bool AbstractStorageDecl::isValidKeyPathComponent() const {
2145+
// Check whether we're an ABI compatible override of another property. If we
2146+
// are, then the key path should refer to the base decl instead.
2147+
auto &ctx = getASTContext();
2148+
auto isABICompatibleOverride = evaluateOrDefault(
2149+
ctx.evaluator,
2150+
IsABICompatibleOverrideRequest{const_cast<AbstractStorageDecl *>(this)},
2151+
false);
2152+
return !isABICompatibleOverride;
21702153
}
21712154

21722155
bool AbstractStorageDecl::isGetterMutating() const {
@@ -6586,26 +6569,22 @@ static bool requiresNewVTableEntry(const AbstractFunctionDecl *decl) {
65866569
if (decl->isEffectiveLinkageMoreVisibleThan(base))
65876570
return true;
65886571

6589-
// If the method overrides something, we only need a new entry if the
6590-
// override has a more general AST type. However an abstraction
6591-
// change is OK; we don't want to add a whole new vtable entry just
6592-
// because an @in parameter because @owned, or whatever.
6593-
auto baseInterfaceTy = base->getInterfaceType();
6594-
auto derivedInterfaceTy = decl->getInterfaceType();
6595-
65966572
using Direction = ASTContext::OverrideGenericSignatureReqCheck;
65976573
if (!ctx.overrideGenericSignatureReqsSatisfied(
65986574
base, decl, Direction::BaseReqSatisfiedByDerived)) {
65996575
return true;
66006576
}
66016577

6602-
auto selfInterfaceTy = decl->getDeclContext()->getDeclaredInterfaceType();
6603-
6604-
auto overrideInterfaceTy = selfInterfaceTy->adjustSuperclassMemberDeclType(
6605-
base, decl, baseInterfaceTy);
6606-
6607-
return !derivedInterfaceTy->matches(overrideInterfaceTy,
6608-
TypeMatchFlags::AllowABICompatible);
6578+
// If this method is an ABI compatible override, then we don't need a new
6579+
// vtable entry. Otherwise, if it's not ABI compatible, for example if the
6580+
// base has a more general AST type, then we need a new entry. Note that an
6581+
// abstraction change is OK; we don't want to add a whole new vtable entry
6582+
// just because an @in parameter becomes @owned, or whatever.
6583+
auto isABICompatibleOverride = evaluateOrDefault(
6584+
ctx.evaluator,
6585+
IsABICompatibleOverrideRequest{const_cast<AbstractFunctionDecl *>(decl)},
6586+
false);
6587+
return !isABICompatibleOverride;
66096588
}
66106589

66116590
void AbstractFunctionDecl::computeNeedsNewVTableEntry() {

Diff for: lib/Sema/TypeCheckDeclOverride.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -1954,3 +1954,22 @@ OverriddenDeclsRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
19541954
return matcher.checkPotentialOverrides(matches,
19551955
OverrideCheckingAttempt::PerfectMatch);
19561956
}
1957+
1958+
llvm::Expected<bool>
1959+
IsABICompatibleOverrideRequest::evaluate(Evaluator &evaluator,
1960+
ValueDecl *decl) const {
1961+
auto base = decl->getOverriddenDecl();
1962+
if (!base)
1963+
return false;
1964+
1965+
auto baseInterfaceTy = base->getInterfaceType();
1966+
auto derivedInterfaceTy = decl->getInterfaceType();
1967+
1968+
auto selfInterfaceTy = decl->getDeclContext()->getDeclaredInterfaceType();
1969+
1970+
auto overrideInterfaceTy = selfInterfaceTy->adjustSuperclassMemberDeclType(
1971+
base, decl, baseInterfaceTy);
1972+
1973+
return derivedInterfaceTy->matches(overrideInterfaceTy,
1974+
TypeMatchFlags::AllowABICompatible);
1975+
}

0 commit comments

Comments
 (0)