@@ -901,68 +901,66 @@ static ManagedValue emitSelfForMemberInit(SILGenFunction &SGF, SILLocation loc,
901901 SGFAccessKind::Write);
902902}
903903
904- static LValue emitLValueForMemberInit (SILGenFunction &SGF, SILLocation loc,
905- VarDecl *selfDecl,
906- VarDecl *property) {
907- CanType selfFormalType = selfDecl->getType ()->getCanonicalType ();
908- auto self = emitSelfForMemberInit (SGF, loc, selfDecl);
909- return SGF.emitPropertyLValue (loc, self, selfFormalType, property,
910- LValueOptions (), SGFAccessKind::Write,
911- AccessSemantics::DirectToStorage);
912- }
913-
914- // / Emit a member initialization for the members described in the
915- // / given pattern from the given source value.
916- static void emitMemberInit (SILGenFunction &SGF, VarDecl *selfDecl,
917- Pattern *pattern, RValue &&src) {
904+ // FIXME: Can emitMemberInit() share code with InitializationForPattern in
905+ // SILGenDecl.cpp? Note that this version operates on stored properties of
906+ // types, whereas the former only knows how to handle local bindings, but
907+ // we could generalize it.
908+ static InitializationPtr
909+ emitMemberInit (SILGenFunction &SGF, VarDecl *selfDecl, Pattern *pattern) {
918910 switch (pattern->getKind ()) {
919911 case PatternKind::Paren:
920912 return emitMemberInit (SGF, selfDecl,
921- cast<ParenPattern>(pattern)->getSubPattern (),
922- std::move (src));
913+ cast<ParenPattern>(pattern)->getSubPattern ());
923914
924915 case PatternKind::Tuple: {
916+ TupleInitialization *init = new TupleInitialization ();
925917 auto tuple = cast<TuplePattern>(pattern);
926- auto fields = tuple->getElements ();
927-
928- SmallVector<RValue, 4 > elements;
929- std::move (src).extractElements (elements);
930- for (unsigned i = 0 , n = fields.size (); i != n; ++i) {
931- emitMemberInit (SGF, selfDecl, fields[i].getPattern (),
932- std::move (elements[i]));
918+ for (auto &elt : tuple->getElements ()) {
919+ init->SubInitializations .push_back (
920+ emitMemberInit (SGF, selfDecl, elt.getPattern ()));
933921 }
934- break ;
922+ return InitializationPtr (init) ;
935923 }
936924
937925 case PatternKind::Named: {
938926 auto named = cast<NamedPattern>(pattern);
939- // Form the lvalue referencing this member.
940- FormalEvaluationScope scope (SGF);
941- LValue memberRef = emitLValueForMemberInit (SGF, pattern, selfDecl,
942- named->getDecl ());
943927
944- // Assign to it.
945- SGF.emitAssignToLValue (pattern, std::move (src), std::move (memberRef));
946- return ;
928+ auto self = emitSelfForMemberInit (SGF, pattern, selfDecl);
929+
930+ auto *field = named->getDecl ();
931+
932+ auto selfTy = self.getType ();
933+ auto fieldTy =
934+ selfTy.getFieldType (field, SGF.SGM .M , SGF.getTypeExpansionContext ());
935+ SILValue slot;
936+
937+ if (auto *structDecl = dyn_cast<StructDecl>(field->getDeclContext ())) {
938+ slot = SGF.B .createStructElementAddr (pattern, self.forward (SGF), field,
939+ fieldTy.getAddressType ());
940+ } else {
941+ assert (isa<ClassDecl>(field->getDeclContext ()));
942+ slot = SGF.B .createRefElementAddr (pattern, self.forward (SGF), field,
943+ fieldTy.getAddressType ());
944+ }
945+
946+ return InitializationPtr (new KnownAddressInitialization (slot));
947947 }
948948
949949 case PatternKind::Any:
950- return ;
950+ return InitializationPtr ( new BlackHoleInitialization ()); ;
951951
952952 case PatternKind::Typed:
953953 return emitMemberInit (SGF, selfDecl,
954- cast<TypedPattern>(pattern)->getSubPattern (),
955- std::move (src));
954+ cast<TypedPattern>(pattern)->getSubPattern ());
956955
957956 case PatternKind::Binding:
958957 return emitMemberInit (SGF, selfDecl,
959- cast<BindingPattern>(pattern)->getSubPattern (),
960- std::move (src));
958+ cast<BindingPattern>(pattern)->getSubPattern ());
961959
962960#define PATTERN (Name, Parent )
963961#define REFUTABLE_PATTERN (Name, Parent ) case PatternKind::Name:
964962#include " swift/AST/PatternNodes.def"
965- llvm_unreachable (" Refutable pattern in pattern binding" );
963+ llvm_unreachable (" Refutable pattern in stored property pattern binding" );
966964 }
967965}
968966
@@ -991,6 +989,46 @@ getInitializationTypeInContext(
991989 return std::make_pair (origType, substType);
992990}
993991
992+ static void
993+ emitAndStoreInitialValueInto (SILGenFunction &SGF,
994+ SILLocation loc,
995+ PatternBindingDecl *pbd, unsigned i,
996+ SubstitutionMap subs,
997+ AbstractionPattern origType,
998+ CanType substType,
999+ Initialization *init) {
1000+ bool injectIntoWrapper = false ;
1001+ if (auto singleVar = pbd->getSingleVar ()) {
1002+ auto originalVar = singleVar->getOriginalWrappedProperty ();
1003+ if (originalVar &&
1004+ originalVar->isPropertyMemberwiseInitializedWithWrappedType ()) {
1005+ injectIntoWrapper = true ;
1006+ }
1007+ }
1008+
1009+ SGFContext C = (injectIntoWrapper ? SGFContext () : SGFContext (init));
1010+
1011+ RValue result = SGF.emitApplyOfStoredPropertyInitializer (
1012+ pbd->getExecutableInit (i),
1013+ pbd->getAnchoringVarDecl (i),
1014+ subs, substType, origType, C);
1015+
1016+ // need to store result into the init if its in context
1017+
1018+ // If we have the backing storage for a property with an attached
1019+ // property wrapper initialized with `=`, inject the value into an
1020+ // instance of the wrapper.
1021+ if (injectIntoWrapper) {
1022+ auto *singleVar = pbd->getSingleVar ();
1023+ result = maybeEmitPropertyWrapperInitFromValue (
1024+ SGF, pbd->getExecutableInit (i),
1025+ singleVar, subs, std::move (result));
1026+ }
1027+
1028+ if (!result.isInContext ())
1029+ std::move (result).forwardInto (SGF, loc, init);
1030+ }
1031+
9941032void SILGenFunction::emitMemberInitializers (DeclContext *dc,
9951033 VarDecl *selfDecl,
9961034 NominalTypeDecl *nominal) {
@@ -1006,6 +1044,7 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
10061044 if (!init) continue ;
10071045
10081046 auto *varPattern = pbd->getPattern (i);
1047+
10091048 // Cleanup after this initialization.
10101049 FullExpr scope (Cleanups, varPattern);
10111050
@@ -1016,26 +1055,11 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
10161055 AbstractionPattern origType = resultType.first ;
10171056 CanType substType = resultType.second ;
10181057
1019- // FIXME: Can emitMemberInit() share code with
1020- // InitializationForPattern in SILGenDecl.cpp?
1021- RValue result = emitApplyOfStoredPropertyInitializer (
1022- init, pbd->getAnchoringVarDecl (i), subs,
1023- substType, origType,
1024- SGFContext ());
1025-
1026- // If we have the backing storage for a property with an attached
1027- // property wrapper initialized with `=`, inject the value into an
1028- // instance of the wrapper.
1029- if (auto singleVar = pbd->getSingleVar ()) {
1030- auto originalVar = singleVar->getOriginalWrappedProperty ();
1031- if (originalVar &&
1032- originalVar->isPropertyMemberwiseInitializedWithWrappedType ()) {
1033- result = maybeEmitPropertyWrapperInitFromValue (
1034- *this , init, singleVar, subs, std::move (result));
1035- }
1036- }
1058+ // Figure out what we're initializing.
1059+ auto memberInit = emitMemberInit (*this , selfDecl, varPattern);
10371060
1038- emitMemberInit (*this , selfDecl, varPattern, std::move (result));
1061+ emitAndStoreInitialValueInto (*this , varPattern, pbd, i, subs,
1062+ origType, substType, memberInit.get ());
10391063 }
10401064 }
10411065 }
0 commit comments