Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions lib/SILGen/SILGenBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,12 @@ expandTupleTypes(AnyFunctionType::CanParamArrayRef params) {
return results;
}

static CanAnyFunctionType getBridgedBlockType(SILGenModule &SGM,
CanAnyFunctionType blockType) {
return SGM.Types.getBridgedFunctionType(AbstractionPattern(blockType),
blockType, blockType->getExtInfo());
}

static void buildFuncToBlockInvokeBody(SILGenFunction &SGF,
SILLocation loc,
CanAnyFunctionType formalFuncType,
Expand All @@ -368,10 +374,7 @@ static void buildFuncToBlockInvokeBody(SILGenFunction &SGF,
SILFunctionConventions funcConv(funcTy, SGF.SGM.M);

// Make sure we lower the component types of the formal block type.
formalBlockType =
SGF.SGM.Types.getBridgedFunctionType(AbstractionPattern(formalBlockType),
formalBlockType,
formalBlockType->getExtInfo());
formalBlockType = getBridgedBlockType(SGF.SGM, formalBlockType);

// Set up the indirect result.
SILType blockResultTy = blockTy->getAllResultsType();
Expand Down Expand Up @@ -764,6 +767,9 @@ static void buildBlockToFuncThunkBody(SILGenFunction &SGF,
// Collect the native arguments, which should all be +1.
Scope scope(SGF.Cleanups, CleanupLocation::get(loc));

// Make sure we lower the component types of the formal block type.
formalBlockTy = getBridgedBlockType(SGF.SGM, formalBlockTy);

assert(blockTy->getNumParameters() == funcTy->getNumParameters()
&& "block and function types don't match");

Expand Down
2 changes: 2 additions & 0 deletions test/SILGen/Inputs/usr/include/BridgeTestFoundation.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,5 @@ void escapeBlockAlias(dispatch_block_t block);
@interface ObjectWithSplitProperty : NSObject
@property (nonatomic, setter=private_setFlagForSomething:) BOOL flagForSomething;
@end

extern NSString * __nonnull (^ const __nonnull GlobalBlock)(NSString * __nonnull);
8 changes: 8 additions & 0 deletions test/SILGen/objc_blocks_bridging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,11 @@ struct GenericStruct<T> {
// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @_T0Ix_Ixx_IyB_IyBy_TR : $@convention(c) (@inout_aliasable @block_storage @noescape @callee_owned (@owned @noescape @callee_owned () -> ()) -> (), @convention(block) @noescape () -> ()) -> ()
// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @_T0IyB_Ix_TR : $@convention(thin) (@owned @convention(block) @noescape () -> ()) -> ()

// rdar://35402696
func takeOptStringFunction(fn: (String) -> String?) {}
func testGlobalBlock() {
takeOptStringFunction(fn: GlobalBlock)
}
// CHECK-LABEL: sil hidden @_T020objc_blocks_bridging15testGlobalBlockyyF
// CHECK: global_addr @GlobalBlock : $*@convention(block) (NSString) -> @autoreleased Optional<NSString>
// CHECK: function_ref @_T0So8NSStringCABSgIeyBya_S2SIexxo_TR : $@convention(thin) (@owned String, @owned @convention(block) (NSString) -> @autoreleased Optional<NSString>) -> @owned String