@@ -4563,7 +4563,7 @@ synthesizeBaseClassFieldGetterBody(AbstractFunctionDecl *afd, void *context) {
45634563 ASTContext &ctx = afd->getASTContext ();
45644564
45654565 AccessorDecl *getterDecl = cast<AccessorDecl>(afd);
4566- VarDecl *baseClassVar = static_cast <VarDecl *>(context);
4566+ AbstractStorageDecl *baseClassVar = static_cast <AbstractStorageDecl *>(context);
45674567 StructDecl *baseStruct =
45684568 cast<StructDecl>(baseClassVar->getDeclContext ()->getAsDecl ());
45694569 StructDecl *derivedStruct =
@@ -4590,10 +4590,29 @@ synthesizeBaseClassFieldGetterBody(AbstractFunctionDecl *afd, void *context) {
45904590 AccessSemantics accessKind = baseClassVar->getClangDecl ()
45914591 ? AccessSemantics::DirectToStorage
45924592 : AccessSemantics::DirectToImplementation;
4593- auto baseMember =
4594- new (ctx) MemberRefExpr (casted, SourceLoc (), baseClassVar, DeclNameLoc (),
4595- /* Implicit=*/ true , accessKind);
4596- baseMember->setType (baseClassVar->getType ());
4593+ Expr *baseMember = nullptr ;
4594+ if (auto subscript = dyn_cast<SubscriptDecl>(baseClassVar)) {
4595+ auto paramDecl = getterDecl->getParameters ()->get (0 );
4596+ auto paramRefExpr = new (ctx) DeclRefExpr (paramDecl,
4597+ DeclNameLoc (),
4598+ /* Implicit=*/ true );
4599+ paramRefExpr->setType (paramDecl->getType ());
4600+
4601+ auto *argList = ArgumentList::forImplicitUnlabeled (ctx, {paramRefExpr});
4602+ baseMember = SubscriptExpr::create (ctx, casted, argList, subscript);
4603+ baseMember->setType (subscript->getElementInterfaceType ());
4604+ } else {
4605+ // If the base class var has a clang decl, that means it's an access into a
4606+ // stored field. Otherwise, we're looking into another base class, so it's a
4607+ // another synthesized accessor.
4608+ AccessSemantics accessKind = baseClassVar->getClangDecl ()
4609+ ? AccessSemantics::DirectToStorage
4610+ : AccessSemantics::DirectToImplementation;
4611+ baseMember =
4612+ new (ctx) MemberRefExpr (casted, SourceLoc (), baseClassVar, DeclNameLoc (),
4613+ /* Implicit=*/ true , accessKind);
4614+ baseMember->setType (cast<VarDecl>(baseClassVar)->getType ());
4615+ }
45974616
45984617 auto ret = new (ctx) ReturnStmt (SourceLoc (), baseMember);
45994618 auto body = BraceStmt::create (ctx, SourceLoc (), {ret}, SourceLoc (),
@@ -4611,7 +4630,7 @@ synthesizeBaseClassFieldGetterBody(AbstractFunctionDecl *afd, void *context) {
46114630static std::pair<BraceStmt *, bool >
46124631synthesizeBaseClassFieldSetterBody (AbstractFunctionDecl *afd, void *context) {
46134632 auto setterDecl = cast<AccessorDecl>(afd);
4614- VarDecl *baseClassVar = static_cast <VarDecl *>(context);
4633+ AbstractStorageDecl *baseClassVar = static_cast <AbstractStorageDecl *>(context);
46154634 ASTContext &ctx = setterDecl->getASTContext ();
46164635
46174636 StructDecl *baseStruct =
@@ -4622,16 +4641,30 @@ synthesizeBaseClassFieldSetterBody(AbstractFunctionDecl *afd, void *context) {
46224641 auto *pointeePropertyRefExpr =
46234642 getInOutSelfInteropStaticCast (setterDecl, baseStruct, derivedStruct);
46244643
4625- // If the base class var has a clang decl, that means it's an access into a
4626- // stored field. Otherwise, we're looking into another base class, so it's a
4627- // another synthesized accessor.
4628- AccessSemantics accessKind = baseClassVar->getClangDecl ()
4629- ? AccessSemantics::DirectToStorage
4630- : AccessSemantics::DirectToImplementation;
4631- auto storedRef =
4632- new (ctx) MemberRefExpr (pointeePropertyRefExpr, SourceLoc (), baseClassVar,
4633- DeclNameLoc (), /* Implicit=*/ true , accessKind);
4634- storedRef->setType (LValueType::get (baseClassVar->getType ()));
4644+ Expr *storedRef = nullptr ;
4645+ if (auto subscript = dyn_cast<SubscriptDecl>(baseClassVar)) {
4646+ auto paramDecl = setterDecl->getParameters ()->get (1 );
4647+ auto paramRefExpr = new (ctx) DeclRefExpr (paramDecl,
4648+ DeclNameLoc (),
4649+ /* Implicit=*/ true );
4650+ paramRefExpr->setType (paramDecl->getType ());
4651+
4652+ auto *argList = ArgumentList::forImplicitUnlabeled (ctx, {paramRefExpr});
4653+ storedRef = SubscriptExpr::create (ctx, pointeePropertyRefExpr, argList, subscript);
4654+ storedRef->setType (subscript->getElementInterfaceType ());
4655+ } else {
4656+ // If the base class var has a clang decl, that means it's an access into a
4657+ // stored field. Otherwise, we're looking into another base class, so it's a
4658+ // another synthesized accessor.
4659+ AccessSemantics accessKind = baseClassVar->getClangDecl ()
4660+ ? AccessSemantics::DirectToStorage
4661+ : AccessSemantics::DirectToImplementation;
4662+
4663+ storedRef =
4664+ new (ctx) MemberRefExpr (pointeePropertyRefExpr, SourceLoc (), baseClassVar,
4665+ DeclNameLoc (), /* Implicit=*/ true , accessKind);
4666+ storedRef->setType (LValueType::get (cast<VarDecl>(baseClassVar)->getType ()));
4667+ }
46354668
46364669 auto newValueParamRefExpr =
46374670 new (ctx) DeclRefExpr (setterDecl->getParameters ()->get (0 ), DeclNameLoc (),
@@ -4648,12 +4681,23 @@ synthesizeBaseClassFieldSetterBody(AbstractFunctionDecl *afd, void *context) {
46484681 return {body, /* isTypeChecked=*/ true };
46494682}
46504683
4651- static std::array<AccessorDecl *, 2 >
4652- makeBaseClassFieldAccessors (DeclContext *declContext, VarDecl *computedVar,
4653- VarDecl *baseClassVar) {
4684+ static SmallVector<AccessorDecl *, 2 >
4685+ makeBaseClassMemberAccessors (DeclContext *declContext,
4686+ AbstractStorageDecl *computedVar,
4687+ AbstractStorageDecl *baseClassVar) {
46544688 auto &ctx = declContext->getASTContext ();
46554689 auto computedType = computedVar->getInterfaceType ();
46564690
4691+ ParameterList *bodyParams = nullptr ;
4692+ if (auto subscript = dyn_cast<SubscriptDecl>(baseClassVar)) {
4693+ computedType = computedType->getAs <FunctionType>()->getResult ();
4694+
4695+ auto idxParam = subscript->getIndices ()->get (0 );
4696+ bodyParams = ParameterList::create (ctx, { idxParam });
4697+ } else {
4698+ bodyParams = ParameterList::createEmpty (ctx);
4699+ }
4700+
46574701 auto getterDecl = AccessorDecl::create (
46584702 ctx,
46594703 /* FuncLoc=*/ SourceLoc (),
@@ -4663,18 +4707,31 @@ makeBaseClassFieldAccessors(DeclContext *declContext, VarDecl *computedVar,
46634707 /* Async=*/ false , /* AsyncLoc=*/ SourceLoc (),
46644708 /* Throws=*/ false ,
46654709 /* ThrowsLoc=*/ SourceLoc (),
4666- /* GenericParams=*/ nullptr , ParameterList::createEmpty (ctx) , computedType,
4710+ /* GenericParams=*/ nullptr , bodyParams , computedType,
46674711 declContext);
46684712 getterDecl->setIsTransparent (true );
46694713 getterDecl->setAccess (AccessLevel::Public);
46704714 getterDecl->setBodySynthesizer (synthesizeBaseClassFieldGetterBody,
46714715 baseClassVar);
46724716
4717+ if (baseClassVar->getWriteImpl () == WriteImplKind::Immutable)
4718+ return {getterDecl};
4719+
46734720 auto newValueParam =
46744721 new (ctx) ParamDecl (SourceLoc (), SourceLoc (), Identifier (), SourceLoc (),
46754722 ctx.getIdentifier (" newValue" ), declContext);
46764723 newValueParam->setSpecifier (ParamSpecifier::Default);
46774724 newValueParam->setInterfaceType (computedType);
4725+
4726+ ParameterList *setterBodyParams = nullptr ;
4727+ if (auto subscript = dyn_cast<SubscriptDecl>(baseClassVar)) {
4728+ auto idxParam = subscript->getIndices ()->get (0 );
4729+ bodyParams = ParameterList::create (ctx, { idxParam });
4730+ setterBodyParams = ParameterList::create (ctx, { newValueParam, idxParam });
4731+ } else {
4732+ setterBodyParams = ParameterList::create (ctx, { newValueParam });
4733+ }
4734+
46784735 auto setterDecl = AccessorDecl::create (
46794736 ctx,
46804737 /* FuncLoc=*/ SourceLoc (),
@@ -4684,7 +4741,7 @@ makeBaseClassFieldAccessors(DeclContext *declContext, VarDecl *computedVar,
46844741 /* Async=*/ false , /* AsyncLoc=*/ SourceLoc (),
46854742 /* Throws=*/ false ,
46864743 /* ThrowsLoc=*/ SourceLoc (),
4687- /* GenericParams=*/ nullptr , ParameterList::create (ctx, {newValueParam}) ,
4744+ /* GenericParams=*/ nullptr , setterBodyParams ,
46884745 TupleType::getEmpty (ctx), declContext);
46894746 setterDecl->setIsTransparent (true );
46904747 setterDecl->setAccess (AccessLevel::Public);
@@ -4717,6 +4774,20 @@ ValueDecl *cloneBaseMemberDecl(ValueDecl *decl, DeclContext *newContext) {
47174774 return out;
47184775 }
47194776
4777+ if (auto subscript = dyn_cast<SubscriptDecl>(decl)) {
4778+ auto out = SubscriptDecl::create (
4779+ subscript->getASTContext (), subscript->getName (), subscript->getStaticLoc (),
4780+ subscript->getStaticSpelling (), subscript->getSubscriptLoc (),
4781+ subscript->getIndices (), subscript->getNameLoc (), subscript->getElementInterfaceType (),
4782+ newContext, subscript->getGenericParams ());
4783+ out->copyFormalAccessFrom (subscript);
4784+ out->setAccessors (SourceLoc (),
4785+ makeBaseClassMemberAccessors (newContext, out, subscript),
4786+ SourceLoc ());
4787+ out->setImplInfo (subscript->getImplInfo ());
4788+ return out;
4789+ }
4790+
47204791 if (auto var = dyn_cast<VarDecl>(decl)) {
47214792 auto rawMemory = allocateMemoryForDecl<VarDecl>(var->getASTContext (),
47224793 sizeof (VarDecl), false );
@@ -4728,9 +4799,11 @@ ValueDecl *cloneBaseMemberDecl(ValueDecl *decl, DeclContext *newContext) {
47284799 out->setIsDynamic (var->isDynamic ());
47294800 out->copyFormalAccessFrom (var);
47304801 out->setAccessors (SourceLoc (),
4731- makeBaseClassFieldAccessors (newContext, out, var),
4802+ makeBaseClassMemberAccessors (newContext, out, var),
47324803 SourceLoc ());
4733- out->setImplInfo (StorageImplInfo::getComputed (StorageIsMutable));
4804+ auto isMutable = var->getWriteImpl () == WriteImplKind::Immutable
4805+ ? StorageIsNotMutable : StorageIsMutable;
4806+ out->setImplInfo (StorageImplInfo::getComputed (isMutable));
47344807 out->setIsSetterMutating (true );
47354808 return out;
47364809 }
0 commit comments