@@ -3642,9 +3642,21 @@ namespace {
3642
3642
3643
3643
result->setHasUnreferenceableStorage (hasUnreferenceableStorage);
3644
3644
3645
- if (cxxRecordDecl)
3645
+ if (cxxRecordDecl) {
3646
3646
result->setIsCxxNonTrivial (!cxxRecordDecl->isTriviallyCopyable ());
3647
3647
3648
+ for (auto &subscriptInfo : Impl.cxxSubscripts ) {
3649
+ auto declAndParameterType = subscriptInfo.first ;
3650
+ if (declAndParameterType.first != result)
3651
+ continue ;
3652
+
3653
+ auto getterAndSetter = subscriptInfo.second ;
3654
+ auto subscript = makeSubscript (getterAndSetter.first ,
3655
+ getterAndSetter.second );
3656
+ result->addMember (subscript);
3657
+ }
3658
+ }
3659
+
3648
3660
return result;
3649
3661
}
3650
3662
@@ -3917,12 +3929,10 @@ namespace {
3917
3929
AbstractStorageDecl *owningStorage;
3918
3930
switch (importedName.getAccessorKind ()) {
3919
3931
case ImportedAccessorKind::None:
3920
- owningStorage = nullptr ;
3921
- break ;
3922
-
3923
3932
case ImportedAccessorKind::SubscriptGetter:
3924
3933
case ImportedAccessorKind::SubscriptSetter:
3925
- llvm_unreachable (" Not possible for a function" );
3934
+ owningStorage = nullptr ;
3935
+ break ;
3926
3936
3927
3937
case ImportedAccessorKind::PropertyGetter: {
3928
3938
auto property = getImplicitProperty (importedName, decl);
@@ -4122,6 +4132,30 @@ namespace {
4122
4132
func->setImportAsStaticMember ();
4123
4133
}
4124
4134
}
4135
+
4136
+ if (importedName.isSubscriptAccessor ()) {
4137
+ assert (func->getParameters ()->size () == 1 );
4138
+ auto typeDecl = dc->getSelfNominalTypeDecl ();
4139
+ auto parameterType = func->getParameters ()->get (0 )->getType ();
4140
+ if (!typeDecl || !parameterType)
4141
+ return nullptr ;
4142
+
4143
+ auto &getterAndSetter = Impl.cxxSubscripts [{ typeDecl,
4144
+ parameterType }];
4145
+
4146
+ switch (importedName.getAccessorKind ()) {
4147
+ case ImportedAccessorKind::SubscriptGetter:
4148
+ getterAndSetter.first = func;
4149
+ break ;
4150
+ case ImportedAccessorKind::SubscriptSetter:
4151
+ getterAndSetter.second = func;
4152
+ break ;
4153
+ default :
4154
+ llvm_unreachable (" invalid subscript kind" );
4155
+ }
4156
+
4157
+ Impl.markUnavailable (func, " use subscript" );
4158
+ }
4125
4159
// Someday, maybe this will need to be 'open' for C++ virtual methods.
4126
4160
func->setAccess (AccessLevel::Public);
4127
4161
}
@@ -4950,6 +4984,15 @@ namespace {
4950
4984
SubscriptDecl *importSubscript (Decl *decl,
4951
4985
const clang::ObjCMethodDecl *objcMethod);
4952
4986
4987
+ // / Given either the getter, the setter, or both getter & setter
4988
+ // / for a subscript operation, create the Swift subscript declaration.
4989
+ // /
4990
+ // / \param getter function returning `UnsafePointer<T>`
4991
+ // / \param setter function returning `UnsafeMutablePointer<T>`
4992
+ // / \return subscript declaration
4993
+ SubscriptDecl *makeSubscript (FuncDecl *getter,
4994
+ FuncDecl *setter);
4995
+
4953
4996
// / Import the accessor and its attributes.
4954
4997
AccessorDecl *importAccessor (clang::ObjCMethodDecl *clangAccessor,
4955
4998
AbstractStorageDecl *storage,
@@ -7339,6 +7382,244 @@ SwiftDeclConverter::importAccessor(clang::ObjCMethodDecl *clangAccessor,
7339
7382
return accessor;
7340
7383
}
7341
7384
7385
+ static InOutExpr *
7386
+ createInOutSelfExpr (AccessorDecl *accessorDecl) {
7387
+ ASTContext &ctx = accessorDecl->getASTContext ();
7388
+
7389
+ auto inoutSelfDecl = accessorDecl->getImplicitSelfDecl ();
7390
+ auto inoutSelfRefExpr =
7391
+ new (ctx) DeclRefExpr (inoutSelfDecl, DeclNameLoc (),
7392
+ /* implicit=*/ true );
7393
+ inoutSelfRefExpr->setType (LValueType::get (inoutSelfDecl->getInterfaceType ()));
7394
+
7395
+ auto inoutSelfExpr =
7396
+ new (ctx) InOutExpr (SourceLoc (),
7397
+ inoutSelfRefExpr,
7398
+ accessorDecl->mapTypeIntoContext (
7399
+ inoutSelfDecl->getValueInterfaceType ()),
7400
+ /* isImplicit=*/ true );
7401
+ inoutSelfExpr->setType (InOutType::get (inoutSelfDecl->getInterfaceType ()));
7402
+ return inoutSelfExpr;
7403
+ }
7404
+
7405
+ static DeclRefExpr *
7406
+ createParamRefExpr (AccessorDecl *accessorDecl, unsigned index) {
7407
+ ASTContext &ctx = accessorDecl->getASTContext ();
7408
+
7409
+ auto paramDecl = accessorDecl->getParameters ()->get (index);
7410
+ auto paramRefExpr = new (ctx) DeclRefExpr (paramDecl,
7411
+ DeclNameLoc (),
7412
+ /* Implicit=*/ true );
7413
+ paramRefExpr->setType (paramDecl->getType ());
7414
+ return paramRefExpr;
7415
+ }
7416
+
7417
+ static CallExpr *
7418
+ createAccessorImplCallExpr (FuncDecl *accessorImpl,
7419
+ InOutExpr *inoutSelfExpr,
7420
+ DeclRefExpr *keyRefExpr) {
7421
+ ASTContext &ctx = accessorImpl->getASTContext ();
7422
+
7423
+ auto accessorImplExpr =
7424
+ new (ctx) DeclRefExpr (ConcreteDeclRef (accessorImpl),
7425
+ DeclNameLoc (),
7426
+ /* Implicit=*/ true );
7427
+ accessorImplExpr->setType (accessorImpl->getInterfaceType ());
7428
+
7429
+ auto accessorImplDotCallExpr =
7430
+ new (ctx) DotSyntaxCallExpr (accessorImplExpr,
7431
+ SourceLoc (),
7432
+ inoutSelfExpr);
7433
+ accessorImplDotCallExpr->setType (accessorImpl->getMethodInterfaceType ());
7434
+ accessorImplDotCallExpr->setThrows (false );
7435
+
7436
+ auto *accessorImplCallExpr =
7437
+ CallExpr::createImplicit (ctx, accessorImplDotCallExpr,
7438
+ { keyRefExpr }, { Identifier () });
7439
+ accessorImplCallExpr->setType (accessorImpl->getResultInterfaceType ());
7440
+ accessorImplCallExpr->setThrows (false );
7441
+ return accessorImplCallExpr;
7442
+ }
7443
+
7444
+ // / Synthesizer callback for a subscript getter.
7445
+ static std::pair<BraceStmt *, bool >
7446
+ synthesizeSubscriptGetterBody (AbstractFunctionDecl *afd, void *context) {
7447
+ auto getterDecl = cast<AccessorDecl>(afd);
7448
+ auto getterImpl = static_cast <FuncDecl *>(context);
7449
+
7450
+ ASTContext &ctx = getterDecl->getASTContext ();
7451
+
7452
+ InOutExpr *inoutSelfExpr = createInOutSelfExpr (getterDecl);
7453
+ DeclRefExpr *keyRefExpr = createParamRefExpr (getterDecl, 0 );
7454
+
7455
+ Type elementTy = getterDecl->getResultInterfaceType ();
7456
+
7457
+ auto *getterImplCallExpr = createAccessorImplCallExpr (getterImpl,
7458
+ inoutSelfExpr,
7459
+ keyRefExpr);
7460
+
7461
+ // `getterImpl` can return either UnsafePointer or UnsafeMutablePointer.
7462
+ // Retrieve the corresponding `.pointee` declaration.
7463
+ PointerTypeKind ptrKind;
7464
+ getterImpl->getResultInterfaceType ()->getAnyPointerElementType (ptrKind);
7465
+ VarDecl *pointeePropertyDecl = ctx.getPointerPointeePropertyDecl (ptrKind);
7466
+
7467
+ SubstitutionMap subMap =
7468
+ SubstitutionMap::get (ctx.getUnsafePointerDecl ()->getGenericSignature (),
7469
+ { elementTy }, { });
7470
+ auto pointeePropertyRefExpr =
7471
+ new (ctx) MemberRefExpr (getterImplCallExpr,
7472
+ SourceLoc (),
7473
+ ConcreteDeclRef (pointeePropertyDecl, subMap),
7474
+ DeclNameLoc (),
7475
+ /* implicit=*/ true );
7476
+ pointeePropertyRefExpr->setType (elementTy);
7477
+
7478
+ auto returnStmt = new (ctx) ReturnStmt (SourceLoc (),
7479
+ pointeePropertyRefExpr,
7480
+ /* implicit=*/ true );
7481
+
7482
+ auto body = BraceStmt::create (ctx, SourceLoc (), { returnStmt }, SourceLoc (),
7483
+ /* implicit=*/ true );
7484
+ return { body, /* isTypeChecked=*/ true };
7485
+ }
7486
+
7487
+ // / Synthesizer callback for a subscript setter.
7488
+ static std::pair<BraceStmt *, bool >
7489
+ synthesizeSubscriptSetterBody (AbstractFunctionDecl *afd, void *context) {
7490
+ auto setterDecl = cast<AccessorDecl>(afd);
7491
+ auto setterImpl = static_cast <FuncDecl *>(context);
7492
+
7493
+ ASTContext &ctx = setterDecl->getASTContext ();
7494
+
7495
+ InOutExpr *inoutSelfExpr = createInOutSelfExpr (setterDecl);
7496
+ DeclRefExpr *valueParamRefExpr = createParamRefExpr (setterDecl, 0 );
7497
+ DeclRefExpr *keyParamRefExpr = createParamRefExpr (setterDecl, 1 );
7498
+
7499
+ Type elementTy = valueParamRefExpr->getDecl ()->getInterfaceType ();
7500
+
7501
+ auto *setterImplCallExpr = createAccessorImplCallExpr (setterImpl,
7502
+ inoutSelfExpr,
7503
+ keyParamRefExpr);
7504
+
7505
+ VarDecl *pointeePropertyDecl = ctx.getPointerPointeePropertyDecl (PTK_UnsafeMutablePointer);
7506
+
7507
+ SubstitutionMap subMap =
7508
+ SubstitutionMap::get (ctx.getUnsafeMutablePointerDecl ()->getGenericSignature (),
7509
+ { elementTy }, { });
7510
+ auto pointeePropertyRefExpr =
7511
+ new (ctx) MemberRefExpr (setterImplCallExpr,
7512
+ SourceLoc (),
7513
+ ConcreteDeclRef (pointeePropertyDecl, subMap),
7514
+ DeclNameLoc (),
7515
+ /* implicit=*/ true );
7516
+ pointeePropertyRefExpr->setType (LValueType::get (elementTy));
7517
+
7518
+ auto assignExpr = new (ctx) AssignExpr (pointeePropertyRefExpr,
7519
+ SourceLoc (),
7520
+ valueParamRefExpr,
7521
+ /* implicit*/ true );
7522
+ assignExpr->setType (TupleType::getEmpty (ctx));
7523
+
7524
+ auto body = BraceStmt::create (ctx, SourceLoc (), { assignExpr, }, SourceLoc ());
7525
+ return { body, /* isTypeChecked=*/ true };
7526
+ }
7527
+
7528
+ SubscriptDecl *
7529
+ SwiftDeclConverter::makeSubscript (FuncDecl *getter, FuncDecl *setter) {
7530
+ assert ((getter || setter) && " getter or setter required to generate subscript" );
7531
+
7532
+ // If only a setter (imported from non-const `operator[]`) is defined,
7533
+ // generate both get & set accessors from it.
7534
+ FuncDecl *getterImpl = getter ? getter : setter;
7535
+ FuncDecl *setterImpl = setter;
7536
+
7537
+ // Get the return type wrapped in `Unsafe(Mutable)Pointer<T>`.
7538
+ const auto rawElementTy = getterImpl->getResultInterfaceType ();
7539
+ // Unwrap `T`.
7540
+ const auto elementTy = rawElementTy->getAnyPointerElementType ();
7541
+
7542
+ auto &ctx = Impl.SwiftContext ;
7543
+ auto bodyParams = getterImpl->getParameters ();
7544
+ DeclName name (ctx, DeclBaseName::createSubscript (), bodyParams);
7545
+ auto dc = getterImpl->getDeclContext ();
7546
+
7547
+ SubscriptDecl *subscript = SubscriptDecl::createImported (ctx,
7548
+ name,
7549
+ getterImpl->getLoc (),
7550
+ bodyParams,
7551
+ getterImpl->getLoc (),
7552
+ elementTy,
7553
+ dc,
7554
+ getterImpl->getClangNode ());
7555
+ subscript->setAccess (AccessLevel::Public);
7556
+
7557
+ AccessorDecl *getterDecl = AccessorDecl::create (ctx,
7558
+ getterImpl->getLoc (),
7559
+ getterImpl->getLoc (),
7560
+ AccessorKind::Get,
7561
+ subscript,
7562
+ SourceLoc (),
7563
+ subscript->getStaticSpelling (),
7564
+ false ,
7565
+ SourceLoc (),
7566
+ nullptr ,
7567
+ bodyParams,
7568
+ elementTy,
7569
+ dc);
7570
+ getterDecl->setAccess (AccessLevel::Public);
7571
+ getterDecl->setImplicit ();
7572
+ getterDecl->setIsDynamic (false );
7573
+ getterDecl->setIsTransparent (true );
7574
+ getterDecl->setBodySynthesizer (synthesizeSubscriptGetterBody, getterImpl);
7575
+
7576
+ if (getterImpl->isMutating ()) {
7577
+ getterDecl->setSelfAccessKind (SelfAccessKind::Mutating);
7578
+ subscript->setIsGetterMutating (true );
7579
+ }
7580
+
7581
+ AccessorDecl *setterDecl = nullptr ;
7582
+ if (setterImpl) {
7583
+ auto paramVarDecl =
7584
+ new (ctx) ParamDecl (SourceLoc (), SourceLoc (),
7585
+ Identifier (), SourceLoc (),
7586
+ ctx.getIdentifier (" newValue" ), dc);
7587
+ paramVarDecl->setSpecifier (ParamSpecifier::Default);
7588
+ paramVarDecl->setInterfaceType (elementTy);
7589
+
7590
+ auto setterParamList =
7591
+ ParameterList::create (ctx, { paramVarDecl, bodyParams->get (0 ) });
7592
+
7593
+ setterDecl = AccessorDecl::create (ctx,
7594
+ setterImpl->getLoc (),
7595
+ setterImpl->getLoc (),
7596
+ AccessorKind::Set,
7597
+ subscript,
7598
+ SourceLoc (),
7599
+ subscript->getStaticSpelling (),
7600
+ false ,
7601
+ SourceLoc (),
7602
+ nullptr ,
7603
+ setterParamList,
7604
+ TupleType::getEmpty (ctx),
7605
+ dc);
7606
+ setterDecl->setAccess (AccessLevel::Public);
7607
+ setterDecl->setImplicit ();
7608
+ setterDecl->setIsDynamic (false );
7609
+ setterDecl->setIsTransparent (true );
7610
+ setterDecl->setBodySynthesizer (synthesizeSubscriptSetterBody, setterImpl);
7611
+
7612
+ if (setterImpl->isMutating ()) {
7613
+ setterDecl->setSelfAccessKind (SelfAccessKind::Mutating);
7614
+ subscript->setIsSetterMutating (true );
7615
+ }
7616
+ }
7617
+
7618
+ makeComputed (subscript, getterDecl, setterDecl);
7619
+
7620
+ return subscript;
7621
+ }
7622
+
7342
7623
void SwiftDeclConverter::addProtocols (
7343
7624
ProtocolDecl *protocol, SmallVectorImpl<ProtocolDecl *> &protocols,
7344
7625
llvm::SmallPtrSetImpl<ProtocolDecl *> &known) {
0 commit comments