@@ -4564,7 +4564,7 @@ synthesizeBaseClassFieldGetterBody(AbstractFunctionDecl *afd, void *context) {
45644564 ASTContext &ctx = afd->getASTContext ();
45654565
45664566 AccessorDecl *getterDecl = cast<AccessorDecl>(afd);
4567- VarDecl *baseClassVar = static_cast <VarDecl *>(context);
4567+ AbstractStorageDecl *baseClassVar = static_cast <AbstractStorageDecl *>(context);
45684568 StructDecl *baseStruct =
45694569 cast<StructDecl>(baseClassVar->getDeclContext ()->getAsDecl ());
45704570 StructDecl *derivedStruct =
@@ -4591,10 +4591,29 @@ synthesizeBaseClassFieldGetterBody(AbstractFunctionDecl *afd, void *context) {
45914591 AccessSemantics accessKind = baseClassVar->getClangDecl ()
45924592 ? AccessSemantics::DirectToStorage
45934593 : AccessSemantics::DirectToImplementation;
4594- auto baseMember =
4595- new (ctx) MemberRefExpr (casted, SourceLoc (), baseClassVar, DeclNameLoc (),
4596- /* Implicit=*/ true , accessKind);
4597- baseMember->setType (baseClassVar->getType ());
4594+ Expr *baseMember = nullptr ;
4595+ if (auto subscript = dyn_cast<SubscriptDecl>(baseClassVar)) {
4596+ auto paramDecl = getterDecl->getParameters ()->get (0 );
4597+ auto paramRefExpr = new (ctx) DeclRefExpr (paramDecl,
4598+ DeclNameLoc (),
4599+ /* Implicit=*/ true );
4600+ paramRefExpr->setType (paramDecl->getType ());
4601+
4602+ auto *argList = ArgumentList::forImplicitUnlabeled (ctx, {paramRefExpr});
4603+ baseMember = SubscriptExpr::create (ctx, casted, argList, subscript);
4604+ baseMember->setType (subscript->getElementInterfaceType ());
4605+ } else {
4606+ // If the base class var has a clang decl, that means it's an access into a
4607+ // stored field. Otherwise, we're looking into another base class, so it's a
4608+ // another synthesized accessor.
4609+ AccessSemantics accessKind = baseClassVar->getClangDecl ()
4610+ ? AccessSemantics::DirectToStorage
4611+ : AccessSemantics::DirectToImplementation;
4612+ baseMember =
4613+ new (ctx) MemberRefExpr (casted, SourceLoc (), baseClassVar, DeclNameLoc (),
4614+ /* Implicit=*/ true , accessKind);
4615+ baseMember->setType (cast<VarDecl>(baseClassVar)->getType ());
4616+ }
45984617
45994618 auto ret = new (ctx) ReturnStmt (SourceLoc (), baseMember);
46004619 auto body = BraceStmt::create (ctx, SourceLoc (), {ret}, SourceLoc (),
@@ -4612,7 +4631,7 @@ synthesizeBaseClassFieldGetterBody(AbstractFunctionDecl *afd, void *context) {
46124631static std::pair<BraceStmt *, bool >
46134632synthesizeBaseClassFieldSetterBody (AbstractFunctionDecl *afd, void *context) {
46144633 auto setterDecl = cast<AccessorDecl>(afd);
4615- VarDecl *baseClassVar = static_cast <VarDecl *>(context);
4634+ AbstractStorageDecl *baseClassVar = static_cast <AbstractStorageDecl *>(context);
46164635 ASTContext &ctx = setterDecl->getASTContext ();
46174636
46184637 StructDecl *baseStruct =
@@ -4623,16 +4642,30 @@ synthesizeBaseClassFieldSetterBody(AbstractFunctionDecl *afd, void *context) {
46234642 auto *pointeePropertyRefExpr =
46244643 getInOutSelfInteropStaticCast (setterDecl, baseStruct, derivedStruct);
46254644
4626- // If the base class var has a clang decl, that means it's an access into a
4627- // stored field. Otherwise, we're looking into another base class, so it's a
4628- // another synthesized accessor.
4629- AccessSemantics accessKind = baseClassVar->getClangDecl ()
4630- ? AccessSemantics::DirectToStorage
4631- : AccessSemantics::DirectToImplementation;
4632- auto storedRef =
4633- new (ctx) MemberRefExpr (pointeePropertyRefExpr, SourceLoc (), baseClassVar,
4634- DeclNameLoc (), /* Implicit=*/ true , accessKind);
4635- storedRef->setType (LValueType::get (baseClassVar->getType ()));
4645+ Expr *storedRef = nullptr ;
4646+ if (auto subscript = dyn_cast<SubscriptDecl>(baseClassVar)) {
4647+ auto paramDecl = setterDecl->getParameters ()->get (1 );
4648+ auto paramRefExpr = new (ctx) DeclRefExpr (paramDecl,
4649+ DeclNameLoc (),
4650+ /* Implicit=*/ true );
4651+ paramRefExpr->setType (paramDecl->getType ());
4652+
4653+ auto *argList = ArgumentList::forImplicitUnlabeled (ctx, {paramRefExpr});
4654+ storedRef = SubscriptExpr::create (ctx, pointeePropertyRefExpr, argList, subscript);
4655+ storedRef->setType (subscript->getElementInterfaceType ());
4656+ } else {
4657+ // If the base class var has a clang decl, that means it's an access into a
4658+ // stored field. Otherwise, we're looking into another base class, so it's a
4659+ // another synthesized accessor.
4660+ AccessSemantics accessKind = baseClassVar->getClangDecl ()
4661+ ? AccessSemantics::DirectToStorage
4662+ : AccessSemantics::DirectToImplementation;
4663+
4664+ storedRef =
4665+ new (ctx) MemberRefExpr (pointeePropertyRefExpr, SourceLoc (), baseClassVar,
4666+ DeclNameLoc (), /* Implicit=*/ true , accessKind);
4667+ storedRef->setType (LValueType::get (cast<VarDecl>(baseClassVar)->getType ()));
4668+ }
46364669
46374670 auto newValueParamRefExpr =
46384671 new (ctx) DeclRefExpr (setterDecl->getParameters ()->get (0 ), DeclNameLoc (),
@@ -4649,12 +4682,23 @@ synthesizeBaseClassFieldSetterBody(AbstractFunctionDecl *afd, void *context) {
46494682 return {body, /* isTypeChecked=*/ true };
46504683}
46514684
4652- static std::array<AccessorDecl *, 2 >
4653- makeBaseClassFieldAccessors (DeclContext *declContext, VarDecl *computedVar,
4654- VarDecl *baseClassVar) {
4685+ static SmallVector<AccessorDecl *, 2 >
4686+ makeBaseClassMemberAccessors (DeclContext *declContext,
4687+ AbstractStorageDecl *computedVar,
4688+ AbstractStorageDecl *baseClassVar) {
46554689 auto &ctx = declContext->getASTContext ();
46564690 auto computedType = computedVar->getInterfaceType ();
46574691
4692+ ParameterList *bodyParams = nullptr ;
4693+ if (auto subscript = dyn_cast<SubscriptDecl>(baseClassVar)) {
4694+ computedType = computedType->getAs <FunctionType>()->getResult ();
4695+
4696+ auto idxParam = subscript->getIndices ()->get (0 );
4697+ bodyParams = ParameterList::create (ctx, { idxParam });
4698+ } else {
4699+ bodyParams = ParameterList::createEmpty (ctx);
4700+ }
4701+
46584702 auto getterDecl = AccessorDecl::create (
46594703 ctx,
46604704 /* FuncLoc=*/ SourceLoc (),
@@ -4664,18 +4708,31 @@ makeBaseClassFieldAccessors(DeclContext *declContext, VarDecl *computedVar,
46644708 /* Async=*/ false , /* AsyncLoc=*/ SourceLoc (),
46654709 /* Throws=*/ false ,
46664710 /* ThrowsLoc=*/ SourceLoc (),
4667- /* GenericParams=*/ nullptr , ParameterList::createEmpty (ctx) , computedType,
4711+ /* GenericParams=*/ nullptr , bodyParams , computedType,
46684712 declContext);
46694713 getterDecl->setIsTransparent (true );
46704714 getterDecl->setAccess (AccessLevel::Public);
46714715 getterDecl->setBodySynthesizer (synthesizeBaseClassFieldGetterBody,
46724716 baseClassVar);
46734717
4718+ if (baseClassVar->getWriteImpl () == WriteImplKind::Immutable)
4719+ return {getterDecl};
4720+
46744721 auto newValueParam =
46754722 new (ctx) ParamDecl (SourceLoc (), SourceLoc (), Identifier (), SourceLoc (),
46764723 ctx.getIdentifier (" newValue" ), declContext);
46774724 newValueParam->setSpecifier (ParamSpecifier::Default);
46784725 newValueParam->setInterfaceType (computedType);
4726+
4727+ ParameterList *setterBodyParams = nullptr ;
4728+ if (auto subscript = dyn_cast<SubscriptDecl>(baseClassVar)) {
4729+ auto idxParam = subscript->getIndices ()->get (0 );
4730+ bodyParams = ParameterList::create (ctx, { idxParam });
4731+ setterBodyParams = ParameterList::create (ctx, { newValueParam, idxParam });
4732+ } else {
4733+ setterBodyParams = ParameterList::create (ctx, { newValueParam });
4734+ }
4735+
46794736 auto setterDecl = AccessorDecl::create (
46804737 ctx,
46814738 /* FuncLoc=*/ SourceLoc (),
@@ -4685,7 +4742,7 @@ makeBaseClassFieldAccessors(DeclContext *declContext, VarDecl *computedVar,
46854742 /* Async=*/ false , /* AsyncLoc=*/ SourceLoc (),
46864743 /* Throws=*/ false ,
46874744 /* ThrowsLoc=*/ SourceLoc (),
4688- /* GenericParams=*/ nullptr , ParameterList::create (ctx, {newValueParam}) ,
4745+ /* GenericParams=*/ nullptr , setterBodyParams ,
46894746 TupleType::getEmpty (ctx), declContext);
46904747 setterDecl->setIsTransparent (true );
46914748 setterDecl->setAccess (AccessLevel::Public);
@@ -4718,6 +4775,20 @@ ValueDecl *cloneBaseMemberDecl(ValueDecl *decl, DeclContext *newContext) {
47184775 return out;
47194776 }
47204777
4778+ if (auto subscript = dyn_cast<SubscriptDecl>(decl)) {
4779+ auto out = SubscriptDecl::create (
4780+ subscript->getASTContext (), subscript->getName (), subscript->getStaticLoc (),
4781+ subscript->getStaticSpelling (), subscript->getSubscriptLoc (),
4782+ subscript->getIndices (), subscript->getNameLoc (), subscript->getElementInterfaceType (),
4783+ newContext, subscript->getGenericParams ());
4784+ out->copyFormalAccessFrom (subscript);
4785+ out->setAccessors (SourceLoc (),
4786+ makeBaseClassMemberAccessors (newContext, out, subscript),
4787+ SourceLoc ());
4788+ out->setImplInfo (subscript->getImplInfo ());
4789+ return out;
4790+ }
4791+
47214792 if (auto var = dyn_cast<VarDecl>(decl)) {
47224793 auto rawMemory = allocateMemoryForDecl<VarDecl>(var->getASTContext (),
47234794 sizeof (VarDecl), false );
@@ -4729,9 +4800,11 @@ ValueDecl *cloneBaseMemberDecl(ValueDecl *decl, DeclContext *newContext) {
47294800 out->setIsDynamic (var->isDynamic ());
47304801 out->copyFormalAccessFrom (var);
47314802 out->setAccessors (SourceLoc (),
4732- makeBaseClassFieldAccessors (newContext, out, var),
4803+ makeBaseClassMemberAccessors (newContext, out, var),
47334804 SourceLoc ());
4734- out->setImplInfo (StorageImplInfo::getComputed (StorageIsMutable));
4805+ auto isMutable = var->getWriteImpl () == WriteImplKind::Immutable
4806+ ? StorageIsNotMutable : StorageIsMutable;
4807+ out->setImplInfo (StorageImplInfo::getComputed (isMutable));
47354808 out->setIsSetterMutating (true );
47364809 return out;
47374810 }
0 commit comments