@@ -6145,19 +6145,18 @@ static ManagedValue emitDynamicPartialApply(SILGenFunction &SGF,
61456145 return result;
61466146}
61476147
6148- RValue SILGenFunction::emitDynamicMemberRefExpr (DynamicMemberRefExpr *e ,
6149- SGFContext c) {
6150- // Emit the operand.
6151- ManagedValue base = emitRValueAsSingleValue (e-> getBase ());
6148+ RValue SILGenFunction::emitDynamicMemberRef (SILLocation loc, SILValue operand ,
6149+ ConcreteDeclRef memberRef,
6150+ CanType refTy, SGFContext C) {
6151+ assert (refTy-> isOptional ());
61526152
6153- SILValue operand = base.getValue ();
6154- if (!e->getMember ().getDecl ()->isInstanceMember ()) {
6153+ if (!memberRef.getDecl ()->isInstanceMember ()) {
61556154 auto metatype = operand->getType ().castTo <MetatypeType>();
61566155 assert (metatype->getRepresentation () == MetatypeRepresentation::Thick);
61576156 metatype = CanMetatypeType::get (metatype.getInstanceType (),
61586157 MetatypeRepresentation::ObjC);
6159- operand = B.createThickToObjCMetatype (e, operand,
6160- SILType::getPrimitiveObjectType (metatype));
6158+ operand = B.createThickToObjCMetatype (
6159+ loc, operand, SILType::getPrimitiveObjectType (metatype));
61616160 }
61626161
61636162 // Create the continuation block.
@@ -6169,39 +6168,34 @@ RValue SILGenFunction::emitDynamicMemberRefExpr(DynamicMemberRefExpr *e,
61696168 // Create the has-member block.
61706169 SILBasicBlock *hasMemberBB = createBasicBlock ();
61716170
6172- // The continuation block
6173- auto memberMethodTy = e->getType ()->getOptionalObjectType ();
6174-
6175- const TypeLowering &optTL = getTypeLowering (e->getType ());
6171+ const TypeLowering &optTL = getTypeLowering (refTy);
61766172 auto loweredOptTy = optTL.getLoweredType ();
61776173
6178- SILValue optTemp = emitTemporaryAllocation (e , loweredOptTy);
6174+ SILValue optTemp = emitTemporaryAllocation (loc , loweredOptTy);
61796175
61806176 // Create the branch.
61816177 FuncDecl *memberFunc;
6182- if (auto *VD = dyn_cast<VarDecl>(e-> getMember () .getDecl ())) {
6178+ if (auto *VD = dyn_cast<VarDecl>(memberRef .getDecl ())) {
61836179 memberFunc = VD->getOpaqueAccessor (AccessorKind::Get);
6184- // FIXME: Verify ExtInfo state is correct, not working by accident.
6185- CanFunctionType::ExtInfo info;
6186- memberMethodTy = FunctionType::get ({}, memberMethodTy, info);
6187- } else
6188- memberFunc = cast<FuncDecl>(e->getMember ().getDecl ());
6180+ } else {
6181+ memberFunc = cast<FuncDecl>(memberRef.getDecl ());
6182+ }
61896183 auto member = SILDeclRef (memberFunc, SILDeclRef::Kind::Func)
61906184 .asForeign ();
6191- B.createDynamicMethodBranch (e , operand, member, hasMemberBB, noMemberBB);
6185+ B.createDynamicMethodBranch (loc , operand, member, hasMemberBB, noMemberBB);
61926186
61936187 // Create the has-member branch.
61946188 {
61956189 B.emitBlock (hasMemberBB);
61966190
6197- FullExpr hasMemberScope (Cleanups, CleanupLocation (e ));
6191+ FullExpr hasMemberScope (Cleanups, CleanupLocation (loc ));
61986192
61996193 // The argument to the has-member block is the uncurried method.
6200- auto valueTy = e-> getType ()-> getCanonicalType () .getOptionalObjectType ();
6194+ const CanType valueTy = refTy .getOptionalObjectType ();
62016195 CanFunctionType methodTy;
62026196
62036197 // For a computed variable, we want the getter.
6204- if (isa<VarDecl>(e-> getMember () .getDecl ())) {
6198+ if (isa<VarDecl>(memberRef .getDecl ())) {
62056199 // FIXME: Verify ExtInfo state is correct, not working by accident.
62066200 CanFunctionType::ExtInfo info;
62076201 methodTy = CanFunctionType::get ({}, valueTy, info);
@@ -6213,50 +6207,49 @@ RValue SILGenFunction::emitDynamicMemberRefExpr(DynamicMemberRefExpr *e,
62136207 // TODO: instead of building this and then potentially converting, we
62146208 // should just build a single thunk.
62156209 auto foreignMethodTy =
6216- getPartialApplyOfDynamicMethodFormalType (SGM, member, e-> getMember () );
6210+ getPartialApplyOfDynamicMethodFormalType (SGM, member, memberRef );
62176211
62186212 // FIXME: Verify ExtInfo state is correct, not working by accident.
62196213 CanFunctionType::ExtInfo info;
62206214 FunctionType::Param arg (operand->getType ().getASTType ());
6221- auto memberFnTy =
6222- CanFunctionType::get ({arg}, memberMethodTy->getCanonicalType (), info);
6215+ auto memberFnTy = CanFunctionType::get ({arg}, methodTy, info);
62236216
62246217 auto loweredMethodTy = getDynamicMethodLoweredType (SGM.M , member,
62256218 memberFnTy);
62266219 SILValue memberArg =
62276220 hasMemberBB->createPhiArgument (loweredMethodTy, OwnershipKind::Owned);
62286221
62296222 // Create the result value.
6230- Scope applyScope (Cleanups, CleanupLocation (e));
6231- ManagedValue result =
6232- emitDynamicPartialApply (*this , e, memberArg, operand,
6233- foreignMethodTy, methodTy);
6223+ Scope applyScope (Cleanups, CleanupLocation (loc));
6224+ ManagedValue result = emitDynamicPartialApply (
6225+ *this , loc, memberArg, operand, foreignMethodTy, methodTy);
62346226
62356227 RValue resultRV;
6236- if (isa<VarDecl>(e-> getMember () .getDecl ())) {
6237- resultRV = emitMonomorphicApply (e, result, {},
6238- foreignMethodTy.getResult (), valueTy ,
6239- ApplyOptions (), None, None);
6228+ if (isa<VarDecl>(memberRef .getDecl ())) {
6229+ resultRV =
6230+ emitMonomorphicApply (loc, result, {}, foreignMethodTy.getResult (),
6231+ valueTy, ApplyOptions (), None, None);
62406232 } else {
6241- resultRV = RValue (*this , e , valueTy, result);
6233+ resultRV = RValue (*this , loc , valueTy, result);
62426234 }
62436235
62446236 // Package up the result in an optional.
6245- emitInjectOptionalValueInto (e, {e, std::move (resultRV)}, optTemp, optTL);
6237+ emitInjectOptionalValueInto (loc, {loc, std::move (resultRV)}, optTemp,
6238+ optTL);
62466239
62476240 applyScope.pop ();
62486241 // Branch to the continuation block.
6249- B.createBranch (e , contBB);
6242+ B.createBranch (loc , contBB);
62506243 }
62516244
62526245 // Create the no-member branch.
62536246 {
62546247 B.emitBlock (noMemberBB);
62556248
6256- emitInjectOptionalNothingInto (e , optTemp, optTL);
6249+ emitInjectOptionalNothingInto (loc , optTemp, optTL);
62576250
62586251 // Branch to the continuation block.
6259- B.createBranch (e , contBB);
6252+ B.createBranch (loc , contBB);
62606253 }
62616254
62626255 // Emit the continuation block.
@@ -6265,21 +6258,19 @@ RValue SILGenFunction::emitDynamicMemberRefExpr(DynamicMemberRefExpr *e,
62656258 // Package up the result.
62666259 auto optResult = optTemp;
62676260 if (optTL.isLoadable ())
6268- optResult = optTL.emitLoad (B, e, optResult, LoadOwnershipQualifier::Take);
6269- return RValue (*this , e, emitManagedRValueWithCleanup (optResult, optTL));
6261+ optResult = optTL.emitLoad (B, loc, optResult, LoadOwnershipQualifier::Take);
6262+ return RValue (*this , loc, refTy,
6263+ emitManagedRValueWithCleanup (optResult, optTL));
62706264}
62716265
6272- RValue SILGenFunction::emitDynamicSubscriptExpr (DynamicSubscriptExpr *e,
6266+ RValue
6267+ SILGenFunction::emitDynamicSubscriptGetterApply (SILLocation loc,
6268+ SILValue operand,
6269+ ConcreteDeclRef subscriptRef,
6270+ PreparedArguments &&indexArgs,
6271+ CanType resultTy,
62736272 SGFContext c) {
6274- // Emit the base operand.
6275- ManagedValue managedBase = emitRValueAsSingleValue (e->getBase ());
6276-
6277- SILValue base = managedBase.getValue ();
6278-
6279- // Emit the index.
6280- auto *indexExpr = e->getArgs ()->getUnaryExpr ();
6281- assert (indexExpr);
6282- RValue index = emitRValue (indexExpr);
6273+ assert (resultTy->isOptional ());
62836274
62846275 // Create the continuation block.
62856276 SILBasicBlock *contBB = createBasicBlock ();
@@ -6290,72 +6281,77 @@ RValue SILGenFunction::emitDynamicSubscriptExpr(DynamicSubscriptExpr *e,
62906281 // Create the has-member block.
62916282 SILBasicBlock *hasMemberBB = createBasicBlock ();
62926283
6293- const TypeLowering &optTL = getTypeLowering (e->getType ());
6294- auto loweredOptTy = optTL.getLoweredType ();
6295- SILValue optTemp = emitTemporaryAllocation (e, loweredOptTy);
6284+ const TypeLowering &optTL = getTypeLowering (resultTy);
6285+ const SILValue optTemp = emitTemporaryAllocation (loc, optTL.getLoweredType ());
62966286
62976287 // Create the branch.
6298- auto subscriptDecl = cast<SubscriptDecl>(e-> getMember () .getDecl ());
6288+ auto * subscriptDecl = cast<SubscriptDecl>(subscriptRef .getDecl ());
62996289 auto member = SILDeclRef (subscriptDecl->getOpaqueAccessor (AccessorKind::Get),
63006290 SILDeclRef::Kind::Func)
63016291 .asForeign ();
6302- B.createDynamicMethodBranch (e, base , member, hasMemberBB, noMemberBB);
6292+ B.createDynamicMethodBranch (loc, operand , member, hasMemberBB, noMemberBB);
63036293
63046294 // Create the has-member branch.
63056295 {
63066296 B.emitBlock (hasMemberBB);
63076297
6308- FullExpr hasMemberScope (Cleanups, CleanupLocation (e ));
6298+ FullExpr hasMemberScope (Cleanups, CleanupLocation (loc ));
63096299
63106300 // The argument to the has-member block is the uncurried method.
63116301 // Build the substituted getter type from the AST nodes.
6312- auto valueTy = e-> getType ()-> getCanonicalType () .getOptionalObjectType ();
6302+ const CanType valueTy = resultTy .getOptionalObjectType ();
63136303
6314- // Objective-C subscripts only ever have a single parameter.
6315- //
63166304 // FIXME: Verify ExtInfo state is correct, not working by accident.
63176305 CanFunctionType::ExtInfo methodInfo;
6318- FunctionType::Param indexArg (indexExpr-> getType ()-> getCanonicalType ());
6319- auto methodTy = CanFunctionType::get ({indexArg} , valueTy, methodInfo);
6306+ const auto methodTy =
6307+ CanFunctionType::get (indexArgs. getParams () , valueTy, methodInfo);
63206308 auto foreignMethodTy =
6321- getPartialApplyOfDynamicMethodFormalType (SGM, member, e-> getMember () );
6309+ getPartialApplyOfDynamicMethodFormalType (SGM, member, subscriptRef );
63226310
63236311 // FIXME: Verify ExtInfo state is correct, not working by accident.
63246312 CanFunctionType::ExtInfo functionInfo;
6325- FunctionType::Param baseArg (base ->getType ().getASTType ());
6313+ FunctionType::Param baseArg (operand ->getType ().getASTType ());
63266314 auto functionTy = CanFunctionType::get ({baseArg}, methodTy, functionInfo);
63276315 auto loweredMethodTy = getDynamicMethodLoweredType (SGM.M , member,
63286316 functionTy);
63296317 SILValue memberArg =
63306318 hasMemberBB->createPhiArgument (loweredMethodTy, OwnershipKind::Owned);
63316319 // Emit the application of 'self'.
6332- Scope applyScope (Cleanups, CleanupLocation (e));
6333- ManagedValue result = emitDynamicPartialApply (*this , e, memberArg, base,
6334- foreignMethodTy, methodTy);
6335- // Emit the index.
6336- llvm::SmallVector<ManagedValue, 2 > indexArgs;
6337- std::move (index).getAll (indexArgs);
6338-
6339- auto resultRV = emitMonomorphicApply (e, result, indexArgs,
6320+ Scope applyScope (Cleanups, CleanupLocation (loc));
6321+ ManagedValue result = emitDynamicPartialApply (
6322+ *this , loc, memberArg, operand, foreignMethodTy, methodTy);
6323+
6324+ // Collect the index values for application.
6325+ llvm::SmallVector<ManagedValue, 2 > indexValues;
6326+ for (auto &source : std::move (indexArgs).getSources ()) {
6327+ // @objc subscripts cannot have 'inout' indices.
6328+ RValue rVal = std::move (source).asKnownRValue (*this );
6329+
6330+ // @objc subscripts cannot have tuple indices.
6331+ indexValues.push_back (std::move (rVal).getScalarValue ());
6332+ }
6333+
6334+ auto resultRV = emitMonomorphicApply (loc, result, indexValues,
63406335 foreignMethodTy.getResult (), valueTy,
63416336 ApplyOptions (), None, None);
63426337
63436338 // Package up the result in an optional.
6344- emitInjectOptionalValueInto (e, {e, std::move (resultRV)}, optTemp, optTL);
6339+ emitInjectOptionalValueInto (loc, {loc, std::move (resultRV)}, optTemp,
6340+ optTL);
63456341
63466342 applyScope.pop ();
63476343 // Branch to the continuation block.
6348- B.createBranch (e , contBB);
6344+ B.createBranch (loc , contBB);
63496345 }
63506346
63516347 // Create the no-member branch.
63526348 {
63536349 B.emitBlock (noMemberBB);
63546350
6355- emitInjectOptionalNothingInto (e , optTemp, optTL);
6351+ emitInjectOptionalNothingInto (loc , optTemp, optTL);
63566352
63576353 // Branch to the continuation block.
6358- B.createBranch (e , contBB);
6354+ B.createBranch (loc , contBB);
63596355 }
63606356
63616357 // Emit the continuation block.
@@ -6364,8 +6360,9 @@ RValue SILGenFunction::emitDynamicSubscriptExpr(DynamicSubscriptExpr *e,
63646360 // Package up the result.
63656361 auto optResult = optTemp;
63666362 if (optTL.isLoadable ())
6367- optResult = optTL.emitLoad (B, e, optResult, LoadOwnershipQualifier::Take);
6368- return RValue (*this , e, emitManagedRValueWithCleanup (optResult, optTL));
6363+ optResult = optTL.emitLoad (B, loc, optResult, LoadOwnershipQualifier::Take);
6364+ return RValue (*this , loc, resultTy,
6365+ emitManagedRValueWithCleanup (optResult, optTL));
63696366}
63706367
63716368SmallVector<ManagedValue, 4 > SILGenFunction::emitKeyPathSubscriptOperands (
0 commit comments