@@ -381,6 +381,65 @@ namespace {
381
381
}
382
382
};
383
383
384
+ class EndAccessPseudoComponent : public WritebackPseudoComponent {
385
+ public:
386
+ EndAccessPseudoComponent (const LValueTypeData &typeData)
387
+ : WritebackPseudoComponent(typeData) {}
388
+
389
+ private:
390
+ void writeback (SILGenFunction &SGF, SILLocation loc,
391
+ ManagedValue base,
392
+ MaterializedLValue materialized,
393
+ bool isFinal) override {
394
+ assert (base.isLValue ());
395
+ SGF.B .createEndAccess (loc, base.getValue (), /* abort*/ false );
396
+ }
397
+
398
+ void print (raw_ostream &OS) const override {
399
+ OS << " EndAccessPseudoComponent" ;
400
+ }
401
+ };
402
+ } // end anonymous namespace
403
+
404
+ static SILValue enterAccessScope (SILGenFunction &SGF, SILLocation loc,
405
+ SILValue addr, LValueTypeData typeData,
406
+ AccessKind accessKind,
407
+ SILAccessEnforcement enforcement) {
408
+ auto silAccessKind = [&] {
409
+ switch (accessKind) {
410
+ case AccessKind::Read:
411
+ return SILAccessKind::Read;
412
+ case AccessKind::Write:
413
+ case AccessKind::ReadWrite:
414
+ return SILAccessKind::Modify;
415
+ }
416
+ }();
417
+
418
+ // Hack for materializeForSet emission, where we can't safely
419
+ // push a begin/end access.
420
+ if (!SGF.InWritebackScope ) {
421
+ assert (SGF.ValuesToEndAccessForMaterializeForSet );
422
+ if (enforcement == SILAccessEnforcement::Dynamic) {
423
+ // FIXME: begin access.
424
+ SGF.ValuesToEndAccessForMaterializeForSet ->push_back (addr);
425
+ }
426
+ return addr;
427
+ }
428
+
429
+ // Enter the access.
430
+ addr = SGF.B .createBeginAccess (loc, addr, silAccessKind, enforcement);
431
+
432
+ // Push a writeback to end it.
433
+ auto accessedMV = ManagedValue::forLValue (addr);
434
+ std::unique_ptr<LogicalPathComponent>
435
+ component (new EndAccessPseudoComponent (typeData));
436
+ pushWriteback (SGF, loc, std::move (component), accessedMV,
437
+ MaterializedLValue ());
438
+
439
+ return addr;
440
+ }
441
+
442
+ namespace {
384
443
class RefElementComponent : public PhysicalPathComponent {
385
444
VarDecl *Field;
386
445
SILType SubstFieldType;
@@ -399,9 +458,16 @@ namespace {
399
458
// Borrow the ref element addr using formal access. If we need the ref
400
459
// element addr, we will load it in this expression.
401
460
base = base.formalAccessBorrow (SGF, loc);
402
- auto Res = SGF.B .createRefElementAddr (loc, base.getUnmanagedValue (),
403
- Field, SubstFieldType);
404
- return ManagedValue::forLValue (Res);
461
+ SILValue result =
462
+ SGF.B .createRefElementAddr (loc, base.getUnmanagedValue (),
463
+ Field, SubstFieldType);
464
+
465
+ if (auto enforcement = SGF.getDynamicEnforcement (Field)) {
466
+ result = enterAccessScope (SGF, loc, result, getTypeData (),
467
+ accessKind, *enforcement);
468
+ }
469
+
470
+ return ManagedValue::forLValue (result);
405
471
}
406
472
407
473
void print (raw_ostream &OS) const override {
@@ -517,25 +583,6 @@ namespace {
517
583
}
518
584
};
519
585
520
- class EndAccessPseudoComponent : public WritebackPseudoComponent {
521
- public:
522
- EndAccessPseudoComponent (const LValueTypeData &typeData)
523
- : WritebackPseudoComponent(typeData) {}
524
-
525
- private:
526
- void writeback (SILGenFunction &SGF, SILLocation loc,
527
- ManagedValue base,
528
- MaterializedLValue materialized,
529
- bool isFinal) override {
530
- assert (base.isLValue ());
531
- SGF.B .createEndAccess (loc, base.getValue (), /* abort*/ false );
532
- }
533
-
534
- void print (raw_ostream &OS) const override {
535
- OS << " EndAccessPseudoComponent" ;
536
- }
537
- };
538
-
539
586
// / A physical path component which returns a literal address.
540
587
class ValueComponent : public PhysicalPathComponent {
541
588
ManagedValue Value;
@@ -560,30 +607,11 @@ namespace {
560
607
if (!Enforcement)
561
608
return Value;
562
609
563
- assert (Value.isLValue () && " nonlvalue has enforcement?" );
564
- auto silAccessKind = [&] {
565
- switch (accessKind) {
566
- case AccessKind::Read:
567
- return SILAccessKind::Read;
568
- case AccessKind::Write:
569
- case AccessKind::ReadWrite:
570
- return SILAccessKind::Modify;
571
- }
572
- }();
573
-
574
- // Enter the access.
575
- auto accessedValue =
576
- SGF.B .createBeginAccess (loc, Value.getValue (),
577
- silAccessKind, *Enforcement);
578
- auto accessedMV = ManagedValue::forLValue (accessedValue);
579
-
580
- // Push a writeback to end it.
581
- std::unique_ptr<LogicalPathComponent>
582
- component (new EndAccessPseudoComponent (getTypeData ()));
583
- pushWriteback (SGF, loc, std::move (component), accessedMV,
584
- MaterializedLValue ());
610
+ SILValue addr = Value.getLValueAddress ();
611
+ addr = enterAccessScope (SGF, loc, addr, getTypeData (),
612
+ accessKind, *Enforcement);
585
613
586
- return ManagedValue::forLValue (accessedValue );
614
+ return ManagedValue::forLValue (addr );
587
615
}
588
616
589
617
bool isRValue () const override {
0 commit comments