Skip to content

Commit 764f148

Browse files
committed
[AST] Centralize the storage of the overridden declarations of a declaration.
Several kinds of declarations can override other declarations, but the computation and storage for these “overridden” declarations was scattered in at least 3 different places, with different resolution paths. Pull them all together into two bits of LazySemanticInfo in ValueDecl (“have we computed overrides?” and “are there any overrides?”), with a side table for the actual list of overrides. One side effect here is that the AST can now represent multiple overridden declarations, although only associated type declarations track this information. Start using LazyResolver::resolveOverriddenDecl() more consistently, unifying it with the separate path we had for associated type overrides. All of this is staging for a move to the request-evaluator for overridden declaration computation.
1 parent 730cf6c commit 764f148

File tree

7 files changed

+212
-226
lines changed

7 files changed

+212
-226
lines changed

include/swift/AST/Decl.h

Lines changed: 50 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "swift/AST/TypeAlignments.h"
3232
#include "swift/AST/TypeWalker.h"
3333
#include "swift/AST/Witness.h"
34+
#include "swift/Basic/ArrayRefView.h"
3435
#include "swift/Basic/Compiler.h"
3536
#include "swift/Basic/InlineBitfield.h"
3637
#include "swift/Basic/OptionalEnum.h"
@@ -319,10 +320,7 @@ class alignas(1 << DeclAlignInBits) Decl {
319320
IsUserAccessible : 1
320321
);
321322

