@@ -3651,9 +3651,21 @@ namespace {
3651
3651
3652
3652
result->setHasUnreferenceableStorage (hasUnreferenceableStorage);
3653
3653
3654
- if (cxxRecordDecl)
3654
+ if (cxxRecordDecl) {
3655
3655
result->setIsCxxNonTrivial (!cxxRecordDecl->isTriviallyCopyable ());
3656
3656
3657
+ for (auto &subscriptInfo : Impl.cxxSubscripts ) {
3658
+ auto declAndParameterType = subscriptInfo.first ;
3659
+ if (declAndParameterType.first != result)
3660
+ continue ;
3661
+
3662
+ auto getterAndSetter = subscriptInfo.second ;
3663
+ auto subscript = makeSubscript (getterAndSetter.first ,
3664
+ getterAndSetter.second );
3665
+ result->addMember (subscript);
3666
+ }
3667
+ }
3668
+
3657
3669
return result;
3658
3670
}
3659
3671
@@ -3945,12 +3957,10 @@ namespace {
3945
3957
AbstractStorageDecl *owningStorage;
3946
3958
switch (importedName.getAccessorKind ()) {
3947
3959
case ImportedAccessorKind::None:
3948
- owningStorage = nullptr ;
3949
- break ;
3950
-
3951
3960
case ImportedAccessorKind::SubscriptGetter:
3952
3961
case ImportedAccessorKind::SubscriptSetter:
3953
- llvm_unreachable (" Not possible for a function" );
3962
+ owningStorage = nullptr ;
3963
+ break ;
3954
3964
3955
3965
case ImportedAccessorKind::PropertyGetter: {
3956
3966
auto property = getImplicitProperty (importedName, decl);
@@ -4147,6 +4157,30 @@ namespace {
4147
4157
func->setImportAsStaticMember ();
4148
4158
}
4149
4159
}
4160
+
4161
+ if (importedName.isSubscriptAccessor ()) {
4162
+ assert (func->getParameters ()->size () == 1 );
4163
+ auto typeDecl = dc->getSelfNominalTypeDecl ();
4164
+ auto parameterType = func->getParameters ()->get (0 )->getType ();
4165
+ if (!typeDecl || !parameterType)
4166
+ return nullptr ;
4167
+
4168
+ auto &getterAndSetter = Impl.cxxSubscripts [{ typeDecl,
4169
+ parameterType }];
4170
+
4171
+ switch (importedName.getAccessorKind ()) {
4172
+ case ImportedAccessorKind::SubscriptGetter:
4173
+ getterAndSetter.first = func;
4174
+ break ;
4175
+ case ImportedAccessorKind::SubscriptSetter:
4176
+ getterAndSetter.second = func;
4177
+ break ;
4178
+ default :
4179
+ llvm_unreachable (" invalid subscript kind" );
4180
+ }
4181
+
4182
+ Impl.markUnavailable (func, " use subscript" );
4183
+ }
4150
4184
// Someday, maybe this will need to be 'open' for C++ virtual methods.
4151
4185
func->setAccess (AccessLevel::Public);
4152
4186
}
@@ -4976,6 +5010,15 @@ namespace {
4976
5010
SubscriptDecl *importSubscript (Decl *decl,
4977
5011
const clang::ObjCMethodDecl *objcMethod);
4978
5012
5013
+ // / Given either the getter, the setter, or both getter & setter
5014
+ // / for a subscript operation, create the Swift subscript declaration.
5015
+ // /
5016
+ // / \param getter function returning `UnsafePointer<T>`
5017
+ // / \param setter function returning `UnsafeMutablePointer<T>`
5018
+ // / \return subscript declaration
5019
+ SubscriptDecl *makeSubscript (FuncDecl *getter,
5020
+ FuncDecl *setter);
5021
+
4979
5022
// / Import the accessor and its attributes.
4980
5023
AccessorDecl *importAccessor (clang::ObjCMethodDecl *clangAccessor,
4981
5024
AbstractStorageDecl *storage,
@@ -7363,6 +7406,244 @@ SwiftDeclConverter::importAccessor(clang::ObjCMethodDecl *clangAccessor,
7363
7406
return accessor;
7364
7407
}
7365
7408
7409
+ static InOutExpr *
7410
+ createInOutSelfExpr (AccessorDecl *accessorDecl) {
7411
+ ASTContext &ctx = accessorDecl->getASTContext ();
7412
+
7413
+ auto inoutSelfDecl = accessorDecl->getImplicitSelfDecl ();
7414
+ auto inoutSelfRefExpr =
7415
+ new (ctx) DeclRefExpr (inoutSelfDecl, DeclNameLoc (),
7416
+ /* implicit=*/ true );
7417
+ inoutSelfRefExpr->setType (LValueType::get (inoutSelfDecl->getInterfaceType ()));
7418
+
7419
+ auto inoutSelfExpr =
7420
+ new (ctx) InOutExpr (SourceLoc (),
7421
+ inoutSelfRefExpr,
7422
+ accessorDecl->mapTypeIntoContext (
7423
+ inoutSelfDecl->getValueInterfaceType ()),
7424
+ /* isImplicit=*/ true );
7425
+ inoutSelfExpr->setType (InOutType::get (inoutSelfDecl->getInterfaceType ()));
7426
+ return inoutSelfExpr;
7427
+ }
7428
+
7429
+ static DeclRefExpr *
7430
+ createParamRefExpr (AccessorDecl *accessorDecl, unsigned index) {
7431
+ ASTContext &ctx = accessorDecl->getASTContext ();
7432
+
7433
+ auto paramDecl = accessorDecl->getParameters ()->get (index);
7434
+ auto paramRefExpr = new (ctx) DeclRefExpr (paramDecl,
7435
+ DeclNameLoc (),
7436
+ /* Implicit=*/ true );
7437
+ paramRefExpr->setType (paramDecl->getType ());
7438
+ return paramRefExpr;
7439
+ }
7440
+
7441
+ static CallExpr *
7442
+ createAccessorImplCallExpr (FuncDecl *accessorImpl,
7443
+ InOutExpr *inoutSelfExpr,
7444
+ DeclRefExpr *keyRefExpr) {
7445
+ ASTContext &ctx = accessorImpl->getASTContext ();
7446
+
7447
+ auto accessorImplExpr =
7448
+ new (ctx) DeclRefExpr (ConcreteDeclRef (accessorImpl),
7449
+ DeclNameLoc (),
7450
+ /* Implicit=*/ true );
7451
+ accessorImplExpr->setType (accessorImpl->getInterfaceType ());
7452
+
7453
+ auto accessorImplDotCallExpr =
7454
+ new (ctx) DotSyntaxCallExpr (accessorImplExpr,
7455
+ SourceLoc (),
7456
+ inoutSelfExpr);
7457
+ accessorImplDotCallExpr->setType (accessorImpl->getMethodInterfaceType ());
7458
+ accessorImplDotCallExpr->setThrows (false );
7459
+
7460
+ auto *accessorImplCallExpr =
7461
+ CallExpr::createImplicit (ctx, accessorImplDotCallExpr,
7462
+ { keyRefExpr }, { Identifier () });
7463
+ accessorImplCallExpr->setType (accessorImpl->getResultInterfaceType ());
7464
+ accessorImplCallExpr->setThrows (false );
7465
+ return accessorImplCallExpr;
7466
+ }
7467
+
7468
+ // / Synthesizer callback for a subscript getter.
7469
+ static std::pair<BraceStmt *, bool >
7470
+ synthesizeSubscriptGetterBody (AbstractFunctionDecl *afd, void *context) {
7471
+ auto getterDecl = cast<AccessorDecl>(afd);
7472
+ auto getterImpl = static_cast <FuncDecl *>(context);
7473
+
7474
+ ASTContext &ctx = getterDecl->getASTContext ();
7475
+
7476
+ InOutExpr *inoutSelfExpr = createInOutSelfExpr (getterDecl);
7477
+ DeclRefExpr *keyRefExpr = createParamRefExpr (getterDecl, 0 );
7478
+
7479
+ Type elementTy = getterDecl->getResultInterfaceType ();
7480
+
7481
+ auto *getterImplCallExpr = createAccessorImplCallExpr (getterImpl,
7482
+ inoutSelfExpr,
7483
+ keyRefExpr);
7484
+
7485
+ // `getterImpl` can return either UnsafePointer or UnsafeMutablePointer.
7486
+ // Retrieve the corresponding `.pointee` declaration.
7487
+ PointerTypeKind ptrKind;
7488
+ getterImpl->getResultInterfaceType ()->getAnyPointerElementType (ptrKind);
7489
+ VarDecl *pointeePropertyDecl = ctx.getPointerPointeePropertyDecl (ptrKind);
7490
+
7491
+ SubstitutionMap subMap =
7492
+ SubstitutionMap::get (ctx.getUnsafePointerDecl ()->getGenericSignature (),
7493
+ { elementTy }, { });
7494
+ auto pointeePropertyRefExpr =
7495
+ new (ctx) MemberRefExpr (getterImplCallExpr,
7496
+ SourceLoc (),
7497
+ ConcreteDeclRef (pointeePropertyDecl, subMap),
7498
+ DeclNameLoc (),
7499
+ /* implicit=*/ true );
7500
+ pointeePropertyRefExpr->setType (elementTy);
7501
+
7502
+ auto returnStmt = new (ctx) ReturnStmt (SourceLoc (),
7503
+ pointeePropertyRefExpr,
7504
+ /* implicit=*/ true );
7505
+
7506
+ auto body = BraceStmt::create (ctx, SourceLoc (), { returnStmt }, SourceLoc (),
7507
+ /* implicit=*/ true );
7508
+ return { body, /* isTypeChecked=*/ true };
7509
+ }
7510
+
7511
+ // / Synthesizer callback for a subscript setter.
7512
+ static std::pair<BraceStmt *, bool >
7513
+ synthesizeSubscriptSetterBody (AbstractFunctionDecl *afd, void *context) {
7514
+ auto setterDecl = cast<AccessorDecl>(afd);
7515
+ auto setterImpl = static_cast <FuncDecl *>(context);
7516
+
7517
+ ASTContext &ctx = setterDecl->getASTContext ();
7518
+
7519
+ InOutExpr *inoutSelfExpr = createInOutSelfExpr (setterDecl);
7520
+ DeclRefExpr *valueParamRefExpr = createParamRefExpr (setterDecl, 0 );
7521
+ DeclRefExpr *keyParamRefExpr = createParamRefExpr (setterDecl, 1 );
7522
+
7523
+ Type elementTy = valueParamRefExpr->getDecl ()->getInterfaceType ();
7524
+
7525
+ auto *setterImplCallExpr = createAccessorImplCallExpr (setterImpl,
7526
+ inoutSelfExpr,
7527
+ keyParamRefExpr);
7528
+
7529
+ VarDecl *pointeePropertyDecl = ctx.getPointerPointeePropertyDecl (PTK_UnsafeMutablePointer);
7530
+
7531
+ SubstitutionMap subMap =
7532
+ SubstitutionMap::get (ctx.getUnsafeMutablePointerDecl ()->getGenericSignature (),
7533
+ { elementTy }, { });
7534
+ auto pointeePropertyRefExpr =
7535
+ new (ctx) MemberRefExpr (setterImplCallExpr,
7536
+ SourceLoc (),
7537
+ ConcreteDeclRef (pointeePropertyDecl, subMap),
7538
+ DeclNameLoc (),
7539
+ /* implicit=*/ true );
7540
+ pointeePropertyRefExpr->setType (LValueType::get (elementTy));
7541
+
7542
+ auto assignExpr = new (ctx) AssignExpr (pointeePropertyRefExpr,
7543
+ SourceLoc (),
7544
+ valueParamRefExpr,
7545
+ /* implicit*/ true );
7546
+ assignExpr->setType (TupleType::getEmpty (ctx));
7547
+
7548
+ auto body = BraceStmt::create (ctx, SourceLoc (), { assignExpr, }, SourceLoc ());
7549
+ return { body, /* isTypeChecked=*/ true };
7550
+ }
7551
+
7552
+ SubscriptDecl *
7553
+ SwiftDeclConverter::makeSubscript (FuncDecl *getter, FuncDecl *setter) {
7554
+ assert ((getter || setter) && " getter or setter required to generate subscript" );
7555
+
7556
+ // If only a setter (imported from non-const `operator[]`) is defined,
7557
+ // generate both get & set accessors from it.
7558
+ FuncDecl *getterImpl = getter ? getter : setter;
7559
+ FuncDecl *setterImpl = setter;
7560
+
7561
+ // Get the return type wrapped in `Unsafe(Mutable)Pointer<T>`.
7562
+ const auto rawElementTy = getterImpl->getResultInterfaceType ();
7563
+ // Unwrap `T`.
7564
+ const auto elementTy = rawElementTy->getAnyPointerElementType ();
7565
+
7566
+ auto &ctx = Impl.SwiftContext ;
7567
+ auto bodyParams = getterImpl->getParameters ();
7568
+ DeclName name (ctx, DeclBaseName::createSubscript (), bodyParams);
7569
+ auto dc = getterImpl->getDeclContext ();
7570
+
7571
+ SubscriptDecl *subscript = SubscriptDecl::createImported (ctx,
7572
+ name,
7573
+ getterImpl->getLoc (),
7574
+ bodyParams,
7575
+ getterImpl->getLoc (),
7576
+ elementTy,
7577
+ dc,
7578
+ getterImpl->getClangNode ());
7579
+ subscript->setAccess (AccessLevel::Public);
7580
+
7581
+ AccessorDecl *getterDecl = AccessorDecl::create (ctx,
7582
+ getterImpl->getLoc (),
7583
+ getterImpl->getLoc (),
7584
+ AccessorKind::Get,
7585
+ subscript,
7586
+ SourceLoc (),
7587
+ subscript->getStaticSpelling (),
7588
+ false ,
7589
+ SourceLoc (),
7590
+ nullptr ,
7591
+ bodyParams,
7592
+ elementTy,
7593
+ dc);
7594
+ getterDecl->setAccess (AccessLevel::Public);
7595
+ getterDecl->setImplicit ();
7596
+ getterDecl->setIsDynamic (false );
7597
+ getterDecl->setIsTransparent (true );
7598
+ getterDecl->setBodySynthesizer (synthesizeSubscriptGetterBody, getterImpl);
7599
+
7600
+ if (getterImpl->isMutating ()) {
7601
+ getterDecl->setSelfAccessKind (SelfAccessKind::Mutating);
7602
+ subscript->setIsGetterMutating (true );
7603
+ }
7604
+
7605
+ AccessorDecl *setterDecl = nullptr ;
7606
+ if (setterImpl) {
7607
+ auto paramVarDecl =
7608
+ new (ctx) ParamDecl (SourceLoc (), SourceLoc (),
7609
+ Identifier (), SourceLoc (),
7610
+ ctx.getIdentifier (" newValue" ), dc);
7611
+ paramVarDecl->setSpecifier (ParamSpecifier::Default);
7612
+ paramVarDecl->setInterfaceType (elementTy);
7613
+
7614
+ auto setterParamList =
7615
+ ParameterList::create (ctx, { paramVarDecl, bodyParams->get (0 ) });
7616
+
7617
+ setterDecl = AccessorDecl::create (ctx,
7618
+ setterImpl->getLoc (),
7619
+ setterImpl->getLoc (),
7620
+ AccessorKind::Set,
7621
+ subscript,
7622
+ SourceLoc (),
7623
+ subscript->getStaticSpelling (),
7624
+ false ,
7625
+ SourceLoc (),
7626
+ nullptr ,
7627
+ setterParamList,
7628
+ TupleType::getEmpty (ctx),
7629
+ dc);
7630
+ setterDecl->setAccess (AccessLevel::Public);
7631
+ setterDecl->setImplicit ();
7632
+ setterDecl->setIsDynamic (false );
7633
+ setterDecl->setIsTransparent (true );
7634
+ setterDecl->setBodySynthesizer (synthesizeSubscriptSetterBody, setterImpl);
7635
+
7636
+ if (setterImpl->isMutating ()) {
7637
+ setterDecl->setSelfAccessKind (SelfAccessKind::Mutating);
7638
+ subscript->setIsSetterMutating (true );
7639
+ }
7640
+ }
7641
+
7642
+ makeComputed (subscript, getterDecl, setterDecl);
7643
+
7644
+ return subscript;
7645
+ }
7646
+
7366
7647
void SwiftDeclConverter::addProtocols (
7367
7648
ProtocolDecl *protocol, SmallVectorImpl<ProtocolDecl *> &protocols,
7368
7649
llvm::SmallPtrSetImpl<ProtocolDecl *> &known) {
0 commit comments