static ManagedValue emitSelfForMemberInit(SILGenFunction &SGF, SILLocation loc, VarDecl *selfDecl) { CanType selfFormalType = selfDecl->getType()->getCanonicalType(); if (selfFormalType->hasReferenceSemantics()) return SGF.emitRValueForDecl(loc, selfDecl, selfFormalType, AccessSemantics::DirectToStorage, SGFContext::AllowImmediatePlusZero) .getAsSingleValue(SGF, loc); else return SGF.emitAddressOfLocalVarDecl(loc, selfDecl, selfFormalType, SGFAccessKind::Write); }
/// Emit a member initialization for the members described in the /// given pattern from the given source value. static void emitMemberInit(SILGenFunction &SGF, VarDecl *selfDecl, Pattern *pattern, RValue &&src) { switch (pattern->getKind()) { case PatternKind::Paren: return emitMemberInit(SGF, selfDecl, cast<ParenPattern>(pattern)->getSubPattern(), std::move(src)); case PatternKind::Tuple: { auto tuple = cast<TuplePattern>(pattern); auto fields = tuple->getElements(); SmallVector<RValue, 4> elements; std::move(src).extractElements(elements); for (unsigned i = 0, n = fields.size(); i != n; ++i) { emitMemberInit(SGF, selfDecl, fields[i].getPattern(), std::move(elements[i])); } break; } case PatternKind::Named: { auto named = cast<NamedPattern>(pattern); // Form the lvalue referencing this member. WritebackScope scope(SGF); SILLocation loc = pattern; ManagedValue self; CanType selfFormalType = selfDecl->getType() ->getInOutObjectType()->getCanonicalType(); if (selfFormalType->hasReferenceSemantics()) self = SGF.emitRValueForDecl(loc, selfDecl, selfDecl->getType(), AccessSemantics::DirectToStorage, SGFContext::AllowImmediatePlusZero) .getAsSingleValue(SGF, loc); else self = SGF.emitLValueForDecl(loc, selfDecl, src.getType()->getCanonicalType(), AccessKind::Write, AccessSemantics::DirectToStorage); LValue memberRef = SGF.emitPropertyLValue(loc, self, selfFormalType, named->getDecl(), AccessKind::Write, AccessSemantics::DirectToStorage); // Assign to it. SGF.emitAssignToLValue(loc, std::move(src), std::move(memberRef)); return; } case PatternKind::Any: return; case PatternKind::Typed: return emitMemberInit(SGF, selfDecl, cast<TypedPattern>(pattern)->getSubPattern(), std::move(src)); case PatternKind::Var: return emitMemberInit(SGF, selfDecl, cast<VarPattern>(pattern)->getSubPattern(), std::move(src)); #define PATTERN(Name, Parent) #define REFUTABLE_PATTERN(Name, Parent) case PatternKind::Name: #include "swift/AST/PatternNodes.def" llvm_unreachable("Refutable pattern in pattern binding"); } }