@@ -290,13 +290,13 @@ class DestroyLocalVariable : public Cleanup {
290
290
namespace {
291
291
// / Cleanup to destroy an uninitialized local variable.
292
292
class DeallocateUninitializedLocalVariable : public Cleanup {
293
- VarDecl *Var ;
293
+ SILValue Box ;
294
294
public:
295
- DeallocateUninitializedLocalVariable (VarDecl *var ) : Var(var ) {}
295
+ DeallocateUninitializedLocalVariable (SILValue box ) : Box(box ) {}
296
296
297
297
void emit (SILGenFunction &SGF, CleanupLocation l,
298
298
ForUnwind_t forUnwind) override {
299
- SGF.deallocateUninitializedLocalVariable (l, Var );
299
+ SGF.B . createDeallocBox (l, Box );
300
300
}
301
301
302
302
void dump (SILGenFunction &) const override {
@@ -315,7 +315,12 @@ namespace {
315
315
class LocalVariableInitialization : public SingleBufferInitialization {
316
316
// / The local variable decl being initialized.
317
317
VarDecl *decl;
318
- SILGenFunction &SGF;
318
+
319
+ // / The alloc_box instruction.
320
+ SILValue Box;
321
+
322
+ // / The projected address.
323
+ SILValue Addr;
319
324
320
325
// / The cleanup we pushed to deallocate the local variable before it
321
326
// / gets initialized.
@@ -332,7 +337,7 @@ class LocalVariableInitialization : public SingleBufferInitialization {
332
337
LocalVariableInitialization (VarDecl *decl,
333
338
Optional<MarkUninitializedInst::Kind> kind,
334
339
uint16_t ArgNo, SILGenFunction &SGF)
335
- : decl(decl), SGF(SGF) {
340
+ : decl(decl) {
336
341
assert (decl->getDeclContext ()->isLocalContext () &&
337
342
" can't emit a local var for a non-local var decl" );
338
343
assert (decl->hasStorage () && " can't emit storage for a computed variable" );
@@ -348,26 +353,24 @@ class LocalVariableInitialization : public SingleBufferInitialization {
348
353
// The variable may have its lifetime extended by a closure, heap-allocate
349
354
// it using a box.
350
355
SILDebugVariable DbgVar (decl->isLet (), ArgNo);
351
- SILValue allocBox = SGF.B .createAllocBox (decl, boxType, DbgVar);
356
+ Box = SGF.B .createAllocBox (decl, boxType, DbgVar);
352
357
353
358
// Mark the memory as uninitialized, so DI will track it for us.
354
359
if (kind)
355
- allocBox = SGF.B .createMarkUninitialized (decl, allocBox , kind.getValue ());
360
+ Box = SGF.B .createMarkUninitialized (decl, Box , kind.getValue ());
356
361
357
- SILValue addr = SGF.B .createProjectBox (decl, allocBox, 0 );
358
-
359
- // / Remember that this is the memory location that we're emitting the
360
- // / decl to.
361
- SGF.VarLocs [decl] = SILGenFunction::VarLoc::get (addr, allocBox);
362
+ Addr = SGF.B .createProjectBox (decl, Box, 0 );
362
363
363
364
// Push a cleanup to destroy the local variable. This has to be
364
365
// inactive until the variable is initialized.
365
366
SGF.Cleanups .pushCleanupInState <DestroyLocalVariable>(CleanupState::Dormant,
366
367
decl);
367
368
ReleaseCleanup = SGF.Cleanups .getTopCleanup ();
368
369
369
- // Push a cleanup to deallocate the local variable.
370
- SGF.Cleanups .pushCleanup <DeallocateUninitializedLocalVariable>(decl);
370
+ // Push a cleanup to deallocate the local variable. This references the
371
+ // box directly since it might be activated before we update
372
+ // SGF.VarLocs.
373
+ SGF.Cleanups .pushCleanup <DeallocateUninitializedLocalVariable>(Box);
371
374
DeallocCleanup = SGF.Cleanups .getTopCleanup ();
372
375
}
373
376
@@ -376,8 +379,7 @@ class LocalVariableInitialization : public SingleBufferInitialization {
376
379
}
377
380
378
381
SILValue getAddress () const {
379
- assert (SGF.VarLocs .count (decl) && " did not emit var?!" );
380
- return SGF.VarLocs [decl].value ;
382
+ return Addr;
381
383
}
382
384
383
385
SILValue getAddressForInPlaceInitialization (SILGenFunction &SGF,
@@ -394,6 +396,11 @@ class LocalVariableInitialization : public SingleBufferInitialization {
394
396
}
395
397
396
398
void finishInitialization (SILGenFunction &SGF) override {
399
+ // / Remember that this is the memory location that we've emitted the
400
+ // / decl to.
401
+ assert (SGF.VarLocs .count (decl) == 0 && " Already emitted the local?" );
402
+ SGF.VarLocs [decl] = SILGenFunction::VarLoc::get (Addr, Box);
403
+
397
404
SingleBufferInitialization::finishInitialization (SGF);
398
405
assert (!DidFinish &&
399
406
" called LocalVariableInitialization::finishInitialization twice!" );
@@ -1688,21 +1695,4 @@ void SILGenFunction::destroyLocalVariable(SILLocation silLoc, VarDecl *vd) {
1688
1695
B.emitDestroyValueOperation (silLoc, Val);
1689
1696
else
1690
1697
B.createDestroyAddr (silLoc, Val);
1691
- }
1692
-
1693
- void SILGenFunction::deallocateUninitializedLocalVariable (SILLocation silLoc,
1694
- VarDecl *vd) {
1695
- assert (vd->getDeclContext ()->isLocalContext () &&
1696
- " can't emit a local var for a non-local var decl" );
1697
- assert (vd->hasStorage () && " can't emit storage for a computed variable" );
1698
-
1699
- assert (VarLocs.count (vd) && " var decl wasn't emitted?!" );
1700
-
1701
- auto loc = VarLocs[vd];
1702
-
1703
- // Ignore let values captured without a memory location.
1704
- if (!loc.value ->getType ().isAddress ()) return ;
1705
-
1706
- assert (loc.box && " captured var should have been given a box" );
1707
- B.createDeallocBox (silLoc, loc.box );
1708
- }
1698
+ }
0 commit comments