322-
SWIFT_INLINE_BITFIELD(AbstractStorageDecl, ValueDecl, 1+1+1+1+1,
323-
/// Whether we are overridden later
324-
Overridden : 1,
325-
323+
SWIFT_INLINE_BITFIELD(AbstractStorageDecl, ValueDecl, 1+1+1+1,
326324
/// Whether the getter is mutating.
327325
IsGetterMutating : 1,
328326

@@ -582,11 +580,6 @@ class alignas(1 << DeclAlignInBits) Decl {
582580
Associativity : 2
583581
);
584582

585-
SWIFT_INLINE_BITFIELD(AssociatedTypeDecl, ValueDecl, 1+1,
586-
ComputedOverridden : 1,
587-
HasOverridden : 1
588-
);
589-
590583
SWIFT_INLINE_BITFIELD(ImportDecl, Decl, 3+8,
591584
ImportKind : 3,
592585

@@ -2181,6 +2174,13 @@ class ValueDecl : public Decl {
21812174

21822175
/// Whether this declaration is exposed to Objective-C.
21832176
unsigned isObjC : 1;
2177+
2178+
/// Whether the "overridden" declarations have been computed already.
2179+
unsigned hasOverriddenComputed : 1;
2180+
2181+
/// Whether there are any "overridden" declarations. The actual overridden
2182+
/// declarations are kept in a side table in the ASTContext.
2183+
unsigned hasOverridden : 1;
21842184
} LazySemanticInfo;
21852185

21862186
protected:
@@ -2193,6 +2193,8 @@ class ValueDecl : public Decl {
21932193
Bits.ValueDecl.IsUserAccessible = true;
21942194
LazySemanticInfo.isObjCComputed = false;
21952195
LazySemanticInfo.isObjC = false;
2196+
LazySemanticInfo.hasOverriddenComputed = false;
2197+
LazySemanticInfo.hasOverridden = false;
21962198
}
21972199

21982200
// MemberLookupTable borrows a bit from this type
@@ -2416,6 +2418,23 @@ class ValueDecl : public Decl {
24162418
/// Retrieve the declaration that this declaration overrides, if any.
24172419
ValueDecl *getOverriddenDecl() const;
24182420

2421+
/// Retrieve the declarations that this declaration overrides, if any.
2422+
ArrayRef<ValueDecl *> getOverriddenDecls() const;
2423+
2424+
/// Set the declaration that this declaration overrides.
2425+
void setOverriddenDecl(ValueDecl *overridden) {
2426+
(void)setOverriddenDecls(overridden);
2427+
}
2428+
2429+
/// 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);
2434+
2435+
/// Whether the overridden declarations have already been computed.
2436+
bool overriddenDeclsComputed() const;
2437+
24192438
/// Compute the untyped overload signature for this declaration.
24202439
OverloadSignature getOverloadSignature() const;
24212440

@@ -2809,23 +2828,19 @@ class AssociatedTypeDecl : public AbstractTypeParamDecl {
28092828
AssociatedTypeDecl *getAssociatedTypeAnchor() const;
28102829

28112830
/// Retrieve the (first) overridden associated type declaration, if any.
2812-
AssociatedTypeDecl *getOverriddenDecl() const;
2831+
AssociatedTypeDecl *getOverriddenDecl() const {
2832+
return cast_or_null<AssociatedTypeDecl>(
2833+
AbstractTypeParamDecl::getOverriddenDecl());
2834+
}
28132835

28142836
/// Retrieve the set of associated types overridden by this associated
28152837
/// type.
2816-
ArrayRef<AssociatedTypeDecl *> getOverriddenDecls() const;
2817-
2818-
/// Whether the overridden declarations have already been computed.
2819-
bool overriddenDeclsComputed() const {
2820-
return Bits.AssociatedTypeDecl.ComputedOverridden;
2838+
CastArrayRefView<ValueDecl *, AssociatedTypeDecl>
2839+
getOverriddenDecls() const {
2840+
return CastArrayRefView<ValueDecl *, AssociatedTypeDecl>(
2841+
AbstractTypeParamDecl::getOverriddenDecls());
28212842
}
28222843

2823-
/// Record the set of overridden declarations.
2824-
///
2825-
/// \returns the array recorded in the AST.
2826-
ArrayRef<AssociatedTypeDecl *> setOverriddenDecls(
2827-
ArrayRef<AssociatedTypeDecl *> overridden);
2828-
28292844
SourceLoc getStartLoc() const { return KeywordLoc; }
28302845
SourceRange getSourceRange() const;
28312846

@@ -4022,8 +4037,6 @@ class AbstractStorageDecl : public ValueDecl {
40224037
public:
40234038
static const size_t MaxNumAccessors = 255;
40244039
private:
4025-
AbstractStorageDecl *OverriddenDecl;
4026-
40274040
/// A record of the accessors for the declaration.
40284041
class alignas(1 << 3) AccessorRecord final :
40294042
private llvm::TrailingObjects<AccessorRecord, AccessorDecl*> {
@@ -4094,12 +4107,11 @@ class AbstractStorageDecl : public ValueDecl {
40944107
protected:
40954108
AbstractStorageDecl(DeclKind Kind, DeclContext *DC, DeclName Name,
40964109
SourceLoc NameLoc, bool supportsMutation)
4097-
: ValueDecl(Kind, DC, Name, NameLoc), OverriddenDecl(nullptr) {
4110+
: ValueDecl(Kind, DC, Name, NameLoc) {
40984111
Bits.AbstractStorageDecl.HasStorage = true;
40994112
Bits.AbstractStorageDecl.SupportsMutation = supportsMutation;
41004113
Bits.AbstractStorageDecl.IsGetterMutating = false;
41014114
Bits.AbstractStorageDecl.IsSetterMutating = true;
4102-
Bits.AbstractStorageDecl.Overridden = false;
41034115
}
41044116

41054117
void setSupportsMutationIfStillStored(bool supportsMutation) {
@@ -4294,28 +4306,9 @@ class AbstractStorageDecl : public ValueDecl {
42944306
getObjCSetterSelector(Identifier preferredName = Identifier()) const;
42954307

42964308
AbstractStorageDecl *getOverriddenDecl() const {
4297-
return OverriddenDecl;
4298-
}
4299-
void setOverriddenDecl(AbstractStorageDecl *over) {
4300-
// FIXME: Hack due to broken class circularity checking.
4301-
if (over == this) return;
4302-
OverriddenDecl = over;
4303-
over->setIsOverridden();
4309+
return cast_or_null<AbstractStorageDecl>(ValueDecl::getOverriddenDecl());
43044310
}
43054311

4306-
/// The declaration has been overridden in the module
4307-
///
4308-
/// Resolved during type checking
4309-
void setIsOverridden() {
4310-
Bits.AbstractStorageDecl.Overridden = true;
4311-
}
4312-
4313-
/// Whether the declaration is later overridden in the module
4314-
///
4315-
/// Overrides are resolved during type checking; only query this field after
4316-
/// the whole module has been checked
4317-
bool isOverridden() const { return Bits.AbstractStorageDecl.Overridden; }
4318-
43194312
/// Returns the location of 'override' keyword, if any.
43204313
SourceLoc getOverrideLoc() const;
43214314

@@ -5173,7 +5166,9 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
51735166
ParamDecl *getImplicitSelfDecl();
51745167

51755168
/// Retrieve the declaration that this method overrides, if any.
5176-
AbstractFunctionDecl *getOverriddenDecl() const;
5169+
AbstractFunctionDecl *getOverriddenDecl() const {
5170+
return cast_or_null<AbstractFunctionDecl>(ValueDecl::getOverriddenDecl());
5171+
}
51775172

51785173
/// Returns true if a function declaration overrides a given
51795174
/// method from its direct or indirect superclass.
@@ -5261,9 +5256,8 @@ class FuncDecl : public AbstractFunctionDecl {
52615256

52625257
/// \brief If this FuncDecl is an accessor for a property, this indicates
52635258
/// which property and what kind of accessor.
5264-
llvm::PointerUnion<FuncDecl *, BehaviorRecord *>
5265-
OverriddenOrBehaviorParamDecl;
5266-
OperatorDecl *Operator;
5259+
BehaviorRecord *BehaviorParamDecl = nullptr;
5260+
OperatorDecl *Operator = nullptr;
52675261

52685262
protected:
52695263
ParameterList **getParameterListBuffer(); // defined inline below
@@ -5282,9 +5276,7 @@ class FuncDecl : public AbstractFunctionDecl {
52825276
Name, NameLoc,
52835277
Throws, ThrowsLoc,
52845278
NumParameterLists, GenericParams),
5285-
StaticLoc(StaticLoc), FuncLoc(FuncLoc),
5286-
OverriddenOrBehaviorParamDecl(),
5287-
Operator(nullptr) {
5279+
StaticLoc(StaticLoc), FuncLoc(FuncLoc) {
52885280
assert(!Name.getBaseName().isSpecial());
52895281

52905282
Bits.FuncDecl.IsStatic =
@@ -5442,34 +5434,17 @@ class FuncDecl : public AbstractFunctionDecl {
54425434

54435435
/// Get the supertype method this method overrides, if any.
54445436
FuncDecl *getOverriddenDecl() const {
5445-
return OverriddenOrBehaviorParamDecl.dyn_cast<FuncDecl *>();
5437+
return cast_or_null<FuncDecl>(AbstractFunctionDecl::getOverriddenDecl());
54465438
}
5447-
void setOverriddenDecl(FuncDecl *over) {
5448-
// FIXME: Hack due to broken class circularity checking.
5449-
if (over == this) return;
54505439

5451-
// A function cannot be an override if it is also a derived global decl
5452-
// (since derived decls are at global scope).
5453-
assert((!OverriddenOrBehaviorParamDecl
5454-
|| OverriddenOrBehaviorParamDecl.get<FuncDecl*>() == over)
5455-
&& "function can only be one of override, derived, or behavior param");
5456-
OverriddenOrBehaviorParamDecl = over;
5457-
over->setIsOverridden();
5458-
}
5459-
54605440
/// Get the property behavior this function serves as a parameter for, if
54615441
/// any.
54625442
BehaviorRecord *getParamBehavior() const {
5463-
return OverriddenOrBehaviorParamDecl
5464-
.dyn_cast<BehaviorRecord *>();
5443+
return BehaviorParamDecl;
54655444
}
54665445

54675446
void setParamBehavior(BehaviorRecord *behavior) {
5468-
// Behavior param blocks cannot be overrides or derived.
5469-
assert((!OverriddenOrBehaviorParamDecl
5470-
|| OverriddenOrBehaviorParamDecl.is<BehaviorRecord *>())
5471-
&& "function can only be one of override, derived, or behavior param");
5472-
OverriddenOrBehaviorParamDecl = behavior;
5447+
BehaviorParamDecl = behavior;
54735448
}
54745449

54755450
OperatorDecl *getOperatorDecl() const {
@@ -5863,10 +5838,6 @@ class ConstructorDecl : public AbstractFunctionDecl {
58635838
/// inserted at the end of the initializer by SILGen.
58645839
Expr *CallToSuperInit = nullptr;
58655840

5866-
/// The constructor this overrides, which only makes sense when
5867-
/// both the overriding and the overridden constructors are abstract.
5868-
ConstructorDecl *OverriddenDecl = nullptr;
5869-
58705841
public:
58715842
ConstructorDecl(DeclName Name, SourceLoc ConstructorLoc,
58725843
OptionalTypeKind Failability, SourceLoc FailabilityLoc,
@@ -6019,13 +5990,9 @@ class ConstructorDecl : public AbstractFunctionDecl {
60195990
Bits.ConstructorDecl.HasStubImplementation = stub;
60205991
}
60215992

6022-
ConstructorDecl *getOverriddenDecl() const { return OverriddenDecl; }
6023-
void setOverriddenDecl(ConstructorDecl *over) {
6024-
// FIXME: Hack due to broken class circularity checking.
6025-
if (over == this) return;
6026-
6027-
OverriddenDecl = over;
6028-
over->setIsOverridden();
5993+
ConstructorDecl *getOverriddenDecl() const {
5994+
return cast_or_null<ConstructorDecl>(
5995+
AbstractFunctionDecl::getOverriddenDecl());
60295996
}
60305997

60315998
/// Determine whether this initializer falls into the special case for

0 commit comments

Comments
 (0)