2525#include " swift/AST/ParameterList.h"
2626#include " swift/AST/PropertyWrappers.h"
2727#include " swift/Basic/Defer.h"
28+ #include " swift/Basic/Generators.h"
2829#include " swift/SIL/SILArgument.h"
2930#include " swift/SIL/SILInstruction.h"
3031#include " swift/SIL/SILUndef.h"
3334using namespace swift ;
3435using namespace Lowering ;
3536
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+
3692static SILValue emitConstructorMetatypeArg (SILGenFunction &SGF,
3793 ValueDecl *ctor) {
3894 // In addition to the declared arguments, the constructor implicitly takes
@@ -63,14 +119,65 @@ static SILValue emitConstructorMetatypeArg(SILGenFunction &SGF,
63119static RValue emitImplicitValueConstructorArg (SILGenFunction &SGF,
64120 SILLocation loc,
65121 CanType interfaceType,
66- DeclContext *DC) {
122+ DeclContext *DC,
123+ LoweredParamsInContextGenerator &loweredParamTypes,
124+ Initialization *argInit = nullptr ) {
67125 auto type = DC->mapTypeIntoContext (interfaceType)->getCanonicalType ();
68126
69127 // 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+
71148 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+
74181 return tuple;
75182 }
76183
@@ -83,13 +190,51 @@ static RValue emitImplicitValueConstructorArg(SILGenFunction &SGF,
83190 VD->setSpecifier (ParamSpecifier::Default);
84191 VD->setInterfaceType (interfaceType);
85192
86- auto argType = SGF.getLoweredTypeForFunctionArgument (type);
193+ auto origParamInfo = loweredParamTypes.getOrigInfo ();
194+ auto argType = loweredParamTypes.claimNext ();
195+
87196 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 ();
93238 }
94239
95240 // This can happen if the value is resilient in the calling convention
@@ -164,15 +309,19 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
164309 AssertingManualScope functionLevelScope (SGF.Cleanups ,
165310 CleanupLocation (Loc));
166311
312+ auto loweredFunctionTy = SGF.F .getLoweredFunctionType ();
313+
167314 // FIXME: Handle 'self' along with the other arguments.
315+ assert (loweredFunctionTy->getNumResults () == 1 );
316+ auto selfResultInfo = loweredFunctionTy->getResults ()[0 ];
168317 auto *paramList = ctor->getParameters ();
169318 auto *selfDecl = ctor->getImplicitSelfDecl ();
170319 auto selfIfaceTy = selfDecl->getInterfaceType ();
171- SILType selfTy = SGF.getLoweredTypeForFunctionArgument (selfDecl-> getType () );
320+ SILType selfTy = SGF.getSILTypeInContext (selfResultInfo, loweredFunctionTy );
172321
173322 // Emit the indirect return argument, if any.
174323 SILValue resultSlot;
175- if (SILModuleConventions::isReturnedIndirectlyInSIL ( selfTy, SGF. SGM . M )) {
324+ if (selfTy. isAddress ( )) {
176325 auto &AC = SGF.getASTContext ();
177326 auto VD = new (AC) ParamDecl (SourceLoc (), SourceLoc (),
178327 AC.getIdentifier (" $return_value" ),
@@ -181,21 +330,25 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
181330 ctor);
182331 VD->setSpecifier (ParamSpecifier::InOut);
183332 VD->setInterfaceType (selfIfaceTy);
184- resultSlot =
185- SGF.F .begin ()->createFunctionArgument (selfTy.getAddressType (), VD);
333+ resultSlot = SGF.F .begin ()->createFunctionArgument (selfTy, VD);
186334 }
187335
336+ LoweredParamsInContextGenerator loweredParams (SGF);
337+
188338 // Emit the elementwise arguments.
189339 SmallVector<RValue, 4 > elements;
190340 for (size_t i = 0 , size = paramList->size (); i < size; ++i) {
191341 auto ¶m = paramList->get (i);
192342
193343 elements.push_back (
194344 emitImplicitValueConstructorArg (
195- SGF, Loc, param->getInterfaceType ()->getCanonicalType (), ctor));
345+ SGF, Loc, param->getInterfaceType ()->getCanonicalType (), ctor,
346+ loweredParams));
196347 }
197348
198349 emitConstructorMetatypeArg (SGF, ctor);
350+ (void ) loweredParams.claimNext ();
351+ loweredParams.finish ();
199352
200353 auto *decl = selfTy.getStructOrBoundGenericStruct ();
201354 assert (decl && " not a struct?!" );
@@ -601,16 +754,21 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) {
601754
602755 Scope scope (Cleanups, CleanupLoc);
603756
757+ LoweredParamsInContextGenerator loweredParams (*this );
758+
604759 // Emit the exploded constructor argument.
605760 ArgumentSource payload;
606761 if (element->hasAssociatedValues ()) {
607762 auto eltArgTy = element->getArgumentInterfaceType ()->getCanonicalType ();
608- RValue arg = emitImplicitValueConstructorArg (*this , Loc, eltArgTy, element);
763+ RValue arg = emitImplicitValueConstructorArg (*this , Loc, eltArgTy, element,
764+ loweredParams);
609765 payload = ArgumentSource (Loc, std::move (arg));
610766 }
611767
612768 // Emit the metatype argument.
613769 emitConstructorMetatypeArg (*this , element);
770+ (void ) loweredParams.claimNext ();
771+ loweredParams.finish ();
614772
615773 // If possible, emit the enum directly into the indirect return.
616774 SGFContext C = (dest ? SGFContext (dest.get ()) : SGFContext ());
0 commit comments