25
25
#include " swift/AST/ParameterList.h"
26
26
#include " swift/AST/PropertyWrappers.h"
27
27
#include " swift/Basic/Defer.h"
28
+ #include " swift/Basic/Generators.h"
28
29
#include " swift/SIL/SILArgument.h"
29
30
#include " swift/SIL/SILInstruction.h"
30
31
#include " swift/SIL/SILUndef.h"
33
34
using namespace swift ;
34
35
using namespace Lowering ;
35
36
37
+ namespace {
38
+
39
+ class LoweredParamsInContextGenerator {
40
+ SILGenFunction &SGF;
41
+ ArrayRefGenerator<ArrayRef<SILParameterInfo>> loweredParams;
42
+
43
+ public:
44
+ LoweredParamsInContextGenerator (SILGenFunction &SGF)
45
+ : SGF(SGF),
46
+ loweredParams (SGF.F.getLoweredFunctionType()->getParameters()) {
47
+ }
48
+
49
+ using reference = SILType;
50
+
51
+ // / Get the original (unsubstituted into context) lowered parameter
52
+ // / type information.
53
+ SILParameterInfo getOrigInfo () const {
54
+ return loweredParams.get ();
55
+ }
56
+
57
+ SILType get () const {
58
+ return SGF.getSILTypeInContext (loweredParams.get (),
59
+ SGF.F .getLoweredFunctionType ());
60
+ }
61
+
62
+ SILType claimNext () {
63
+ auto param = get ();
64
+ advance ();
65
+ return param;
66
+ }
67
+
68
+ bool isFinished () const {
69
+ return loweredParams.isFinished ();
70
+ }
71
+
72
+ void advance () {
73
+ loweredParams.advance ();
74
+ }
75
+
76
+ void finish () {
77
+ loweredParams.finish ();
78
+ }
79
+ };
80
+
81
+ } // end anonymous namespace
82
+
83
+ static ManagedValue emitManagedParameter (SILGenFunction &SGF,
84
+ SILValue value, bool isOwned) {
85
+ if (isOwned) {
86
+ return SGF.emitManagedRValueWithCleanup (value);
87
+ } else {
88
+ return ManagedValue::forUnmanaged (value);
89
+ }
90
+ }
91
+
36
92
static SILValue emitConstructorMetatypeArg (SILGenFunction &SGF,
37
93
ValueDecl *ctor) {
38
94
// In addition to the declared arguments, the constructor implicitly takes
@@ -63,14 +119,65 @@ static SILValue emitConstructorMetatypeArg(SILGenFunction &SGF,
63
119
static RValue emitImplicitValueConstructorArg (SILGenFunction &SGF,
64
120
SILLocation loc,
65
121
CanType interfaceType,
66
- DeclContext *DC) {
122
+ DeclContext *DC,
123
+ LoweredParamsInContextGenerator &loweredParamTypes,
124
+ Initialization *argInit = nullptr ) {
67
125
auto type = DC->mapTypeIntoContext (interfaceType)->getCanonicalType ();
68
126
69
127
// Restructure tuple arguments.
70
- if (auto tupleTy = dyn_cast<TupleType>(interfaceType)) {
128
+ if (auto tupleIfaceTy = dyn_cast<TupleType>(interfaceType)) {
129
+ // If we don't have a context to emit into, but we have a tuple
130
+ // that contains pack expansions, create a temporary.
131
+ TemporaryInitializationPtr tempInit;
132
+ if (!argInit && tupleIfaceTy.containsPackExpansionType ()) {
133
+ tempInit = SGF.emitTemporary (loc, SGF.getTypeLowering (type));
134
+ argInit = tempInit.get ();
135
+ }
136
+
137
+ // Split the initialization into element initializations if we have
138
+ // one. We should never have to deal with an initialization that
139
+ // can't be split here.
140
+ assert (!argInit || argInit->canSplitIntoTupleElements ());
141
+ SmallVector<InitializationPtr> initsBuf;
142
+ MutableArrayRef<InitializationPtr> eltInits;
143
+ if (argInit) {
144
+ eltInits = argInit->splitIntoTupleElements (SGF, loc, type, initsBuf);
145
+ assert (eltInits.size () == tupleIfaceTy->getNumElements ());
146
+ }
147
+
71
148
RValue tuple (type);
72
- for (auto fieldType : tupleTy.getElementTypes ())
73
- tuple.addElement (emitImplicitValueConstructorArg (SGF, loc, fieldType, DC));
149
+
150
+ for (auto eltIndex : range (tupleIfaceTy->getNumElements ())) {
151
+ auto eltIfaceType = tupleIfaceTy.getElementType (eltIndex);
152
+ auto eltInit = (argInit ? eltInits[eltIndex].get () : nullptr );
153
+ RValue element = emitImplicitValueConstructorArg (SGF, loc, eltIfaceType,
154
+ DC, loweredParamTypes,
155
+ eltInit);
156
+ if (argInit) {
157
+ assert (element.isInContext ());
158
+ } else {
159
+ tuple.addElement (std::move (element));
160
+ }
161
+ }
162
+
163
+ // If we created a temporary initializer above, finish it and claim
164
+ // the managed buffer.
165
+ if (tempInit) {
166
+ tempInit->finishInitialization (SGF);
167
+
168
+ auto tupleValue = tempInit->getManagedAddress ();
169
+ if (tupleValue.getType ().isLoadable (SGF.F )) {
170
+ tupleValue = SGF.B .createLoadTake (loc, tupleValue);
171
+ }
172
+
173
+ return RValue (SGF, loc, type, tupleValue);
174
+
175
+ // Otherwise, if we have an emitInto, return forInContext().
176
+ } else if (argInit) {
177
+ argInit->finishInitialization (SGF);
178
+ return RValue::forInContext ();
179
+ }
180
+
74
181
return tuple;
75
182
}
76
183
@@ -83,13 +190,51 @@ static RValue emitImplicitValueConstructorArg(SILGenFunction &SGF,
83
190
VD->setSpecifier (ParamSpecifier::Default);
84
191
VD->setInterfaceType (interfaceType);
85
192
86
- auto argType = SGF.getLoweredTypeForFunctionArgument (type);
193
+ auto origParamInfo = loweredParamTypes.getOrigInfo ();
194
+ auto argType = loweredParamTypes.claimNext ();
195
+
87
196
auto *arg = SGF.F .begin ()->createFunctionArgument (argType, VD);
88
- ManagedValue mvArg;
89
- if (arg->getArgumentConvention ().isOwnedConvention ()) {
90
- mvArg = SGF.emitManagedRValueWithCleanup (arg);
91
- } else {
92
- mvArg = ManagedValue::forUnmanaged (arg);
197
+ bool argIsConsumed = origParamInfo.isConsumed ();
198
+
199
+ // If the lowered parameter is a pack expansion, copy/move the pack
200
+ // into the initialization, which we assume is there.
201
+ if (auto packTy = argType.getAs <SILPackType>()) {
202
+ assert (isa<PackExpansionType>(interfaceType));
203
+ assert (packTy->getNumElements () == 1 );
204
+ assert (argInit);
205
+ assert (argInit->canPerformPackExpansionInitialization ());
206
+
207
+ auto expansionTy = packTy->getSILElementType (0 );
208
+ auto openedEnvAndEltTy =
209
+ SGF.createOpenedElementValueEnvironment (expansionTy);
210
+ auto openedEnv = openedEnvAndEltTy.first ;
211
+ auto eltTy = openedEnvAndEltTy.second ;
212
+ auto formalPackType = CanPackType::get (SGF.getASTContext (), {type});
213
+
214
+ SGF.emitDynamicPackLoop (loc, formalPackType, /* component*/ 0 , openedEnv,
215
+ [&](SILValue indexWithinComponent,
216
+ SILValue packExpansionIndex,
217
+ SILValue packIndex) {
218
+ argInit->performPackExpansionInitialization (SGF, loc,
219
+ indexWithinComponent,
220
+ [&](Initialization *eltInit) {
221
+ auto eltAddr =
222
+ SGF.B .createPackElementGet (loc, packIndex, arg, eltTy);
223
+ ManagedValue eltMV = emitManagedParameter (SGF, eltAddr, argIsConsumed);
224
+ eltInit->copyOrInitValueInto (SGF, loc, eltMV, argIsConsumed);
225
+ eltInit->finishInitialization (SGF);
226
+ });
227
+ });
228
+ argInit->finishInitialization (SGF);
229
+ return RValue::forInContext ();
230
+ }
231
+
232
+ ManagedValue mvArg = emitManagedParameter (SGF, arg, argIsConsumed);
233
+
234
+ if (argInit) {
235
+ argInit->copyOrInitValueInto (SGF, loc, mvArg, argIsConsumed);
236
+ argInit->finishInitialization (SGF);
237
+ return RValue::forInContext ();
93
238
}
94
239
95
240
// This can happen if the value is resilient in the calling convention
@@ -164,15 +309,19 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
164
309
AssertingManualScope functionLevelScope (SGF.Cleanups ,
165
310
CleanupLocation (Loc));
166
311
312
+ auto loweredFunctionTy = SGF.F .getLoweredFunctionType ();
313
+
167
314
// FIXME: Handle 'self' along with the other arguments.
315
+ assert (loweredFunctionTy->getNumResults () == 1 );
316
+ auto selfResultInfo = loweredFunctionTy->getResults ()[0 ];
168
317
auto *paramList = ctor->getParameters ();
169
318
auto *selfDecl = ctor->getImplicitSelfDecl ();
170
319
auto selfIfaceTy = selfDecl->getInterfaceType ();
171
- SILType selfTy = SGF.getLoweredTypeForFunctionArgument (selfDecl-> getType () );
320
+ SILType selfTy = SGF.getSILTypeInContext (selfResultInfo, loweredFunctionTy );
172
321
173
322
// Emit the indirect return argument, if any.
174
323
SILValue resultSlot;
175
- if (SILModuleConventions::isReturnedIndirectlyInSIL ( selfTy, SGF. SGM . M )) {
324
+ if (selfTy. isAddress ( )) {
176
325
auto &AC = SGF.getASTContext ();
177
326
auto VD = new (AC) ParamDecl (SourceLoc (), SourceLoc (),
178
327
AC.getIdentifier (" $return_value" ),
@@ -181,21 +330,25 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
181
330
ctor);
182
331
VD->setSpecifier (ParamSpecifier::InOut);
183
332
VD->setInterfaceType (selfIfaceTy);
184
- resultSlot =
185
- SGF.F .begin ()->createFunctionArgument (selfTy.getAddressType (), VD);
333
+ resultSlot = SGF.F .begin ()->createFunctionArgument (selfTy, VD);
186
334
}
187
335
336
+ LoweredParamsInContextGenerator loweredParams (SGF);
337
+
188
338
// Emit the elementwise arguments.
189
339
SmallVector<RValue, 4 > elements;
190
340
for (size_t i = 0 , size = paramList->size (); i < size; ++i) {
191
341
auto ¶m = paramList->get (i);
192
342
193
343
elements.push_back (
194
344
emitImplicitValueConstructorArg (
195
- SGF, Loc, param->getInterfaceType ()->getCanonicalType (), ctor));
345
+ SGF, Loc, param->getInterfaceType ()->getCanonicalType (), ctor,
346
+ loweredParams));
196
347
}
197
348
198
349
emitConstructorMetatypeArg (SGF, ctor);
350
+ (void ) loweredParams.claimNext ();
351
+ loweredParams.finish ();
199
352
200
353
auto *decl = selfTy.getStructOrBoundGenericStruct ();
201
354
assert (decl && " not a struct?!" );
@@ -601,16 +754,21 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) {
601
754
602
755
Scope scope (Cleanups, CleanupLoc);
603
756
757
+ LoweredParamsInContextGenerator loweredParams (*this );
758
+
604
759
// Emit the exploded constructor argument.
605
760
ArgumentSource payload;
606
761
if (element->hasAssociatedValues ()) {
607
762
auto eltArgTy = element->getArgumentInterfaceType ()->getCanonicalType ();
608
- RValue arg = emitImplicitValueConstructorArg (*this , Loc, eltArgTy, element);
763
+ RValue arg = emitImplicitValueConstructorArg (*this , Loc, eltArgTy, element,
764
+ loweredParams);
609
765
payload = ArgumentSource (Loc, std::move (arg));
610
766
}
611
767
612
768
// Emit the metatype argument.
613
769
emitConstructorMetatypeArg (*this , element);
770
+ (void ) loweredParams.claimNext ();
771
+ loweredParams.finish ();
614
772
615
773
// If possible, emit the enum directly into the indirect return.
616
774
SGFContext C = (dest ? SGFContext (dest.get ()) : SGFContext ());
0 commit comments