@@ -1481,3 +1481,81 @@ void SILGenFunction::emitIVarInitializer(SILDeclRef ivarInitializer) {
1481
1481
1482
1482
emitEpilog (loc);
1483
1483
}
1484
+
1485
+ void SILGenFunction::emitInitAccessor (AccessorDecl *accessor) {
1486
+ RegularLocation loc (accessor);
1487
+ loc.markAutoGenerated ();
1488
+
1489
+ auto accessorTy = F.getLoweredFunctionType ();
1490
+
1491
+ auto createArgument = [&](VarDecl *property, SILType type,
1492
+ bool markUninitialized = false ) {
1493
+ auto *arg = ParamDecl::createImplicit (
1494
+ getASTContext (), property->getBaseIdentifier (),
1495
+ property->getBaseIdentifier (), type.getASTType ()->mapTypeOutOfContext (),
1496
+ accessor, ParamSpecifier::InOut);
1497
+
1498
+ RegularLocation loc (property);
1499
+ loc.markAutoGenerated ();
1500
+
1501
+ SILValue argValue = F.begin ()->createFunctionArgument (type, arg);
1502
+ VarLocs[arg] =
1503
+ markUninitialized
1504
+ ? VarLoc::get (B.createMarkUninitializedOut (loc, argValue))
1505
+ : VarLoc::get (argValue);
1506
+
1507
+ InitAccessorArgumentMappings[property] = arg;
1508
+ };
1509
+
1510
+ // First, emit results, this is our "initializes(...)" properties and
1511
+ // require DI to check that each property is fully initialized.
1512
+ if (auto *initAttr = accessor->getAttrs ().getAttribute <InitializesAttr>()) {
1513
+ auto initializedProperties = initAttr->getPropertyDecls (accessor);
1514
+ for (unsigned i = 0 , n = initializedProperties.size (); i != n; ++i) {
1515
+ auto *property = initializedProperties[i];
1516
+ auto propertyTy =
1517
+ getSILTypeInContext (accessorTy->getResults ()[i], accessorTy);
1518
+ createArgument (property, propertyTy, /* markUninitialized=*/ true );
1519
+ }
1520
+ }
1521
+
1522
+ // Collect all of the parameters that represent properties listed by
1523
+ // "accesses" attribute. They have to be emitted in order of arguments which
1524
+ // means after the "newValue" which is emitted by \c emitBasicProlog.
1525
+ Optional<ArrayRef<VarDecl *>> accessedProperties;
1526
+ {
1527
+ if (auto *accessAttr = accessor->getAttrs ().getAttribute <AccessesAttr>())
1528
+ accessedProperties = accessAttr->getPropertyDecls (accessor);
1529
+ }
1530
+
1531
+ // Emit `newValue` argument.
1532
+ emitBasicProlog (accessor->getParameters (), /* selfParam=*/ nullptr ,
1533
+ TupleType::getEmpty (F.getASTContext ()), accessor,
1534
+ /* throws=*/ false , /* throwsLoc=*/ SourceLoc (),
1535
+ /* ignored parameters*/
1536
+ accessedProperties ? accessedProperties->size () : 0 );
1537
+
1538
+ // Emit arguments for all `accesses(...)` properties.
1539
+ if (accessedProperties) {
1540
+ auto propertyIter = accessedProperties->begin ();
1541
+ auto propertyArgs = accessorTy->getParameters ().slice (
1542
+ accessorTy->getNumParameters () - accessedProperties->size ());
1543
+
1544
+ for (const auto &argument : propertyArgs) {
1545
+ createArgument (*propertyIter, getSILTypeInContext (argument, accessorTy));
1546
+ ++propertyIter;
1547
+ }
1548
+ }
1549
+
1550
+ prepareEpilog (accessor->getResultInterfaceType (), accessor->hasThrows (),
1551
+ CleanupLocation (accessor));
1552
+
1553
+ emitProfilerIncrement (accessor->getTypecheckedBody ());
1554
+
1555
+ // Emit the actual function body as usual
1556
+ emitStmt (accessor->getTypecheckedBody ());
1557
+
1558
+ emitEpilog (accessor);
1559
+
1560
+ mergeCleanupBlocks ();
1561
+ }
0 commit comments