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.
This commit is contained in:
Chris Lattner
2015-12-31 12:37:33 -08:00
parent 6dcb6ef594
commit feace85d5a
21 changed files with 104 additions and 26 deletions
+9 -1
View File
@@ -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;
@@ -4248,6 +4248,7 @@ public:
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);
}
@@ -4288,6 +4289,13 @@ public:
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.
+1
View File
@@ -66,6 +66,7 @@ enum class DeclContextKind : uint8_t {
AbstractClosureExpr,
Initializer,
TopLevelCodeDecl,
SubscriptDecl,
AbstractFunctionDecl,
SerializedLocal,
Last_LocalDeclContextKind = SerializedLocal,
+3
View File
@@ -986,6 +986,9 @@ static void printContext(raw_ostream &os, DeclContext *dc) {
os << "deinit";
break;
}
case DeclContextKind::SubscriptDecl:
os << "subscript decl";
break;
}
}
+4
View File
@@ -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;
}
}
+10 -11
View File
@@ -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 {
@@ -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,
+27
View File
@@ -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;
@@ -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();
@@ -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();
@@ -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();
@@ -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;
@@ -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;
@@ -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;
}
@@ -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;
@@ -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);
@@ -408,6 +419,7 @@ bool DeclContext::isGenericContext() const {
case DeclContextKind::Initializer:
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::SerializedLocal:
case DeclContextKind::SubscriptDecl:
// Check parent context.
continue;
@@ -506,6 +518,9 @@ DeclContext::isCascadingContextForLookup(bool functionsAreNonCascading) const {
break;
}
case DeclContextKind::SubscriptDecl:
return false;
case DeclContextKind::Module:
case DeclContextKind::FileUnit:
return true;
@@ -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:
@@ -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;
@@ -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: {
+1
View File
@@ -558,6 +558,7 @@ void DiagnosticEngine::emitDiagnostic(const Diagnostic &diagnostic) {
case DeclContextKind::Initializer:
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
break;
}
+3
View File
@@ -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: {
+1
View File
@@ -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:
+3 -1
View File
@@ -516,6 +516,7 @@ struct ASTNodeBase {};
case DeclContextKind::Initializer:
case DeclContextKind::AbstractClosureExpr:
case DeclContextKind::SerializedLocal:
case DeclContextKind::SubscriptDecl:
return nullptr;
case DeclContextKind::AbstractFunctionDecl:
@@ -1601,6 +1602,7 @@ struct ASTNodeBase {};
case DeclContextKind::Initializer:
case DeclContextKind::NominalTypeDecl:
case DeclContextKind::ExtensionDecl:
case DeclContextKind::SubscriptDecl:
return hasEnclosingFunctionContext(dc->getParent());
}
}
@@ -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>();
})) {
+1
View File
@@ -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;
+1
View File
@@ -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:
+4
View File
@@ -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");
}
+2
View File
@@ -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:
@@ -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:
+2
View File
@@ -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:
@@ -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: {
+2 -1
View File
@@ -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()) {
@@ -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");
+7 -9
View File
@@ -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");
}
@@ -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);
+20 -1
View File
@@ -164,7 +164,8 @@ static ASTContext &getContext(ModuleOrSourceFile DC) {
}
static bool shouldSerializeAsLocalContext(const DeclContext *DC) {
return DC->isLocalContext() && !isa<AbstractFunctionDecl>(DC);
return DC->isLocalContext() && !isa<AbstractFunctionDecl>(DC) &&
!isa<SubscriptDecl>(DC);
}
static const Decl *getDeclForContext(const DeclContext *DC) {
@@ -188,6 +189,8 @@ static const Decl *getDeclForContext(const DeclContext *DC) {
llvm_unreachable("shouldn't serialize the main module");
case DeclContextKind::AbstractFunctionDecl:
return cast<AbstractFunctionDecl>(DC);
case DeclContextKind::SubscriptDecl:
return cast<SubscriptDecl>(DC);
}
}
@@ -1326,6 +1329,21 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
break;
}
case DeclContextKind::SubscriptDecl: {
auto SD = cast<SubscriptDecl>(DC);
writeCrossReference(DC->getParent(), pathLen + 1);
Type ty = SD->getInterfaceType()->getCanonicalType();
abbrCode = DeclTypeAbbrCodes[XRefValuePathPieceLayout::Code];
bool isProtocolExt = SD->getDeclContext()->isProtocolExtensionContext();
XRefValuePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
addTypeRef(ty),
addIdentifierRef(SD->getName()),
isProtocolExt);
break;
}
case DeclContextKind::AbstractFunctionDecl: {
if (auto fn = dyn_cast<FuncDecl>(DC)) {
if (auto storage = fn->getAccessorStorageDecl()) {
@@ -1740,6 +1758,7 @@ void Serializer::writeDeclContext(const DeclContext *DC) {
switch (DC->getContextKind()) {
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
case DeclContextKind::NominalTypeDecl:
case DeclContextKind::ExtensionDecl:
declOrDeclContextID = addDeclRef(getDeclForContext(DC));
+1 -1
View File
@@ -277,7 +277,7 @@ func unterminatedBlockDocComment() {}
// CHECK-NEXT: comment_attach.swift:135:8: Func/decl_struct_1.instanceFunc4 RawComment=[/// instanceFunc4 Aaa.\n]
// CHECK-NEXT: comment_attach.swift:138:3: Constructor/decl_struct_1.init RawComment=[/// init(). Aaa.\n] BriefComment=[init(). Aaa.]
// CHECK-NEXT: comment_attach.swift:141:3: Subscript/decl_struct_1.subscript RawComment=[/// subscript Aaa.\n]
// CHECK-NEXT: comment_attach.swift:141:13: Param/decl_struct_1.i RawComment=none
// CHECK-NEXT: comment_attach.swift:141:13: Param/i RawComment=none
// CHECK-NEXT: comment_attach.swift:141:31: Func/decl_struct_1.<getter for decl_struct_1.subscript> RawComment=none
// CHECK-NEXT: comment_attach.swift:144:10: Struct/decl_struct_1.NestedStruct RawComment=[/// NestedStruct Aaa.\n]
// CHECK-NEXT: comment_attach.swift:147:9: Class/decl_struct_1.NestedClass RawComment=[/// NestedClass Aaa.\n]
+1 -1
View File
@@ -46,7 +46,7 @@ class GenericClass {
}
// CHECK: [[@LINE+2]]:3 s:iC14swift_ide_test12GenericClass9subscriptFSiSf{{$}}
// CHECK: [[@LINE+1]]:13 s:vC14swift_ide_test12GenericClass1iSi{{$}}
// CHECK: [[@LINE+1]]:13 s:vC14swift_ide_test12GenericClassL_1iSi{{$}}
subscript(i: Int) -> Float {
// CHECK: [[@LINE+1]]:5 s:FC14swift_ide_test12GenericClassg9subscriptFSiSf{{$}}
get { return 0.0 }
@@ -1051,6 +1051,7 @@ static Accessibility inferAccessibility(const ValueDecl *D) {
case DeclContextKind::Initializer:
case DeclContextKind::TopLevelCodeDecl:
case DeclContextKind::AbstractFunctionDecl:
case DeclContextKind::SubscriptDecl:
return Accessibility::Private;
case DeclContextKind::Module:
case DeclContextKind::FileUnit: