Skip to content

Commit fb58259

Browse files
committed
[Type Checker] Introduce a request for “overridden declarations”.
Introduce a new request kind to capture the computation of the set of overridden declarations of a given declaration, eliminating the stateful “setOverriddenDecls()” calls from the type checker.
1 parent c40ac22 commit fb58259

14 files changed

+208
-183
lines changed

include/swift/AST/Decl.h

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2195,6 +2195,8 @@ class ValueDecl : public Decl {
21952195
unsigned hasOverridden : 1;
21962196
} LazySemanticInfo;
21972197

2198+
friend class OverriddenDeclsRequest;
2199+
21982200
protected:
21992201
ValueDecl(DeclKind K,
22002202
llvm::PointerUnion<DeclContext *, ASTContext *> context,
@@ -2419,18 +2421,15 @@ class ValueDecl : public Decl {
24192421
ValueDecl *getOverriddenDecl() const;
24202422

24212423
/// Retrieve the declarations that this declaration overrides, if any.
2422-
ArrayRef<ValueDecl *> getOverriddenDecls() const;
2424+
SmallVector<ValueDecl *, 1> getOverriddenDecls() const;
24232425

24242426
/// Set the declaration that this declaration overrides.
24252427
void setOverriddenDecl(ValueDecl *overridden) {
2426-
(void)setOverriddenDecls(overridden);
2428+
setOverriddenDecls(overridden);
24272429
}
24282430

24292431
/// Set the declarations that this declaration overrides.
2430-
///
2431-
/// \returns the ASTContext-allocated version of the array of overridden
2432-
/// declarations.
2433-
ArrayRef<ValueDecl *> setOverriddenDecls(ArrayRef<ValueDecl *> overridden);
2432+
void setOverriddenDecls(ArrayRef<ValueDecl *> overridden);
24342433

24352434
/// Whether the overridden declarations have already been computed.
24362435
bool overriddenDeclsComputed() const;
@@ -2835,11 +2834,7 @@ class AssociatedTypeDecl : public AbstractTypeParamDecl {
28352834

28362835
/// Retrieve the set of associated types overridden by this associated
28372836
/// type.
2838-
CastArrayRefView<ValueDecl *, AssociatedTypeDecl>
2839-
getOverriddenDecls() const {
2840-
return CastArrayRefView<ValueDecl *, AssociatedTypeDecl>(
2841-
AbstractTypeParamDecl::getOverriddenDecls());
2842-
}
2837+
SmallVector<AssociatedTypeDecl *, 1> getOverriddenDecls() const;
28432838

28442839
SourceLoc getStartLoc() const { return KeywordLoc; }
28452840
SourceRange getSourceRange() const;

include/swift/AST/LazyResolver.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ class LazyResolver {
6060
/// consistency and provides the value a type.
6161
virtual void resolveDeclSignature(ValueDecl *VD) = 0;
6262

63-
/// Resolve the "overridden" declaration of the given declaration.
64-
virtual void resolveOverriddenDecl(ValueDecl *VD) = 0;
65-
6663
/// Resolve the "is Objective-C" bit for the given declaration.
6764
virtual void resolveIsObjC(ValueDecl *VD) = 0;
6865

include/swift/AST/TypeCheckRequests.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,35 @@ class EnumRawTypeRequest :
121121
void cacheResult(Type value) const;
122122
};
123123

124+
/// Request to determine the set of declarations that were are overridden
125+
/// by the given declaration.
126+
class OverriddenDeclsRequest
127+
: public SimpleRequest<OverriddenDeclsRequest,
128+
CacheKind::SeparatelyCached,
129+
SmallVector<ValueDecl *, 1>,
130+
ValueDecl *> {
131+
public:
132+
using SimpleRequest::SimpleRequest;
133+
134+
private:
135+
friend class SimpleRequest;
136+
137+
// Evaluation.
138+
SmallVector<ValueDecl *, 1> evaluate(Evaluator &evaluator,
139+
ValueDecl *decl) const;
140+
141+
public:
142+
// Cycle handling
143+
SmallVector<ValueDecl *, 1> breakCycle() const { return { }; }
144+
void diagnoseCycle(DiagnosticEngine &diags) const;
145+
void noteCycleStep(DiagnosticEngine &diags) const;
146+
147+
// Separate caching.
148+
bool isCached() const { return true; }
149+
Optional<SmallVector<ValueDecl *, 1>> getCachedResult() const;
150+
void cacheResult(SmallVector<ValueDecl *, 1> value) const;
151+
};
152+
124153
/// The zone number for the type checker.
125154
#define SWIFT_TYPE_CHECKER_REQUESTS_TYPEID_ZONE 10
126155

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
SWIFT_TYPEID(InheritedTypeRequest)
1818
SWIFT_TYPEID(SuperclassTypeRequest)
1919
SWIFT_TYPEID(EnumRawTypeRequest)
20+
SWIFT_TYPEID(OverriddenDeclsRequest)

lib/AST/ASTContext.cpp

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "swift/AST/RawComment.h"
3636
#include "swift/AST/SubstitutionMap.h"
3737
#include "swift/AST/SILLayout.h"
38+
#include "swift/AST/TypeCheckRequests.h"
3839
#include "swift/AST/TypeCheckerDebugConsumer.h"
3940
#include "swift/Basic/Compiler.h"
4041
#include "swift/Basic/SourceManager.h"
@@ -1594,53 +1595,45 @@ GenericEnvironment *ASTContext::getOrCreateCanonicalGenericEnvironment(
15941595
return env;
15951596
}
15961597

1597-
ArrayRef<ValueDecl *> ValueDecl::getOverriddenDecls() const {
1598-
// Check whether the overrides have already been computed.
1599-
if (LazySemanticInfo.hasOverriddenComputed) {
1600-
// If there are no overridden declarations (the common case), return.
1601-
if (!LazySemanticInfo.hasOverridden) return { };
1598+
Optional<SmallVector<ValueDecl *, 1>>
1599+
OverriddenDeclsRequest::getCachedResult() const {
1600+
auto decl = std::get<0>(getStorage());
1601+
if (!decl->LazySemanticInfo.hasOverriddenComputed)
1602+
return None;
16021603

1603-
// Look up the overridden declarations in the ASTContext.
1604-
auto known = getASTContext().getImpl().Overrides.find(this);
1605-
assert(known != getASTContext().getImpl().Overrides.end());
1606-
return known->second;
1607-
}
1604+
// If there are no overridden declarations (the common case), return.
1605+
SmallVector<ValueDecl *, 1> overridden;
1606+
if (!decl->LazySemanticInfo.hasOverridden) return overridden;
16081607

1609-
ASTContext &ctx = getASTContext();
1610-
if (auto resolver = ctx.getLazyResolver()) {
1611-
resolver->resolveOverriddenDecl(const_cast<ValueDecl *>(this));
1612-
assert(LazySemanticInfo.hasOverriddenComputed);
1613-
return getOverriddenDecls();
1614-
}
1615-
1616-
// FIXME: Shouldn't need this fallback.
1617-
return { };
1608+
// Retrieve the set of overrides from the ASTContext.
1609+
ASTContext &ctx = decl->getASTContext();
1610+
auto known = ctx.getImpl().Overrides.find(decl);
1611+
assert(known != ctx.getImpl().Overrides.end());
1612+
overridden.assign(known->second.begin(), known->second.end());
1613+
return overridden;
16181614
}
16191615

1620-
ArrayRef<ValueDecl *> ValueDecl::setOverriddenDecls(
1621-
ArrayRef<ValueDecl *> overridden) {
1622-
LazySemanticInfo.hasOverriddenComputed = true;
1616+
void OverriddenDeclsRequest::cacheResult(
1617+
SmallVector<ValueDecl *, 1> value) const {
1618+
auto decl = std::get<0>(getStorage());
1619+
decl->LazySemanticInfo.hasOverriddenComputed = true;
1620+
decl->LazySemanticInfo.hasOverridden = !value.empty();
16231621

1624-
// If the set of overridden declarations is empty, note that.
1625-
if (overridden.empty()) {
1626-
LazySemanticInfo.hasOverridden = false;
1627-
return { };
1628-
}
1622+
if (value.empty())
1623+
return;
16291624

16301625
// Sanity-check the declarations we were given.
1631-
for (auto decl : overridden) {
1632-
assert(decl->getKind() == this->getKind() &&
1626+
for (auto overriddenDecl : value) {
1627+
assert(overriddenDecl->getKind() == decl->getKind() &&
16331628
"Overridden decl kind mismatch");
1634-
if (auto func = dyn_cast<AbstractFunctionDecl>(decl))
1629+
if (auto func = dyn_cast<AbstractFunctionDecl>(overriddenDecl))
16351630
func->setIsOverridden();
16361631
}
16371632

16381633
// Record the overrides in the context.
1639-
auto &ctx = getASTContext();
1640-
LazySemanticInfo.hasOverridden = true;
1641-
auto overriddenCopy = ctx.AllocateCopy(overridden);
1642-
(void)ctx.getImpl().Overrides.insert({this, overriddenCopy});
1643-
return overriddenCopy;
1634+
auto &ctx = decl->getASTContext();
1635+
auto overriddenCopy = ctx.AllocateCopy(value);
1636+
(void)ctx.getImpl().Overrides.insert({decl, overriddenCopy});
16441637
}
16451638

16461639
bool ASTContext::canImportModule(std::pair<Identifier, SourceLoc> ModulePath) {

lib/AST/Decl.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2002,6 +2002,18 @@ CanType ValueDecl::getOverloadSignatureType() const {
20022002
return CanType();
20032003
}
20042004

2005+
SmallVector<ValueDecl *, 1> ValueDecl::getOverriddenDecls() const {
2006+
ASTContext &ctx = getASTContext();
2007+
return ctx.evaluator(OverriddenDeclsRequest{const_cast<ValueDecl *>(this)});
2008+
}
2009+
2010+
void ValueDecl::setOverriddenDecls(ArrayRef<ValueDecl *> overridden) {
2011+
SmallVector<ValueDecl *, 1> overriddenVec(overridden.begin(),
2012+
overridden.end());
2013+
OverriddenDeclsRequest request{const_cast<ValueDecl *>(this)};
2014+
request.cacheResult(overriddenVec);
2015+
}
2016+
20052017
bool ValueDecl::isObjC() const {
20062018
if (LazySemanticInfo.isObjCComputed)
20072019
return LazySemanticInfo.isObjC;
@@ -2842,6 +2854,15 @@ SourceRange AssociatedTypeDecl::getSourceRange() const {
28422854
return SourceRange(KeywordLoc, endLoc);
28432855
}
28442856

2857+
SmallVector<AssociatedTypeDecl *, 1>
2858+
AssociatedTypeDecl::getOverriddenDecls() const {
2859+
SmallVector<AssociatedTypeDecl *, 1> assocTypes;
2860+
for (auto decl : AbstractTypeParamDecl::getOverriddenDecls()) {
2861+
assocTypes.push_back(cast<AssociatedTypeDecl>(decl));
2862+
}
2863+
return assocTypes;
2864+
}
2865+
28452866
AssociatedTypeDecl *AssociatedTypeDecl::getAssociatedTypeAnchor() const {
28462867
auto overridden = getOverriddenDecls();
28472868

lib/AST/TypeCheckRequests.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,16 @@ void EnumRawTypeRequest::cacheResult(Type value) const {
146146
auto enumDecl = std::get<0>(getStorage());
147147
enumDecl->LazySemanticInfo.RawType.setPointerAndInt(value, true);
148148
}
149+
150+
//----------------------------------------------------------------------------//
151+
// Overridden decls computation.
152+
//----------------------------------------------------------------------------//
153+
void OverriddenDeclsRequest::diagnoseCycle(DiagnosticEngine &diags) const {
154+
auto decl = std::get<0>(getStorage());
155+
diags.diagnose(decl, diag::circular_reference);
156+
}
157+
158+
void OverriddenDeclsRequest::noteCycleStep(DiagnosticEngine &diags) const {
159+
auto decl = std::get<0>(getStorage());
160+
diags.diagnose(decl, diag::circular_reference_through);
161+
}

lib/ClangImporter/ImportDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6389,7 +6389,7 @@ void SwiftDeclConverter::recordObjCOverride(AbstractFunctionDecl *decl) {
63896389
// Make sure that we always set the overriden declarations.
63906390
SWIFT_DEFER {
63916391
if (!decl->overriddenDeclsComputed())
6392-
(void)decl->setOverriddenDecls({ });
6392+
decl->setOverriddenDecls({ });
63936393
};
63946394

63956395
// Figure out the class in which this method occurs.

lib/Sema/CodeSynthesis.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ void makeFinal(ASTContext &ctx, ValueDecl *D);
9898
void makeDynamic(ASTContext &ctx, ValueDecl *D);
9999

100100
// Implemented in TypeCheckerOverride.cpp
101-
bool checkOverrides(TypeChecker &TC, ValueDecl *decl);
101+
bool checkOverrides(ValueDecl *decl);
102102

103103
// These are implemented in CodeSynthesis.cpp.
104104
void maybeAddMaterializeForSet(AbstractStorageDecl *storage,

lib/Sema/TypeCheckDecl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2373,7 +2373,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23732373
}
23742374
}
23752375

2376-
if (!checkOverrides(TC, VD)) {
2376+
if (!checkOverrides(VD)) {
23772377
// If a property has an override attribute but does not override
23782378
// anything, complain.
23792379
auto overridden = VD->getOverriddenDecl();
@@ -2531,7 +2531,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
25312531
AccessControlChecker::checkAccessControl(TC, SD);
25322532
UsableFromInlineChecker::checkUsableFromInline(TC, SD);
25332533

2534-
if (!checkOverrides(TC, SD)) {
2534+
if (!checkOverrides(SD)) {
25352535
// If a subscript has an override attribute but does not override
25362536
// anything, complain.
25372537
if (auto *OA = SD->getAttrs().getAttribute<OverrideAttr>()) {
@@ -3033,7 +3033,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
30333033
AccessControlChecker::checkAccessControl(TC, FD);
30343034
UsableFromInlineChecker::checkUsableFromInline(TC, FD);
30353035

3036-
if (!checkOverrides(TC, FD)) {
3036+
if (!checkOverrides(FD)) {
30373037
// If a method has an 'override' keyword but does not
30383038
// override anything, complain.
30393039
if (auto *OA = FD->getAttrs().getAttribute<OverrideAttr>()) {
@@ -3174,7 +3174,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
31743174

31753175
// Check whether this initializer overrides an initializer in its
31763176
// superclass.
3177-
if (!checkOverrides(TC, CD)) {
3177+
if (!checkOverrides(CD)) {
31783178
// If an initializer has an override attribute but does not override
31793179
// anything or overrides something that doesn't need an 'override'
31803180
// keyword (e.g., a convenience initializer), complain.

0 commit comments

Comments
 (0)