Skip to content

Commit

Permalink
Enhance SubscriptDecl to be a DeclContext, so it can hold its indices.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lattner committed Dec 31, 2015
1 parent 6dcb6ef commit feace85
Show file tree
Hide file tree
Showing 21 changed files with 104 additions and 26 deletions.
10 changes: 9 additions & 1 deletion include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -4239,7 +4239,7 @@ enum class ObjCSubscriptKind {
/// A given type can have multiple subscript declarations, so long as the
/// signatures (indices and element type) are distinct.
///
class SubscriptDecl : public AbstractStorageDecl {
class SubscriptDecl : public AbstractStorageDecl, public DeclContext {
SourceLoc ArrowLoc;
Pattern *Indices;
TypeLoc ElementTy;
Expand All @@ -4248,6 +4248,7 @@ class SubscriptDecl : public AbstractStorageDecl {
SubscriptDecl(DeclName Name, SourceLoc SubscriptLoc, Pattern *Indices,
SourceLoc ArrowLoc, TypeLoc ElementTy, DeclContext *Parent)
: AbstractStorageDecl(DeclKind::Subscript, Parent, Name, SubscriptLoc),
DeclContext(DeclContextKind::SubscriptDecl, Parent),
ArrowLoc(ArrowLoc), Indices(nullptr), ElementTy(ElementTy) {
setIndices(Indices);
}
Expand Down Expand Up @@ -4288,6 +4289,13 @@ class SubscriptDecl : public AbstractStorageDecl {
static bool classof(const Decl *D) {
return D->getKind() == DeclKind::Subscript;
}

static bool classof(const DeclContext *DC) {
return DC->getContextKind() == DeclContextKind::SubscriptDecl;
}

using DeclContext::operator new;
using Decl::getASTContext;
};

/// \brief Base class for function-like declarations.
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/DeclContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ enum class DeclContextKind : uint8_t {
AbstractClosureExpr,
Initializer,
TopLevelCodeDecl,
SubscriptDecl,
AbstractFunctionDecl,
SerializedLocal,
Last_LocalDeclContextKind = SerializedLocal,
Expand Down
3 changes: 3 additions & 0 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,9 @@ static void printContext(raw_ostream &os, DeclContext *dc) {
os << "deinit";
break;
}
case DeclContextKind::SubscriptDecl:
os << "subscript decl";
break;
}
}

Expand Down
4 changes: 4 additions & 0 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2388,6 +2388,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
case DeclContextKind::AbstractFunctionDecl:
visit(cast<AbstractFunctionDecl>(DC)->getType());
return;

case DeclContextKind::SubscriptDecl:
visit(cast<SubscriptDecl>(DC)->getType());
return;
}
}

Expand Down
21 changes: 10 additions & 11 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3432,10 +3432,18 @@ static bool isIntegralType(Type type) {
return false;
}

/// Set the DeclContext of any VarDecls in P to the specified DeclContext.
static void setDeclContextOfPatternVars(Pattern *P, DeclContext *DC) {
if (!P) return;
P->forEachVariable([&](VarDecl *VD) {
assert(isa<ParamDecl>(VD) && "Pattern variable is not a parameter?");
VD->setDeclContext(DC);
});
}

void SubscriptDecl::setIndices(Pattern *p) {
Indices = p;

// FIXME: What context should the indices patterns be in?
setDeclContextOfPatternVars(Indices, this);
}

Type SubscriptDecl::getIndicesType() const {
Expand Down Expand Up @@ -3881,15 +3889,6 @@ AbstractFunctionDecl *AbstractFunctionDecl::getOverriddenDecl() const {
return nullptr;
}

/// Set the DeclContext of any VarDecls in P to the specified DeclContext.
static void setDeclContextOfPatternVars(Pattern *P, DeclContext *DC) {
if (!P) return;
P->forEachVariable([&](VarDecl *VD) {
assert(isa<ParamDecl>(VD) && "Pattern variable is not a parameter?");
VD->setDeclContext(DC);
});
}

FuncDecl *FuncDecl::createImpl(ASTContext &Context,
SourceLoc StaticLoc,
StaticSpellingKind StaticSpelling,
Expand Down
27 changes: 27 additions & 0 deletions lib/AST/DeclContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ DeclContext::isNominalTypeOrNominalTypeExtensionContext() const {
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
case DeclContextKind::Initializer:
case DeclContextKind::SerializedLocal:
return nullptr;
Expand Down Expand Up @@ -107,6 +108,7 @@ Type DeclContext::getDeclaredTypeOfContext() const {
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
case DeclContextKind::Initializer:
case DeclContextKind::SerializedLocal:
return Type();
Expand Down Expand Up @@ -144,6 +146,7 @@ Type DeclContext::getDeclaredTypeInContext() const {
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
case DeclContextKind::Initializer:
case DeclContextKind::SerializedLocal:
return Type();
Expand Down Expand Up @@ -178,6 +181,7 @@ Type DeclContext::getDeclaredInterfaceType() const {
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
case DeclContextKind::Initializer:
case DeclContextKind::SerializedLocal:
return Type();
Expand Down Expand Up @@ -205,6 +209,7 @@ GenericParamList *DeclContext::getGenericParamsOfContext() const {
case DeclContextKind::SerializedLocal:
case DeclContextKind::Initializer:
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::SubscriptDecl:
// Closures and initializers can't themselves be generic, but they
// can occur in generic contexts.
continue;
Expand Down Expand Up @@ -245,6 +250,7 @@ GenericSignature *DeclContext::getGenericSignatureOfContext() const {
case DeclContextKind::Initializer:
case DeclContextKind::SerializedLocal:
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::SubscriptDecl:
// Closures and initializers can't themselves be generic, but they
// can occur in generic contexts.
continue;
Expand Down Expand Up @@ -309,6 +315,7 @@ AbstractFunctionDecl *DeclContext::getInnermostMethodContext() {
case DeclContextKind::Module:
case DeclContextKind::NominalTypeDecl:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::SubscriptDecl:
// Not in a method context.
return nullptr;
}
Expand All @@ -323,6 +330,7 @@ DeclContext *DeclContext::getInnermostTypeContext() {
case DeclContextKind::Initializer:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
case DeclContextKind::SerializedLocal:
Result = Result->getParent();
continue;
Expand Down Expand Up @@ -355,6 +363,9 @@ Decl *DeclContext::getInnermostDeclarationDeclContext() {
case DeclContextKind::AbstractFunctionDecl:
return cast<AbstractFunctionDecl>(DC);

case DeclContextKind::SubscriptDecl:
return cast<SubscriptDecl>(DC);

case DeclContextKind::NominalTypeDecl:
return cast<NominalTypeDecl>(DC);

Expand Down Expand Up @@ -408,6 +419,7 @@ bool DeclContext::isGenericContext() const {
case DeclContextKind::Initializer:
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::SerializedLocal:
case DeclContextKind::SubscriptDecl:
// Check parent context.
continue;

Expand Down Expand Up @@ -506,6 +518,9 @@ DeclContext::isCascadingContextForLookup(bool functionsAreNonCascading) const {
break;
}

case DeclContextKind::SubscriptDecl:
return false;

case DeclContextKind::Module:
case DeclContextKind::FileUnit:
return true;
Expand Down Expand Up @@ -553,6 +568,8 @@ bool DeclContext::walkContext(ASTWalker &Walker) {
return cast<TopLevelCodeDecl>(this)->walk(Walker);
case DeclContextKind::AbstractFunctionDecl:
return cast<AbstractFunctionDecl>(this)->walk(Walker);
case DeclContextKind::SubscriptDecl:
return cast<SubscriptDecl>(this)->walk(Walker);
case DeclContextKind::SerializedLocal:
llvm_unreachable("walk is unimplemented for deserialized contexts");
case DeclContextKind::Initializer:
Expand Down Expand Up @@ -626,6 +643,7 @@ unsigned DeclContext::printContext(raw_ostream &OS, unsigned indent) const {
case DeclContextKind::AbstractFunctionDecl:
Kind = "AbstractFunctionDecl";
break;
case DeclContextKind::SubscriptDecl: Kind = "SubscriptDecl"; break;
}
OS.indent(Depth*2 + indent) << "0x" << (void*)this << " " << Kind;

Expand Down Expand Up @@ -673,6 +691,15 @@ unsigned DeclContext::printContext(raw_ostream &OS, unsigned indent) const {
OS << " : (no type set)";
break;
}
case DeclContextKind::SubscriptDecl: {
auto *SD = cast<SubscriptDecl>(this);
OS << " name=" << SD->getName();
if (SD->hasType())
OS << " : " << SD->getType();
else
OS << " : (no type set)";
break;
}
case DeclContextKind::Initializer:
switch (cast<Initializer>(this)->getInitializerKind()) {
case InitializerKind::PatternBinding: {
Expand Down
1 change: 1 addition & 0 deletions lib/AST/DiagnosticEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ void DiagnosticEngine::emitDiagnostic(const Diagnostic &diagnostic) {
case DeclContextKind::Initializer:
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
break;
}

Expand Down
3 changes: 3 additions & 0 deletions lib/AST/Mangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,9 @@ void Mangler::mangleContext(const DeclContext *ctx, BindGenerics shouldBind) {
return mangleEntity(fn, ResilienceExpansion::Minimal, /*uncurry*/ 0);
}

case DeclContextKind::SubscriptDecl:
return mangleContext(ctx->getParent(), shouldBind);

case DeclContextKind::Initializer:
switch (cast<Initializer>(ctx)->getInitializerKind()) {
case InitializerKind::DefaultArgument: {
Expand Down
1 change: 1 addition & 0 deletions lib/AST/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ void Module::lookupMember(SmallVectorImpl<ValueDecl*> &results,
case DeclContextKind::Initializer:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
llvm_unreachable("This context does not support lookup.");

case DeclContextKind::FileUnit:
Expand Down
4 changes: 3 additions & 1 deletion lib/AST/Verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ struct ASTNodeBase {};
case DeclContextKind::Initializer:
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::SerializedLocal:
case DeclContextKind::SubscriptDecl:
return nullptr;

case DeclContextKind::AbstractFunctionDecl:
Expand Down Expand Up @@ -1601,6 +1602,7 @@ struct ASTNodeBase {};
case DeclContextKind::Initializer:
case DeclContextKind::NominalTypeDecl:
case DeclContextKind::ExtensionDecl:
case DeclContextKind::SubscriptDecl:
return hasEnclosingFunctionContext(dc->getParent());
}
}
Expand All @@ -1616,7 +1618,7 @@ struct ASTNodeBase {};
// Make sure that there are no archetypes in the interface type.
if (VD->getDeclContext()->isTypeContext() &&
!hasEnclosingFunctionContext(VD->getDeclContext()) &&
!isa<ParamDecl>(VD) && /* because of subscripts */
// !isa<ParamDecl>(VD) && /* because of subscripts */
VD->getInterfaceType().findIf([](Type type) {
return type->is<ArchetypeType>();
})) {
Expand Down
1 change: 1 addition & 0 deletions lib/IDE/CodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1326,6 +1326,7 @@ static bool isTopLevelContext(const DeclContext *DC) {
case DeclContextKind::TopLevelCodeDecl:
return true;
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
return false;
default:
continue;
Expand Down
1 change: 1 addition & 0 deletions lib/IRGen/IRGenDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ llvm::DIScope *IRGenDebugInfo::getOrCreateContext(DeclContext *DC) {
case DeclContextKind::SerializedLocal:
case DeclContextKind::Initializer:
case DeclContextKind::ExtensionDecl:
case DeclContextKind::SubscriptDecl:
return getOrCreateContext(DC->getParent());

case DeclContextKind::TopLevelCodeDecl:
Expand Down
4 changes: 4 additions & 0 deletions lib/SIL/SILPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ static void printFullContext(const DeclContext *Context, raw_ostream &Buffer) {
// FIXME
Buffer << "<abstract function>";
return;
case DeclContextKind::SubscriptDecl:
// FIXME
Buffer << "<subscript>";
return;
}
llvm_unreachable("bad decl context");
}
Expand Down
2 changes: 2 additions & 0 deletions lib/Sema/ITCNameLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ bool IterativeTypeChecker::isQualifiedLookupInDeclContextSatisfied(
case DeclContextKind::Initializer:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::SerializedLocal:
case DeclContextKind::SubscriptDecl:
llvm_unreachable("not a DeclContext that supports name lookup");

case DeclContextKind::Module:
Expand Down Expand Up @@ -131,6 +132,7 @@ bool IterativeTypeChecker::isUnqualifiedLookupInDeclContextSatisfied(
switch (dc->getContextKind()) {
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
case DeclContextKind::Initializer:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::SerializedLocal:
Expand Down
2 changes: 2 additions & 0 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,7 @@ void TypeChecker::computeAccessibility(ValueDecl *D) {
case DeclContextKind::Initializer:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
D->setAccessibility(Accessibility::Private);
break;
case DeclContextKind::Module:
Expand Down Expand Up @@ -5769,6 +5770,7 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) {
case DeclContextKind::FileUnit:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::Initializer:
case DeclContextKind::SubscriptDecl:
llvm_unreachable("cannot have type params");

case DeclContextKind::NominalTypeDecl: {
Expand Down
3 changes: 2 additions & 1 deletion lib/Sema/TypeCheckType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ Type TypeChecker::resolveTypeInContext(
// type within the context.
if (auto nominal = dyn_cast<NominalTypeDecl>(typeDecl)) {

this->forceExternalDeclMembers(nominal);
forceExternalDeclMembers(nominal);

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

case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
continue;
case DeclContextKind::SerializedLocal:
llvm_unreachable("should not be typechecking deserialized things");
Expand Down
16 changes: 7 additions & 9 deletions lib/Serialization/Deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1441,6 +1441,8 @@ DeclContext *ModuleFile::getDeclContext(DeclContextID DCID) {
declContextOrOffset = ED;
} else if (auto AFD = dyn_cast<AbstractFunctionDecl>(D)) {
declContextOrOffset = AFD;
} else if (auto SD = dyn_cast<SubscriptDecl>(D)) {
declContextOrOffset = SD;
} else {
llvm_unreachable("Unknown Decl : DeclContext kind");
}
Expand Down Expand Up @@ -2934,23 +2936,19 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
if (declOrOffset.isComplete())
return declOrOffset;

Pattern *indices = maybeReadPattern();
assert(indices);

auto elemTy = TypeLoc::withoutLoc(getType(elemTypeID));
if (declOrOffset.isComplete())
return declOrOffset;

// Resolve the name ids.
SmallVector<Identifier, 2> argNames;
for (auto argNameID : argNameIDs)
argNames.push_back(getIdentifier(argNameID));

DeclName name(ctx, ctx.Id_subscript, argNames);
auto subscript = createDecl<SubscriptDecl>(name, SourceLoc(), indices,
SourceLoc(), elemTy, DC);
auto subscript = createDecl<SubscriptDecl>(name, SourceLoc(), nullptr,
SourceLoc(), TypeLoc(), DC);
declOrOffset = subscript;

subscript->setIndices(maybeReadPattern());
subscript->getElementTypeLoc() = TypeLoc::withoutLoc(getType(elemTypeID));

configureStorage(subscript, rawStorageKind,
getterID, setterID, materializeForSetID,
addressorID, mutableAddressorID, willSetID, didSetID);
Expand Down
Loading

0 comments on commit feace85

Please sign in to comment.