Skip to content

Commit b3087e3

Browse files
committed
SILGen: suppor struct element address projections in emitBuiltinAddressOfBorrowBuiltins
1 parent a38db64 commit b3087e3

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,29 @@ static ManagedValue emitBuiltinUnprotectedAddressOf(SILGenFunction &SGF,
477477
/*stackProtected=*/ false);
478478
}
479479

480+
// Like `tryEmitAddressableParameterAsAddress`, but also handles struct element projections.
481+
static SILValue emitAddressOf(Expr *e, SILGenFunction &SGF, SILLocation loc) {
482+
483+
if (auto *memberRef = dyn_cast<MemberRefExpr>(e)) {
484+
VarDecl *fieldDecl = dyn_cast<VarDecl>(memberRef->getDecl().getDecl());
485+
if (!fieldDecl)
486+
return SILValue();
487+
SILValue addr = emitAddressOf(memberRef->getBase(), SGF, loc);
488+
if (!addr)
489+
return SILValue();
490+
if (addr->getType().getStructOrBoundGenericStruct() != fieldDecl->getDeclContext())
491+
return SILValue();
492+
return SGF.B.createStructElementAddr(loc, addr, fieldDecl);
493+
}
494+
495+
if (auto addressableAddr = SGF.tryEmitAddressableParameterAsAddress(
496+
ArgumentSource(e),
497+
ValueOwnership::Shared)) {
498+
return addressableAddr.getValue();
499+
}
500+
return SILValue();
501+
}
502+
480503
/// Specialized emitter for Builtin.addressOfBorrow.
481504
static ManagedValue emitBuiltinAddressOfBorrowBuiltins(SILGenFunction &SGF,
482505
SILLocation loc,
@@ -491,15 +514,11 @@ static ManagedValue emitBuiltinAddressOfBorrowBuiltins(SILGenFunction &SGF,
491514

492515
auto argument = (*argsOrError)[0];
493516

494-
SILValue addr;
495517
// Try to borrow the argument at +0 indirect.
496518
// If the argument is a reference to a borrowed addressable parameter, then
497519
// use that parameter's stable address.
498-
if (auto addressableAddr = SGF.tryEmitAddressableParameterAsAddress(
499-
ArgumentSource(argument),
500-
ValueOwnership::Shared)) {
501-
addr = addressableAddr.getValue();
502-
} else {
520+
SILValue addr = emitAddressOf(argument, SGF, loc);
521+
if (!addr) {
503522
// We otherwise only support the builtin applied to values that
504523
// are naturally emitted borrowed in memory. (But it would probably be good
505524
// to phase this out since it's not really well-defined how long

0 commit comments

Comments
 (0)