Skip to content

Commit feace85

Browse files
committed
Enhance SubscriptDecl to be a DeclContext, so it can hold its indices.
This is necessary for some other work I'm doing, which really wants paramdecls to have reasonable declcontexts. It is also a small step towards generic subscripts.
1 parent 6dcb6ef commit feace85

21 files changed

+104
-26
lines changed

include/swift/AST/Decl.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4239,7 +4239,7 @@ enum class ObjCSubscriptKind {
42394239
/// A given type can have multiple subscript declarations, so long as the
42404240
/// signatures (indices and element type) are distinct.
42414241
///
4242-
class SubscriptDecl : public AbstractStorageDecl {
4242+
class SubscriptDecl : public AbstractStorageDecl, public DeclContext {
42434243
SourceLoc ArrowLoc;
42444244
Pattern *Indices;
42454245
TypeLoc ElementTy;
@@ -4248,6 +4248,7 @@ class SubscriptDecl : public AbstractStorageDecl {
42484248
SubscriptDecl(DeclName Name, SourceLoc SubscriptLoc, Pattern *Indices,
42494249
SourceLoc ArrowLoc, TypeLoc ElementTy, DeclContext *Parent)
42504250
: AbstractStorageDecl(DeclKind::Subscript, Parent, Name, SubscriptLoc),
4251+
DeclContext(DeclContextKind::SubscriptDecl, Parent),
42514252
ArrowLoc(ArrowLoc), Indices(nullptr), ElementTy(ElementTy) {
42524253
setIndices(Indices);
42534254
}
@@ -4288,6 +4289,13 @@ class SubscriptDecl : public AbstractStorageDecl {
42884289
static bool classof(const Decl *D) {
42894290
return D->getKind() == DeclKind::Subscript;
42904291
}
4292+
4293+
static bool classof(const DeclContext *DC) {
4294+
return DC->getContextKind() == DeclContextKind::SubscriptDecl;
4295+
}
4296+
4297+
using DeclContext::operator new;
4298+
using Decl::getASTContext;
42914299
};
42924300

42934301
/// \brief Base class for function-like declarations.

include/swift/AST/DeclContext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ enum class DeclContextKind : uint8_t {
6666
AbstractClosureExpr,
6767
Initializer,
6868
TopLevelCodeDecl,
69+
SubscriptDecl,
6970
AbstractFunctionDecl,
7071
SerializedLocal,
7172
Last_LocalDeclContextKind = SerializedLocal,

lib/AST/ASTDumper.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,9 @@ static void printContext(raw_ostream &os, DeclContext *dc) {
986986
os << "deinit";
987987
break;
988988
}
989+
case DeclContextKind::SubscriptDecl:
990+
os << "subscript decl";
991+
break;
989992
}
990993
}
991994

lib/AST/ASTPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,6 +2388,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
23882388
case DeclContextKind::AbstractFunctionDecl:
23892389
visit(cast<AbstractFunctionDecl>(DC)->getType());
23902390
return;
2391+
2392+
case DeclContextKind::SubscriptDecl:
2393+
visit(cast<SubscriptDecl>(DC)->getType());
2394+
return;
23912395
}
23922396
}
23932397

lib/AST/Decl.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3432,10 +3432,18 @@ static bool isIntegralType(Type type) {
34323432
return false;
34333433
}
34343434

3435+
/// Set the DeclContext of any VarDecls in P to the specified DeclContext.
3436+
static void setDeclContextOfPatternVars(Pattern *P, DeclContext *DC) {
3437+
if (!P) return;
3438+
P->forEachVariable([&](VarDecl *VD) {
3439+
assert(isa<ParamDecl>(VD) && "Pattern variable is not a parameter?");
3440+
VD->setDeclContext(DC);
3441+
});
3442+
}
3443+
34353444
void SubscriptDecl::setIndices(Pattern *p) {
34363445
Indices = p;
3437-
3438-
// FIXME: What context should the indices patterns be in?
3446+
setDeclContextOfPatternVars(Indices, this);
34393447
}
34403448

34413449
Type SubscriptDecl::getIndicesType() const {
@@ -3881,15 +3889,6 @@ AbstractFunctionDecl *AbstractFunctionDecl::getOverriddenDecl() const {
38813889
return nullptr;
38823890
}
38833891

3884-
/// Set the DeclContext of any VarDecls in P to the specified DeclContext.
3885-
static void setDeclContextOfPatternVars(Pattern *P, DeclContext *DC) {
3886-
if (!P) return;
3887-
P->forEachVariable([&](VarDecl *VD) {
3888-
assert(isa<ParamDecl>(VD) && "Pattern variable is not a parameter?");
3889-
VD->setDeclContext(DC);
3890-
});
3891-
}
3892-
38933892
FuncDecl *FuncDecl::createImpl(ASTContext &Context,
38943893
SourceLoc StaticLoc,
38953894
StaticSpellingKind StaticSpelling,

lib/AST/DeclContext.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ DeclContext::isNominalTypeOrNominalTypeExtensionContext() const {
4646
case DeclContextKind::AbstractClosureExpr:
4747
case DeclContextKind::TopLevelCodeDecl:
4848
case DeclContextKind::AbstractFunctionDecl:
49+
case DeclContextKind::SubscriptDecl:
4950
case DeclContextKind::Initializer:
5051
case DeclContextKind::SerializedLocal:
5152
return nullptr;
@@ -107,6 +108,7 @@ Type DeclContext::getDeclaredTypeOfContext() const {
107108
case DeclContextKind::AbstractClosureExpr:
108109
case DeclContextKind::TopLevelCodeDecl:
109110
case DeclContextKind::AbstractFunctionDecl:
111+
case DeclContextKind::SubscriptDecl:
110112
case DeclContextKind::Initializer:
111113
case DeclContextKind::SerializedLocal:
112114
return Type();
@@ -144,6 +146,7 @@ Type DeclContext::getDeclaredTypeInContext() const {
144146
case DeclContextKind::AbstractClosureExpr:
145147
case DeclContextKind::TopLevelCodeDecl:
146148
case DeclContextKind::AbstractFunctionDecl:
149+
case DeclContextKind::SubscriptDecl:
147150
case DeclContextKind::Initializer:
148151
case DeclContextKind::SerializedLocal:
149152
return Type();
@@ -178,6 +181,7 @@ Type DeclContext::getDeclaredInterfaceType() const {
178181
case DeclContextKind::AbstractClosureExpr:
179182
case DeclContextKind::TopLevelCodeDecl:
180183
case DeclContextKind::AbstractFunctionDecl:
184+
case DeclContextKind::SubscriptDecl:
181185
case DeclContextKind::Initializer:
182186
case DeclContextKind::SerializedLocal:
183187
return Type();
@@ -205,6 +209,7 @@ GenericParamList *DeclContext::getGenericParamsOfContext() const {
205209
case DeclContextKind::SerializedLocal:
206210
case DeclContextKind::Initializer:
207211
case DeclContextKind::AbstractClosureExpr:
212+
case DeclContextKind::SubscriptDecl:
208213
// Closures and initializers can't themselves be generic, but they
209214
// can occur in generic contexts.
210215
continue;
@@ -245,6 +250,7 @@ GenericSignature *DeclContext::getGenericSignatureOfContext() const {
245250
case DeclContextKind::Initializer:
246251
case DeclContextKind::SerializedLocal:
247252
case DeclContextKind::AbstractClosureExpr:
253+
case DeclContextKind::SubscriptDecl:
248254
// Closures and initializers can't themselves be generic, but they
249255
// can occur in generic contexts.
250256
continue;
@@ -309,6 +315,7 @@ AbstractFunctionDecl *DeclContext::getInnermostMethodContext() {
309315
case DeclContextKind::Module:
310316
case DeclContextKind::NominalTypeDecl:
311317
case DeclContextKind::TopLevelCodeDecl:
318+
case DeclContextKind::SubscriptDecl:
312319
// Not in a method context.
313320
return nullptr;
314321
}
@@ -323,6 +330,7 @@ DeclContext *DeclContext::getInnermostTypeContext() {
323330
case DeclContextKind::Initializer:
324331
case DeclContextKind::TopLevelCodeDecl:
325332
case DeclContextKind::AbstractFunctionDecl:
333+
case DeclContextKind::SubscriptDecl:
326334
case DeclContextKind::SerializedLocal:
327335
Result = Result->getParent();
328336
continue;
@@ -355,6 +363,9 @@ Decl *DeclContext::getInnermostDeclarationDeclContext() {
355363
case DeclContextKind::AbstractFunctionDecl:
356364
return cast<AbstractFunctionDecl>(DC);
357365

366+
case DeclContextKind::SubscriptDecl:
367+
return cast<SubscriptDecl>(DC);
368+
358369
case DeclContextKind::NominalTypeDecl:
359370
return cast<NominalTypeDecl>(DC);
360371

@@ -408,6 +419,7 @@ bool DeclContext::isGenericContext() const {
408419
case DeclContextKind::Initializer:
409420
case DeclContextKind::AbstractClosureExpr:
410421
case DeclContextKind::SerializedLocal:
422+
case DeclContextKind::SubscriptDecl:
411423
// Check parent context.
412424
continue;
413425

@@ -506,6 +518,9 @@ DeclContext::isCascadingContextForLookup(bool functionsAreNonCascading) const {
506518
break;
507519
}
508520

521+
case DeclContextKind::SubscriptDecl:
522+
return false;
523+
509524
case DeclContextKind::Module:
510525
case DeclContextKind::FileUnit:
511526
return true;
@@ -553,6 +568,8 @@ bool DeclContext::walkContext(ASTWalker &Walker) {
553568
return cast<TopLevelCodeDecl>(this)->walk(Walker);
554569
case DeclContextKind::AbstractFunctionDecl:
555570
return cast<AbstractFunctionDecl>(this)->walk(Walker);
571+
case DeclContextKind::SubscriptDecl:
572+
return cast<SubscriptDecl>(this)->walk(Walker);
556573
case DeclContextKind::SerializedLocal:
557574
llvm_unreachable("walk is unimplemented for deserialized contexts");
558575
case DeclContextKind::Initializer:
@@ -626,6 +643,7 @@ unsigned DeclContext::printContext(raw_ostream &OS, unsigned indent) const {
626643
case DeclContextKind::AbstractFunctionDecl:
627644
Kind = "AbstractFunctionDecl";
628645
break;
646+
case DeclContextKind::SubscriptDecl: Kind = "SubscriptDecl"; break;
629647
}
630648
OS.indent(Depth*2 + indent) << "0x" << (void*)this << " " << Kind;
631649

@@ -673,6 +691,15 @@ unsigned DeclContext::printContext(raw_ostream &OS, unsigned indent) const {
673691
OS << " : (no type set)";
674692
break;
675693
}
694+
case DeclContextKind::SubscriptDecl: {
695+
auto *SD = cast<SubscriptDecl>(this);
696+
OS << " name=" << SD->getName();
697+
if (SD->hasType())
698+
OS << " : " << SD->getType();
699+
else
700+
OS << " : (no type set)";
701+
break;
702+
}
676703
case DeclContextKind::Initializer:
677704
switch (cast<Initializer>(this)->getInitializerKind()) {
678705
case InitializerKind::PatternBinding: {

lib/AST/DiagnosticEngine.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ void DiagnosticEngine::emitDiagnostic(const Diagnostic &diagnostic) {
558558
case DeclContextKind::Initializer:
559559
case DeclContextKind::AbstractClosureExpr:
560560
case DeclContextKind::AbstractFunctionDecl:
561+
case DeclContextKind::SubscriptDecl:
561562
break;
562563
}
563564

lib/AST/Mangle.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@ void Mangler::mangleContext(const DeclContext *ctx, BindGenerics shouldBind) {
299299
return mangleEntity(fn, ResilienceExpansion::Minimal, /*uncurry*/ 0);
300300
}
301301

302+
case DeclContextKind::SubscriptDecl:
303+
return mangleContext(ctx->getParent(), shouldBind);
304+
302305
case DeclContextKind::Initializer:
303306
switch (cast<Initializer>(ctx)->getInitializerKind()) {
304307
case InitializerKind::DefaultArgument: {

lib/AST/Module.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ void Module::lookupMember(SmallVectorImpl<ValueDecl*> &results,
458458
case DeclContextKind::Initializer:
459459
case DeclContextKind::TopLevelCodeDecl:
460460
case DeclContextKind::AbstractFunctionDecl:
461+
case DeclContextKind::SubscriptDecl:
461462
llvm_unreachable("This context does not support lookup.");
462463

463464
case DeclContextKind::FileUnit:

lib/AST/Verifier.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ struct ASTNodeBase {};
516516
case DeclContextKind::Initializer:
517517
case DeclContextKind::AbstractClosureExpr:
518518
case DeclContextKind::SerializedLocal:
519+
case DeclContextKind::SubscriptDecl:
519520
return nullptr;
520521

521522
case DeclContextKind::AbstractFunctionDecl:
@@ -1601,6 +1602,7 @@ struct ASTNodeBase {};
16011602
case DeclContextKind::Initializer:
16021603
case DeclContextKind::NominalTypeDecl:
16031604
case DeclContextKind::ExtensionDecl:
1605+
case DeclContextKind::SubscriptDecl:
16041606
return hasEnclosingFunctionContext(dc->getParent());
16051607
}
16061608
}
@@ -1616,7 +1618,7 @@ struct ASTNodeBase {};
16161618
// Make sure that there are no archetypes in the interface type.
16171619
if (VD->getDeclContext()->isTypeContext() &&
16181620
!hasEnclosingFunctionContext(VD->getDeclContext()) &&
1619-
!isa<ParamDecl>(VD) && /* because of subscripts */
1621+
// !isa<ParamDecl>(VD) && /* because of subscripts */
16201622
VD->getInterfaceType().findIf([](Type type) {
16211623
return type->is<ArchetypeType>();
16221624
})) {

lib/IDE/CodeCompletion.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,6 +1326,7 @@ static bool isTopLevelContext(const DeclContext *DC) {
13261326
case DeclContextKind::TopLevelCodeDecl:
13271327
return true;
13281328
case DeclContextKind::AbstractFunctionDecl:
1329+
case DeclContextKind::SubscriptDecl:
13291330
return false;
13301331
default:
13311332
continue;

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ llvm::DIScope *IRGenDebugInfo::getOrCreateContext(DeclContext *DC) {
562562
case DeclContextKind::SerializedLocal:
563563
case DeclContextKind::Initializer:
564564
case DeclContextKind::ExtensionDecl:
565+
case DeclContextKind::SubscriptDecl:
565566
return getOrCreateContext(DC->getParent());
566567

567568
case DeclContextKind::TopLevelCodeDecl:

lib/SIL/SILPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ static void printFullContext(const DeclContext *Context, raw_ostream &Buffer) {
212212
// FIXME
213213
Buffer << "<abstract function>";
214214
return;
215+
case DeclContextKind::SubscriptDecl:
216+
// FIXME
217+
Buffer << "<subscript>";
218+
return;
215219
}
216220
llvm_unreachable("bad decl context");
217221
}

lib/Sema/ITCNameLookup.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ bool IterativeTypeChecker::isQualifiedLookupInDeclContextSatisfied(
3535
case DeclContextKind::Initializer:
3636
case DeclContextKind::TopLevelCodeDecl:
3737
case DeclContextKind::SerializedLocal:
38+
case DeclContextKind::SubscriptDecl:
3839
llvm_unreachable("not a DeclContext that supports name lookup");
3940

4041
case DeclContextKind::Module:
@@ -131,6 +132,7 @@ bool IterativeTypeChecker::isUnqualifiedLookupInDeclContextSatisfied(
131132
switch (dc->getContextKind()) {
132133
case DeclContextKind::AbstractClosureExpr:
133134
case DeclContextKind::AbstractFunctionDecl:
135+
case DeclContextKind::SubscriptDecl:
134136
case DeclContextKind::Initializer:
135137
case DeclContextKind::TopLevelCodeDecl:
136138
case DeclContextKind::SerializedLocal:

lib/Sema/TypeCheckDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,6 +1599,7 @@ void TypeChecker::computeAccessibility(ValueDecl *D) {
15991599
case DeclContextKind::Initializer:
16001600
case DeclContextKind::TopLevelCodeDecl:
16011601
case DeclContextKind::AbstractFunctionDecl:
1602+
case DeclContextKind::SubscriptDecl:
16021603
D->setAccessibility(Accessibility::Private);
16031604
break;
16041605
case DeclContextKind::Module:
@@ -5769,6 +5770,7 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
57695770
case DeclContextKind::FileUnit:
57705771
case DeclContextKind::TopLevelCodeDecl:
57715772
case DeclContextKind::Initializer:
5773+
case DeclContextKind::SubscriptDecl:
57725774
llvm_unreachable("cannot have type params");
57735775

57745776
case DeclContextKind::NominalTypeDecl: {

lib/Sema/TypeCheckType.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ Type TypeChecker::resolveTypeInContext(
211211
// type within the context.
212212
if (auto nominal = dyn_cast<NominalTypeDecl>(typeDecl)) {
213213

214-
this->forceExternalDeclMembers(nominal);
214+
forceExternalDeclMembers(nominal);
215215

216216
if (!nominal->getGenericParams() || !isSpecialized) {
217217
for (DeclContext *dc = fromDC; dc; dc = dc->getParent()) {
@@ -240,6 +240,7 @@ Type TypeChecker::resolveTypeInContext(
240240

241241
case DeclContextKind::AbstractClosureExpr:
242242
case DeclContextKind::AbstractFunctionDecl:
243+
case DeclContextKind::SubscriptDecl:
243244
continue;
244245
case DeclContextKind::SerializedLocal:
245246
llvm_unreachable("should not be typechecking deserialized things");

lib/Serialization/Deserialization.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,8 @@ DeclContext *ModuleFile::getDeclContext(DeclContextID DCID) {
14411441
declContextOrOffset = ED;
14421442
} else if (auto AFD = dyn_cast<AbstractFunctionDecl>(D)) {
14431443
declContextOrOffset = AFD;
1444+
} else if (auto SD = dyn_cast<SubscriptDecl>(D)) {
1445+
declContextOrOffset = SD;
14441446
} else {
14451447
llvm_unreachable("Unknown Decl : DeclContext kind");
14461448
}
@@ -2934,23 +2936,19 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
29342936
if (declOrOffset.isComplete())
29352937
return declOrOffset;
29362938

2937-
Pattern *indices = maybeReadPattern();
2938-
assert(indices);
2939-
2940-
auto elemTy = TypeLoc::withoutLoc(getType(elemTypeID));
2941-
if (declOrOffset.isComplete())
2942-
return declOrOffset;
2943-
29442939
// Resolve the name ids.
29452940
SmallVector<Identifier, 2> argNames;
29462941
for (auto argNameID : argNameIDs)
29472942
argNames.push_back(getIdentifier(argNameID));
29482943

29492944
DeclName name(ctx, ctx.Id_subscript, argNames);
2950-
auto subscript = createDecl<SubscriptDecl>(name, SourceLoc(), indices,
2951-
SourceLoc(), elemTy, DC);
2945+
auto subscript = createDecl<SubscriptDecl>(name, SourceLoc(), nullptr,
2946+
SourceLoc(), TypeLoc(), DC);
29522947
declOrOffset = subscript;
29532948

2949+
subscript->setIndices(maybeReadPattern());
2950+
subscript->getElementTypeLoc() = TypeLoc::withoutLoc(getType(elemTypeID));
2951+
29542952
configureStorage(subscript, rawStorageKind,
29552953
getterID, setterID, materializeForSetID,
29562954
addressorID, mutableAddressorID, willSetID, didSetID);

0 commit comments

Comments
 (0)