Skip to content

Commit b572194

Browse files
authored
Merge pull request #38854 from hborla/wrapped-param-in-init
[SILGen] Fix a couple bugs with wrapped parameters in initializers.
2 parents 861f47f + f302c20 commit b572194

File tree

10 files changed

+176
-81
lines changed

10 files changed

+176
-81
lines changed

lib/AST/Parameter.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ ParameterList *ParameterList::clone(const ASTContext &C,
6060

6161
// Remap the ParamDecls inside of the ParameterList.
6262
for (auto &decl : params) {
63-
bool hadDefaultArgument =
64-
decl->getDefaultArgumentKind() == DefaultArgumentKind::Normal;
63+
auto defaultArgKind = decl->getDefaultArgumentKind();
6564

6665
decl = ParamDecl::cloneWithoutType(C, decl);
6766
if (options & Implicit)
@@ -74,11 +73,18 @@ ParameterList *ParameterList::clone(const ASTContext &C,
7473

7574
// If we're inheriting a default argument, mark it as such.
7675
// FIXME: Figure out how to clone default arguments as well.
77-
if (hadDefaultArgument) {
78-
if (options & Inherited)
76+
if (options & Inherited) {
77+
switch (defaultArgKind) {
78+
case DefaultArgumentKind::Normal:
79+
case DefaultArgumentKind::StoredProperty:
7980
decl->setDefaultArgumentKind(DefaultArgumentKind::Inherited);
80-
else
81-
decl->setDefaultArgumentKind(DefaultArgumentKind::None);
81+
break;
82+
83+
default:
84+
break;
85+
}
86+
} else {
87+
decl->setDefaultArgumentKind(DefaultArgumentKind::None);
8288
}
8389
}
8490

lib/SILGen/SILGen.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,8 +1277,8 @@ emitMarkFunctionEscapeForTopLevelCodeGlobals(SILLocation loc,
12771277
}
12781278

12791279
void SILGenModule::emitAbstractFuncDecl(AbstractFunctionDecl *AFD) {
1280-
// Emit any default argument generators.
1281-
emitDefaultArgGenerators(AFD, AFD->getParameters());
1280+
// Emit default arguments and property wrapper initializers.
1281+
emitArgumentGenerators(AFD, AFD->getParameters());
12821282

12831283
// If this is a function at global scope, it may close over a global variable.
12841284
// If we're emitting top-level code, then emit a "mark_function_escape" that
@@ -1373,6 +1373,9 @@ SILFunction *SILGenModule::emitClosure(AbstractClosureExpr *ce) {
13731373
if (!f->isExternalDeclaration())
13741374
return f;
13751375

1376+
// Emit property wrapper argument generators.
1377+
emitArgumentGenerators(ce, ce->getParameters());
1378+
13761379
emitFunctionDefinition(constant, f);
13771380
return f;
13781381
}
@@ -1559,13 +1562,17 @@ void SILGenModule::emitGlobalAccessor(VarDecl *global,
15591562
emitOrDelayFunction(*this, accessor);
15601563
}
15611564

1562-
void SILGenModule::emitDefaultArgGenerators(SILDeclRef::Loc decl,
1563-
ParameterList *paramList) {
1565+
void SILGenModule::emitArgumentGenerators(SILDeclRef::Loc decl,
1566+
ParameterList *paramList) {
15641567
unsigned index = 0;
15651568
for (auto param : *paramList) {
15661569
if (param->isDefaultArgument())
15671570
emitDefaultArgGenerator(SILDeclRef::getDefaultArgGenerator(decl, index),
15681571
param);
1572+
1573+
if (param->hasExternalPropertyWrapper())
1574+
emitPropertyWrapperBackingInitializer(param);
1575+
15691576
++index;
15701577
}
15711578
}

lib/SILGen/SILGen.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
318318
/// Emits the backing initializer for a property with an attached wrapper.
319319
void emitPropertyWrapperBackingInitializer(VarDecl *var);
320320

321-
/// Emits default argument generators for the given parameter list.
322-
void emitDefaultArgGenerators(SILDeclRef::Loc decl,
323-
ParameterList *paramList);
321+
/// Emits argument generators, including default argument generators and
322+
/// property wrapper argument generators, for the given parameter list.
323+
void emitArgumentGenerators(SILDeclRef::Loc decl, ParameterList *paramList);
324324

325325
/// Emits a thunk from a foreign function to the native Swift convention.
326326
void emitForeignToNativeThunk(SILDeclRef thunk);

lib/SILGen/SILGenFunction.cpp

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -521,27 +521,7 @@ void SILGenFunction::emitFunction(FuncDecl *fd) {
521521
emitDistributedActorFactory(fd);
522522
} else {
523523
// Emit the actual function body as usual
524-
if (llvm::any_of(
525-
*fd->getParameters(),
526-
[](ParamDecl *p){ return p->hasAttachedPropertyWrapper(); })) {
527-
// If any parameters have property wrappers, emit the local auxiliary
528-
// variables before emitting the function body.
529-
LexicalScope BraceScope(*this, CleanupLocation(fd));
530-
for (auto *param : *fd->getParameters()) {
531-
param->visitAuxiliaryDecls([&](VarDecl *auxiliaryVar) {
532-
SILLocation WrapperLoc(auxiliaryVar);
533-
WrapperLoc.markAsPrologue();
534-
if (auto *patternBinding = auxiliaryVar->getParentPatternBinding())
535-
visitPatternBindingDecl(patternBinding);
536-
537-
visit(auxiliaryVar);
538-
});
539-
}
540-
541-
emitStmt(fd->getTypecheckedBody());
542-
} else {
543-
emitStmt(fd->getTypecheckedBody());
544-
}
524+
emitStmt(fd->getTypecheckedBody());
545525
}
546526

547527
emitEpilog(fd);
@@ -559,11 +539,6 @@ void SILGenFunction::emitClosure(AbstractClosureExpr *ace) {
559539
emitProlog(captureInfo, ace->getParameters(), /*selfParam=*/nullptr,
560540
ace, resultIfaceTy, ace->isBodyThrowing(), ace->getLoc());
561541
prepareEpilog(true, ace->isBodyThrowing(), CleanupLocation(ace));
562-
for (auto *param : *ace->getParameters()) {
563-
param->visitAuxiliaryDecls([&](VarDecl *auxiliaryVar) {
564-
visit(auxiliaryVar);
565-
});
566-
}
567542

568543
if (auto *ce = dyn_cast<ClosureExpr>(ace)) {
569544
emitStmt(ce->getBody());

lib/SILGen/SILGenFunction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
376376
/// a local variable.
377377
llvm::DenseMap<ValueDecl*, VarLoc> VarLocs;
378378

379+
/// The local auxiliary declarations for the parameters of this function that
380+
/// need to be emitted inside the next brace statement.
381+
llvm::SmallVector<VarDecl *, 2> LocalAuxiliaryDecls;
382+
379383
// Context information for tracking an `async let` child task.
380384
struct AsyncLetChildTask {
381385
SILValue asyncLet; // RawPointer to the async let state

lib/SILGen/SILGenProlog.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,11 @@ struct ArgumentInitHelper {
244244
}
245245

246246
void emitParam(ParamDecl *PD) {
247-
if (PD->hasExternalPropertyWrapper()) {
248-
auto initInfo = PD->getPropertyWrapperInitializerInfo();
249-
if (initInfo.hasSynthesizedInitializers()) {
250-
SGF.SGM.emitPropertyWrapperBackingInitializer(PD);
251-
}
247+
PD->visitAuxiliaryDecls([&](VarDecl *localVar) {
248+
SGF.LocalAuxiliaryDecls.push_back(localVar);
249+
});
252250

251+
if (PD->hasExternalPropertyWrapper()) {
253252
PD = cast<ParamDecl>(PD->getPropertyWrapperBackingProperty());
254253
}
255254

@@ -307,6 +306,10 @@ static void makeArgument(Type ty, ParamDecl *decl,
307306

308307
void SILGenFunction::bindParameterForForwarding(ParamDecl *param,
309308
SmallVectorImpl<SILValue> &parameters) {
309+
if (param->hasExternalPropertyWrapper()) {
310+
param = cast<ParamDecl>(param->getPropertyWrapperBackingProperty());
311+
}
312+
310313
makeArgument(param->getType(), param, parameters, *this);
311314
}
312315

lib/SILGen/SILGenStmt.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,19 @@ void StmtEmitter::visitBraceStmt(BraceStmt *S) {
282282
const unsigned ThrowStmtType = 3;
283283
const unsigned UnknownStmtType = 4;
284284
unsigned StmtType = UnknownStmtType;
285-
285+
286+
// Emit local auxiliary declarations.
287+
if (!SGF.LocalAuxiliaryDecls.empty()) {
288+
for (auto *var : SGF.LocalAuxiliaryDecls) {
289+
if (auto *patternBinding = var->getParentPatternBinding())
290+
SGF.visit(patternBinding);
291+
292+
SGF.visit(var);
293+
}
294+
295+
SGF.LocalAuxiliaryDecls.clear();
296+
}
297+
286298
for (auto &ESD : S->getElements()) {
287299

288300
if (auto D = ESD.dyn_cast<Decl*>())

lib/SILGen/SILGenType.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,7 @@ class SILGenType : public TypeMemberVisitor<SILGenType> {
11001100
return;
11011101

11021102
// Emit any default argument generators.
1103-
SGM.emitDefaultArgGenerators(EED, EED->getParameterList());
1103+
SGM.emitArgumentGenerators(EED, EED->getParameterList());
11041104
}
11051105

11061106
void visitPatternBindingDecl(PatternBindingDecl *pd) {
@@ -1135,7 +1135,7 @@ class SILGenType : public TypeMemberVisitor<SILGenType> {
11351135
}
11361136

11371137
void visitSubscriptDecl(SubscriptDecl *sd) {
1138-
SGM.emitDefaultArgGenerators(sd, sd->getIndices());
1138+
SGM.emitArgumentGenerators(sd, sd->getIndices());
11391139
visitAbstractStorageDecl(sd);
11401140
}
11411141

@@ -1261,7 +1261,7 @@ class SILGenExtension : public TypeMemberVisitor<SILGenExtension> {
12611261
}
12621262

12631263
void visitSubscriptDecl(SubscriptDecl *sd) {
1264-
SGM.emitDefaultArgGenerators(sd, sd->getIndices());
1264+
SGM.emitArgumentGenerators(sd, sd->getIndices());
12651265
visitAbstractStorageDecl(sd);
12661266
}
12671267

test/SILGen/default_arguments.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,23 @@ func testCallableWithDefault(_ x: CallableWithDefault) {
434434
x(y: 5)
435435
}
436436

437+
enum E {
438+
// CHECK-LABEL: sil hidden [ossa] @$s17default_arguments1EO6ResultV4name9platformsAESS_SaySiGtcfcfA0_ : $@convention(thin) () -> @owned Array<Int>
439+
struct Result {
440+
var name: String
441+
var platforms: [Int] = []
442+
}
443+
444+
// CHECK-LABEL: sil hidden [ossa] @$s17default_arguments1EO4testyyFZ : $@convention(method) (@thin E.Type) -> ()
445+
static func test() {
446+
// CHECK: function_ref @$s17default_arguments1EO6ResultV4name9platformsAESS_SaySiGtcfcfA0_ : $@convention(thin) () -> @owned Array<Int>
447+
// CHECK: function_ref @$s17default_arguments1EO4testyyFZAC6ResultVSS_SaySiGtcfu_ : $@convention(thin) (@guaranteed String, @guaranteed Array<Int>) -> @owned E.Result
448+
449+
// CHECK-LABEL: sil private [ossa] @$s17default_arguments1EO4testyyFZAC6ResultVSS_SaySiGtcfu_ : $@convention(thin) (@guaranteed String, @guaranteed Array<Int>) -> @owned E.Result
450+
var result = Self.Result(name: "")
451+
}
452+
}
453+
437454
// FIXME: Arguably we shouldn't allow calling a constructor like this, as
438455
// we usually require the user write an explicit '.init'.
439456
struct WeirdUMEInitCase {

0 commit comments

Comments
 (0)