@@ -462,7 +462,8 @@ namespace {
462462 RValue visitKeyPathExpr (KeyPathExpr *E, SGFContext C);
463463 RValue visitMagicIdentifierLiteralExpr (MagicIdentifierLiteralExpr *E,
464464 SGFContext C);
465- RValue visitCollectionExpr (CollectionExpr *E, SGFContext C);
465+ RValue visitArrayExpr (ArrayExpr *E, SGFContext C);
466+ RValue visitDictionaryExpr (DictionaryExpr *E, SGFContext C);
466467 RValue visitRebindSelfInConstructorExpr (RebindSelfInConstructorExpr *E,
467468 SGFContext C);
468469 RValue visitInjectIntoOptionalExpr (InjectIntoOptionalExpr *E, SGFContext C);
@@ -3601,7 +3602,64 @@ visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *E, SGFContext C) {
36013602 llvm_unreachable (" Unhandled MagicIdentifierLiteralExpr in switch." );
36023603}
36033604
3604- RValue RValueEmitter::visitCollectionExpr (CollectionExpr *E, SGFContext C) {
3605+ RValue RValueEmitter::visitArrayExpr (ArrayExpr *E, SGFContext C) {
3606+ auto loc = SILLocation (E);
3607+ ArgumentScope scope (SGF, loc);
3608+
3609+ CanType elementType = E->getElementType ()->getCanonicalType ();
3610+ CanType arrayTy = ArraySliceType::get (elementType)->getCanonicalType ();
3611+ VarargsInfo varargsInfo =
3612+ emitBeginVarargs (SGF, loc, elementType, arrayTy,
3613+ E->getNumElements (), {});
3614+
3615+ // Cleanups for any elements that have been initialized so far.
3616+ SmallVector<CleanupHandle, 8 > cleanups;
3617+
3618+ for (unsigned index : range (E->getNumElements ())) {
3619+ auto destAddr = varargsInfo.getBaseAddress ();
3620+ if (index != 0 ) {
3621+ SILValue indexValue = SGF.B .createIntegerLiteral (
3622+ loc, SILType::getBuiltinWordType (SGF.getASTContext ()), index);
3623+ destAddr = SGF.B .createIndexAddr (loc, destAddr, indexValue);
3624+ }
3625+ auto &destTL = varargsInfo.getBaseTypeLowering ();
3626+ // Create a dormant cleanup for the value in case we exit before the
3627+ // full array has been constructed.
3628+
3629+ CleanupHandle destCleanup = CleanupHandle::invalid ();
3630+ if (!destTL.isTrivial ()) {
3631+ destCleanup = SGF.enterDestroyCleanup (destAddr);
3632+ SGF.Cleanups .setCleanupState (destCleanup, CleanupState::Dormant);
3633+ cleanups.push_back (destCleanup);
3634+ }
3635+
3636+ TemporaryInitialization init (destAddr, destCleanup);
3637+
3638+ ArgumentSource (E->getElements ()[index])
3639+ .forwardInto (SGF, varargsInfo.getBaseAbstractionPattern (), &init,
3640+ destTL);
3641+ }
3642+
3643+ // Kill the per-element cleanups. The array will take ownership of them.
3644+ for (auto destCleanup : cleanups)
3645+ SGF.Cleanups .setCleanupState (destCleanup, CleanupState::Dead);
3646+
3647+ RValue arg (SGF, loc, arrayTy,
3648+ emitEndVarargs (SGF, loc, std::move (varargsInfo)));
3649+
3650+ arg = scope.popPreservingValue (std::move (arg));
3651+
3652+ // If we're building an array, we don't have to call the initializer;
3653+ // we've already built one.
3654+ if (arrayTy->isEqual (E->getType ()))
3655+ return arg;
3656+
3657+ // Call the builtin initializer.
3658+ return SGF.emitApplyAllocatingInitializer (
3659+ loc, E->getInitializer (), std::move (arg), E->getType (), C);
3660+ }
3661+
3662+ RValue RValueEmitter::visitDictionaryExpr (DictionaryExpr *E, SGFContext C) {
36053663 return visit (E->getSemanticExpr (), C);
36063664}
36073665
0 commit comments