@@ -1538,17 +1538,22 @@ synthesizeUnwrappingGetterBody(AbstractFunctionDecl *afd, void *context) {
15381538 return {body, /* isTypeChecked*/ true };
15391539}
15401540
1541- // / Synthesizer callback for a subscript setter.
1541+ // / Synthesizer callback for a subscript setter or a setter for a dereference
1542+ // / property (`var pointee`).
15421543static std::pair<BraceStmt *, bool >
1543- synthesizeSubscriptSetterBody (AbstractFunctionDecl *afd, void *context) {
1544+ synthesizeUnwrappingSetterBody (AbstractFunctionDecl *afd, void *context) {
15441545 auto setterDecl = cast<AccessorDecl>(afd);
15451546 auto setterImpl = static_cast <FuncDecl *>(context);
15461547
15471548 ASTContext &ctx = setterDecl->getASTContext ();
15481549
15491550 auto selfArg = createSelfArg (setterDecl);
15501551 DeclRefExpr *valueParamRefExpr = createParamRefExpr (setterDecl, 0 );
1551- DeclRefExpr *keyParamRefExpr = createParamRefExpr (setterDecl, 1 );
1552+ // For a subscript this decl will have two parameters, for a pointee property
1553+ // it will only have one.
1554+ DeclRefExpr *keyParamRefExpr = setterDecl->getParameters ()->size () == 1
1555+ ? nullptr
1556+ : createParamRefExpr (setterDecl, 1 );
15521557
15531558 Type elementTy = valueParamRefExpr->getDecl ()->getInterfaceType ();
15541559
@@ -1644,7 +1649,7 @@ SubscriptDecl *SwiftDeclSynthesizer::makeSubscript(FuncDecl *getter,
16441649 setterDecl->setImplicit ();
16451650 setterDecl->setIsDynamic (false );
16461651 setterDecl->setIsTransparent (true );
1647- setterDecl->setBodySynthesizer (synthesizeSubscriptSetterBody , setterImpl);
1652+ setterDecl->setBodySynthesizer (synthesizeUnwrappingSetterBody , setterImpl);
16481653
16491654 if (setterImpl->isMutating ()) {
16501655 setterDecl->setSelfAccessKind (SelfAccessKind::Mutating);
@@ -1663,28 +1668,34 @@ SubscriptDecl *SwiftDeclSynthesizer::makeSubscript(FuncDecl *getter,
16631668
16641669// MARK: C++ dereference operator
16651670
1666- VarDecl *SwiftDeclSynthesizer::makeDereferencedPointeeProperty (
1667- FuncDecl *dereferenceFunc) {
1671+ VarDecl *
1672+ SwiftDeclSynthesizer::makeDereferencedPointeeProperty (FuncDecl *getter,
1673+ FuncDecl *setter) {
1674+ assert ((getter || setter) &&
1675+ " getter or setter required to generate a pointee property" );
1676+
16681677 auto &ctx = ImporterImpl.SwiftContext ;
1669- auto dc = dereferenceFunc->getDeclContext ();
1678+ FuncDecl *getterImpl = getter ? getter : setter;
1679+ FuncDecl *setterImpl = setter;
1680+ auto dc = getterImpl->getDeclContext ();
16701681
16711682 // Get the return type wrapped in `Unsafe(Mutable)Pointer<T>`.
1672- const auto rawElementTy = dereferenceFunc ->getResultInterfaceType ();
1683+ const auto rawElementTy = getterImpl ->getResultInterfaceType ();
16731684 // Unwrap `T`. Use rawElementTy for return by value.
16741685 const auto elementTy = rawElementTy->getAnyPointerElementType ()
16751686 ? rawElementTy->getAnyPointerElementType ()
16761687 : rawElementTy;
16771688
16781689 auto result = new (ctx)
16791690 VarDecl (/* isStatic*/ false , VarDecl::Introducer::Var,
1680- dereferenceFunc ->getStartLoc (), ctx.getIdentifier (" pointee" ), dc);
1691+ getterImpl ->getStartLoc (), ctx.getIdentifier (" pointee" ), dc);
16811692 result->setInterfaceType (elementTy);
16821693 result->setAccess (AccessLevel::Public);
16831694 result->setImplInfo (StorageImplInfo::getImmutableComputed ());
16841695
16851696 AccessorDecl *getterDecl = AccessorDecl::create (
1686- ctx, dereferenceFunc ->getLoc (), dereferenceFunc ->getLoc (),
1687- AccessorKind::Get, result, SourceLoc (), StaticSpellingKind::None,
1697+ ctx, getterImpl ->getLoc (), getterImpl ->getLoc (), AccessorKind::Get ,
1698+ result, SourceLoc (), StaticSpellingKind::None,
16881699 /* async*/ false , SourceLoc (),
16891700 /* throws*/ false , SourceLoc (), ParameterList::createEmpty (ctx), elementTy,
16901701 dc);
@@ -1693,14 +1704,43 @@ VarDecl *SwiftDeclSynthesizer::makeDereferencedPointeeProperty(
16931704 getterDecl->setIsDynamic (false );
16941705 getterDecl->setIsTransparent (true );
16951706 getterDecl->setBodySynthesizer (synthesizeUnwrappingGetterBody,
1696- dereferenceFunc );
1707+ getterImpl );
16971708
1698- if (dereferenceFunc ->isMutating ()) {
1709+ if (getterImpl ->isMutating ()) {
16991710 getterDecl->setSelfAccessKind (SelfAccessKind::Mutating);
17001711 result->setIsGetterMutating (true );
17011712 }
17021713
1703- ImporterImpl.makeComputed (result, getterDecl, /* setter*/ nullptr );
1714+ AccessorDecl *setterDecl = nullptr ;
1715+ if (setterImpl) {
1716+ auto paramVarDecl =
1717+ new (ctx) ParamDecl (SourceLoc (), SourceLoc (), Identifier (), SourceLoc (),
1718+ ctx.getIdentifier (" newValue" ), dc);
1719+ paramVarDecl->setSpecifier (ParamSpecifier::Default);
1720+ paramVarDecl->setInterfaceType (elementTy);
1721+
1722+ auto setterParamList =
1723+ ParameterList::create (ctx, {paramVarDecl});
1724+
1725+ setterDecl = AccessorDecl::create (
1726+ ctx, setterImpl->getLoc (), setterImpl->getLoc (), AccessorKind::Set,
1727+ result, SourceLoc (), StaticSpellingKind::None,
1728+ /* async*/ false , SourceLoc (),
1729+ /* throws*/ false , SourceLoc (), setterParamList,
1730+ TupleType::getEmpty (ctx), dc);
1731+ setterDecl->setAccess (AccessLevel::Public);
1732+ setterDecl->setImplicit ();
1733+ setterDecl->setIsDynamic (false );
1734+ setterDecl->setIsTransparent (true );
1735+ setterDecl->setBodySynthesizer (synthesizeUnwrappingSetterBody, setterImpl);
1736+
1737+ if (setterImpl->isMutating ()) {
1738+ setterDecl->setSelfAccessKind (SelfAccessKind::Mutating);
1739+ result->setIsSetterMutating (true );
1740+ }
1741+ }
1742+
1743+ ImporterImpl.makeComputed (result, getterDecl, setterDecl);
17041744 return result;
17051745}
17061746
0 commit comments