@@ -901,68 +901,66 @@ static ManagedValue emitSelfForMemberInit(SILGenFunction &SGF, SILLocation loc,
901
901
SGFAccessKind::Write);
902
902
}
903
903
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) {
918
910
switch (pattern->getKind ()) {
919
911
case PatternKind::Paren:
920
912
return emitMemberInit (SGF, selfDecl,
921
- cast<ParenPattern>(pattern)->getSubPattern (),
922
- std::move (src));
913
+ cast<ParenPattern>(pattern)->getSubPattern ());
923
914
924
915
case PatternKind::Tuple: {
916
+ TupleInitialization *init = new TupleInitialization ();
925
917
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 ()));
933
921
}
934
- break ;
922
+ return InitializationPtr (init) ;
935
923
}
936
924
937
925
case PatternKind::Named: {
938
926
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 ());
943
927
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));
947
947
}
948
948
949
949
case PatternKind::Any:
950
- return ;
950
+ return InitializationPtr ( new BlackHoleInitialization ()); ;
951
951
952
952
case PatternKind::Typed:
953
953
return emitMemberInit (SGF, selfDecl,
954
- cast<TypedPattern>(pattern)->getSubPattern (),
955
- std::move (src));
954
+ cast<TypedPattern>(pattern)->getSubPattern ());
956
955
957
956
case PatternKind::Binding:
958
957
return emitMemberInit (SGF, selfDecl,
959
- cast<BindingPattern>(pattern)->getSubPattern (),
960
- std::move (src));
958
+ cast<BindingPattern>(pattern)->getSubPattern ());
961
959
962
960
#define PATTERN (Name, Parent )
963
961
#define REFUTABLE_PATTERN (Name, Parent ) case PatternKind::Name:
964
962
#include " swift/AST/PatternNodes.def"
965
- llvm_unreachable (" Refutable pattern in pattern binding" );
963
+ llvm_unreachable (" Refutable pattern in stored property pattern binding" );
966
964
}
967
965
}
968
966
@@ -991,6 +989,46 @@ getInitializationTypeInContext(
991
989
return std::make_pair (origType, substType);
992
990
}
993
991
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
+
994
1032
void SILGenFunction::emitMemberInitializers (DeclContext *dc,
995
1033
VarDecl *selfDecl,
996
1034
NominalTypeDecl *nominal) {
@@ -1006,6 +1044,7 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
1006
1044
if (!init) continue ;
1007
1045
1008
1046
auto *varPattern = pbd->getPattern (i);
1047
+
1009
1048
// Cleanup after this initialization.
1010
1049
FullExpr scope (Cleanups, varPattern);
1011
1050
@@ -1016,26 +1055,11 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
1016
1055
AbstractionPattern origType = resultType.first ;
1017
1056
CanType substType = resultType.second ;
1018
1057
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);
1037
1060
1038
- emitMemberInit (*this , selfDecl, varPattern, std::move (result));
1061
+ emitAndStoreInitialValueInto (*this , varPattern, pbd, i, subs,
1062
+ origType, substType, memberInit.get ());
1039
1063
}
1040
1064
}
1041
1065
}
0 commit comments