Skip to content

Commit af47b21

Browse files
committed
[NFC] AST: Requestify checkInheritanceClause.
1 parent b969940 commit af47b21

File tree

5 files changed

+139
-8
lines changed

5 files changed

+139
-8
lines changed

include/swift/AST/Decl.h

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,13 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
559559
HasStubImplementation : 1
560560
);
561561

562-
SWIFT_INLINE_BITFIELD_EMPTY(TypeDecl, ValueDecl);
562+
SWIFT_INLINE_BITFIELD(TypeDecl, ValueDecl, 1+1,
563+
/// Whether the inheritance clause has been checked.
564+
HasCheckedInheritanceClause : 1,
565+
566+
/// Whether the inheritance clause checked successfully.
567+
HasValidInheritanceClause : 1
568+
);
563569

564570
SWIFT_INLINE_BITFIELD_FULL(GenericTypeParamDecl, TypeDecl, 16+16+1+1,
565571
: NumPadBits,
@@ -772,7 +778,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
772778
NumPathElements : 8
773779
);
774780

775-
SWIFT_INLINE_BITFIELD(ExtensionDecl, Decl, 4+1,
781+
SWIFT_INLINE_BITFIELD(ExtensionDecl, Decl, 4+1+1+1,
776782
/// An encoding of the default and maximum access level for this extension.
777783
/// The value 4 corresponds to AccessLevel::Public
778784
///
@@ -782,7 +788,13 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
782788
DefaultAndMaxAccessLevel : 4,
783789

784790
/// Whether there is are lazily-loaded conformances for this extension.
785-
HasLazyConformances : 1
791+
HasLazyConformances : 1,
792+
793+
/// Whether the inheritance clause has been checked.
794+
HasCheckedInheritanceClause : 1,
795+
796+
/// Whether the inheritance clause checked successfully.
797+
HasValidInheritanceClause : 1
786798
);
787799

788800
SWIFT_INLINE_BITFIELD(IfConfigDecl, Decl, 1,
@@ -1812,6 +1824,17 @@ class ExtensionDecl final : public GenericContext, public Decl,
18121824

18131825
void setInherited(ArrayRef<InheritedEntry> i) { Inherited = i; }
18141826

1827+
void setInheritanceClauseChecked(bool valid) {
1828+
assert(!Bits.ExtensionDecl.HasCheckedInheritanceClause);
1829+
Bits.ExtensionDecl.HasCheckedInheritanceClause = true;
1830+
Bits.ExtensionDecl.HasValidInheritanceClause = valid;
1831+
}
1832+
1833+
std::pair<bool, bool> hasCheckedInheritanceClause() const {
1834+
return {Bits.ExtensionDecl.HasCheckedInheritanceClause,
1835+
Bits.ExtensionDecl.HasValidInheritanceClause};
1836+
}
1837+
18151838
bool hasDefaultAccessLevel() const {
18161839
return Bits.ExtensionDecl.DefaultAndMaxAccessLevel != 0;
18171840
}
@@ -3226,8 +3249,11 @@ class TypeDecl : public ValueDecl {
32263249
protected:
32273250
TypeDecl(DeclKind K, llvm::PointerUnion<DeclContext *, ASTContext *> context,
32283251
Identifier name, SourceLoc NameLoc,
3229-
ArrayRef<InheritedEntry> inherited) :
3230-
ValueDecl(K, context, name, NameLoc), Inherited(inherited) {}
3252+
ArrayRef<InheritedEntry> inherited)
3253+
: ValueDecl(K, context, name, NameLoc), Inherited(inherited) {
3254+
Bits.TypeDecl.HasCheckedInheritanceClause = false;
3255+
Bits.TypeDecl.HasValidInheritanceClause = false;
3256+
}
32313257

32323258
friend class InheritedTypes;
32333259

@@ -3250,6 +3276,17 @@ class TypeDecl : public ValueDecl {
32503276

32513277
void setInherited(ArrayRef<InheritedEntry> i) { Inherited = i; }
32523278

3279+
void setInheritanceClauseChecked(bool valid) {
3280+
assert(!Bits.TypeDecl.HasCheckedInheritanceClause);
3281+
Bits.TypeDecl.HasCheckedInheritanceClause = true;
3282+
Bits.TypeDecl.HasValidInheritanceClause = valid;
3283+
}
3284+
3285+
std::pair<bool, bool> hasCheckedInheritanceClause() const {
3286+
return {Bits.TypeDecl.HasCheckedInheritanceClause,
3287+
Bits.TypeDecl.HasValidInheritanceClause};
3288+
}
3289+
32533290
struct CanBeInvertible {
32543291
/// Indicates how "strongly" a TypeDecl will conform to an invertible
32553292
/// protocol. Supports inequality comparisons and casts to bool.

include/swift/AST/TypeCheckRequests.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4845,6 +4845,30 @@ class ObjCRequirementMapRequest
48454845
bool isCached() const { return true; }
48464846
};
48474847

4848+
class InheritanceClauseRequest
4849+
: public SimpleRequest<
4850+
InheritanceClauseRequest,
4851+
ArrayRef<InheritedEntry>(
4852+
llvm::PointerUnion<const TypeDecl *, const ExtensionDecl *>),
4853+
RequestFlags::Cached> {
4854+
public:
4855+
using SimpleRequest::SimpleRequest;
4856+
4857+
private:
4858+
friend SimpleRequest;
4859+
4860+
ArrayRef<InheritedEntry>
4861+
evaluate(Evaluator &evaluator,
4862+
llvm::PointerUnion<const TypeDecl *, const ExtensionDecl *>
4863+
declUnion) const;
4864+
4865+
public:
4866+
// Cached in TypeDecl/ExtensionDecl.
4867+
bool isCached() const { return true; }
4868+
std::optional<ArrayRef<InheritedEntry>> getCachedResult() const;
4869+
void cacheResult(ArrayRef<InheritedEntry>) const;
4870+
};
4871+
48484872
#define SWIFT_TYPEID_ZONE TypeChecker
48494873
#define SWIFT_TYPEID_HEADER "swift/AST/TypeCheckerTypeIDZone.def"
48504874
#include "swift/Basic/DefineTypeIDZone.h"

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ SWIFT_REQUEST(TypeChecker, InheritedTypeRequest,
205205
Type(llvm::PointerUnion<const TypeDecl *, const ExtensionDecl *>,
206206
unsigned, TypeResolutionStage),
207207
SeparatelyCached, HasNearestLocation)
208+
SWIFT_REQUEST(TypeChecker, InheritanceClauseRequest,
209+
evaluator::SideEffect(llvm::PointerUnion<const TypeDecl *, const ExtensionDecl *>),
210+
Cached, NoLocationInfo)
208211
SWIFT_REQUEST(TypeChecker, InheritsSuperclassInitializersRequest,
209212
bool(ClassDecl *), SeparatelyCached, NoLocationInfo)
210213
SWIFT_REQUEST(TypeChecker, InitKindRequest,

lib/AST/Decl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,6 +1673,8 @@ ExtensionDecl::ExtensionDecl(SourceLoc extensionLoc,
16731673
{
16741674
Bits.ExtensionDecl.DefaultAndMaxAccessLevel = 0;
16751675
Bits.ExtensionDecl.HasLazyConformances = false;
1676+
Bits.ExtensionDecl.HasCheckedInheritanceClause = false;
1677+
Bits.ExtensionDecl.HasValidInheritanceClause = false;
16761678
setTrailingWhereClause(trailingWhereClause);
16771679
}
16781680

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,34 @@ static Type containsParameterizedProtocolType(Type inheritedTy) {
8787
return Type();
8888
}
8989

90+
static ArrayRef<InheritedEntry> checkInheritanceClauseEntries(
91+
llvm::PointerUnion<const TypeDecl *, const ExtensionDecl *> declUnion) {
92+
const Decl *decl = nullptr;
93+
if (const auto *td = declUnion.dyn_cast<const TypeDecl *>()) {
94+
decl = td;
95+
} else {
96+
decl = declUnion.get<const ExtensionDecl *>();
97+
}
98+
ASTContext &ctx = decl->getASTContext();
99+
return evaluateOrDefault(ctx.evaluator, InheritanceClauseRequest{declUnion},
100+
{});
101+
}
102+
103+
static void checkInheritanceClause(
104+
llvm::PointerUnion<const TypeDecl *, const ExtensionDecl *> declUnion) {
105+
auto entries = checkInheritanceClauseEntries(declUnion);
106+
(void)entries;
107+
}
108+
90109
/// Check the inheritance clause of a type declaration or extension thereof.
91110
///
92111
/// This routine performs detailed checking of the inheritance clause of the
93112
/// given type or extension. It need only be called within the primary source
94113
/// file.
95-
static void checkInheritanceClause(
96-
llvm::PointerUnion<const TypeDecl *, const ExtensionDecl *> declUnion) {
114+
ArrayRef<InheritedEntry> InheritanceClauseRequest::evaluate(
115+
Evaluator &evaluator,
116+
llvm::PointerUnion<const TypeDecl *, const ExtensionDecl *> declUnion)
117+
const {
97118
auto inheritedTypes = InheritedTypes(declUnion);
98119
auto inheritedClause = inheritedTypes.getEntries();
99120
const ExtensionDecl *ext = nullptr;
@@ -109,7 +130,7 @@ static void checkInheritanceClause(
109130
proto->getName())
110131
.highlight(SourceRange(inheritedClause.front().getSourceRange().Start,
111132
inheritedClause.back().getSourceRange().End));
112-
return;
133+
return {};
113134
}
114135
}
115136
} else {
@@ -341,6 +362,50 @@ static void checkInheritanceClause(
341362
inheritedTy);
342363
// FIXME: Note pointing to the declaration 'inheritedTy' references?
343364
}
365+
CheckSuppressions(declUnion, suppressedConformances, ctx).check();
366+
return inheritedTypes.getEntries();
367+
}
368+
369+
std::optional<ArrayRef<InheritedEntry>>
370+
InheritanceClauseRequest::getCachedResult() const {
371+
auto declUnion = std::get<0>(getStorage());
372+
if (const auto *td = declUnion.dyn_cast<const TypeDecl *>()) {
373+
auto checking = td->hasCheckedInheritanceClause();
374+
if (!checking.first)
375+
return std::nullopt;
376+
if (!checking.second)
377+
return {{}};
378+
} else {
379+
auto *ed = declUnion.get<const ExtensionDecl *>();
380+
auto checking = ed->hasCheckedInheritanceClause();
381+
if (!checking.first)
382+
return std::nullopt;
383+
if (!checking.second)
384+
return {{}};
385+
}
386+
return InheritedTypes(std::get<0>(getStorage())).getEntries();
387+
}
388+
389+
void InheritanceClauseRequest::cacheResult(
390+
ArrayRef<InheritedEntry> entries) const {
391+
auto declUnion = std::get<0>(getStorage());
392+
auto inheritanceClause = InheritedTypes(declUnion);
393+
if (inheritanceClause.size() == 0) {
394+
// Nothing to check, nothing to cache.
395+
assert(entries.size() == 0);
396+
return;
397+
}
398+
assert(entries.size() == 0 || entries.size() == inheritanceClause.size());
399+
// It's valid if it has entries.
400+
auto valid = entries.size() > 0;
401+
if (const auto *td = declUnion.dyn_cast<const TypeDecl *>()) {
402+
auto *mtd = const_cast<TypeDecl *>(td);
403+
mtd->setInheritanceClauseChecked(valid);
404+
} else {
405+
auto *ed = declUnion.get<const ExtensionDecl *>();
406+
auto *med = const_cast<ExtensionDecl *>(ed);
407+
med->setInheritanceClauseChecked(valid);
408+
}
344409
}
345410

346411
static void installCodingKeysIfNecessary(NominalTypeDecl *NTD) {

0 commit comments

Comments
 (0)