Skip to content

Commit e4cb1d7

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-next
2 parents 91ba2d8 + d767b25 commit e4cb1d7

File tree

14 files changed

+117
-49
lines changed

14 files changed

+117
-49
lines changed

include/swift/AST/ModuleLoader.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ class NominalTypeDecl;
3838

3939
enum class KnownProtocolKind : uint8_t;
4040

41+
enum class Bridgeability : unsigned {
42+
/// This context does not permit bridging at all. For example, the
43+
/// target of a C pointer.
44+
None,
45+
46+
/// This context permits all kinds of bridging. For example, the
47+
/// imported result of a method declaration.
48+
Full
49+
};
50+
4151
/// Records dependencies on files outside of the current module;
4252
/// implemented in terms of a wrapped clang::DependencyCollector.
4353
class DependencyTracker {

include/swift/SIL/TypeLowering.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace clang {
3131

3232
namespace swift {
3333
class AnyFunctionRef;
34+
enum class Bridgeability : unsigned;
3435
class ForeignErrorConvention;
3536
enum IsInitialization_t : bool;
3637
enum IsTake_t : bool;
@@ -851,6 +852,7 @@ class TypeConverter {
851852
/// Map an AST-level type to the corresponding foreign representation type we
852853
/// implicitly convert to for a given calling convention.
853854
Type getLoweredBridgedType(AbstractionPattern pattern, Type t,
855+
Bridgeability bridging,
854856
SILFunctionTypeRepresentation rep,
855857
BridgedTypePurpose purpose);
856858

@@ -871,7 +873,8 @@ class TypeConverter {
871873
/// Given a function type, yield its bridged formal type.
872874
CanAnyFunctionType getBridgedFunctionType(AbstractionPattern fnPattern,
873875
CanAnyFunctionType fnType,
874-
AnyFunctionType::ExtInfo extInfo);
876+
AnyFunctionType::ExtInfo extInfo,
877+
Bridgeability bridging);
875878

876879
/// Given a referenced value and the substituted formal type of a
877880
/// resulting l-value expression, produce the substituted formal
@@ -975,22 +978,26 @@ class TypeConverter {
975978
CanType getLoweredRValueType(AbstractionPattern origType, CanType substType);
976979

977980
Type getLoweredCBridgedType(AbstractionPattern pattern, Type t,
978-
bool canBridgeBool,
979-
bool bridgedCollectionsAreOptional);
981+
Bridgeability bridging,
982+
SILFunctionTypeRepresentation rep,
983+
BridgedTypePurpose purpose);
980984

981985
AnyFunctionType::Param
982986
getBridgedParam(SILFunctionTypeRepresentation rep,
983987
AbstractionPattern pattern,
984-
AnyFunctionType::Param param);
988+
AnyFunctionType::Param param,
989+
Bridgeability bridging);
985990

986991
void getBridgedParams(SILFunctionTypeRepresentation rep,
987992
AbstractionPattern pattern,
988993
ArrayRef<AnyFunctionType::Param> params,
989-
SmallVectorImpl<AnyFunctionType::Param> &bridged);
994+
SmallVectorImpl<AnyFunctionType::Param> &bridged,
995+
Bridgeability bridging);
990996

991997
CanType getBridgedResultType(SILFunctionTypeRepresentation rep,
992998
AbstractionPattern pattern,
993999
CanType result,
1000+
Bridgeability bridging,
9941001
bool suppressOptional);
9951002
};
9961003

lib/ClangImporter/ImporterImpl.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,6 @@ enum class ImportTypeKind {
181181
Enum
182182
};
183183

184-
enum class Bridgeability {
185-
/// This context does not permit bridging at all. For example, the
186-
/// target of a C pointer.
187-
None,
188-
189-
/// This context permits all kinds of bridging. For example, the
190-
/// imported result of a method declaration.
191-
Full
192-
};
193-
194184
/// Controls whether a typedef for \p type should name the fully-bridged Swift
195185
/// type or the original Clang type.
196186
///

lib/SIL/AbstractionPattern.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ static const clang::Type *getClangType(const clang::Decl *decl) {
6060
return cast<clang::ObjCPropertyDecl>(decl)->getType().getTypePtr();
6161
}
6262

63+
static Bridgeability getClangDeclBridgeability(const clang::Decl *decl) {
64+
// These declarations are always imported without bridging (for now).
65+
if (isa<clang::VarDecl>(decl) ||
66+
isa<clang::FieldDecl>(decl) ||
67+
isa<clang::IndirectFieldDecl>(decl))
68+
return Bridgeability::None;
69+
70+
// Functions and methods always use normal bridging.
71+
return Bridgeability::Full;
72+
}
73+
6374
AbstractionPattern
6475
TypeConverter::getAbstractionPattern(VarDecl *var, bool isNonObjC) {
6576
CanGenericSignature genericSig;
@@ -77,7 +88,7 @@ TypeConverter::getAbstractionPattern(VarDecl *var, bool isNonObjC) {
7788
auto contextType = var->getDeclContext()->mapTypeIntoContext(swiftType);
7889
swiftType = getLoweredBridgedType(
7990
AbstractionPattern(genericSig, swiftType, clangType),
80-
contextType,
91+
contextType, getClangDeclBridgeability(clangDecl),
8192
SILFunctionTypeRepresentation::CFunctionPointer,
8293
TypeConverter::ForMemory)->getCanonicalType();
8394
return AbstractionPattern(genericSig, swiftType, clangType);

lib/SIL/Bridging.cpp

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@ SILType TypeConverter::getLoweredTypeOfGlobal(VarDecl *var) {
3838
AnyFunctionType::Param
3939
TypeConverter::getBridgedParam(SILFunctionTypeRepresentation rep,
4040
AbstractionPattern pattern,
41-
AnyFunctionType::Param param) {
41+
AnyFunctionType::Param param,
42+
Bridgeability bridging) {
4243
assert(!param.getParameterFlags().isInOut() &&
4344
!param.getParameterFlags().isVariadic());
4445

45-
auto bridged = getLoweredBridgedType(pattern, param.getPlainType(), rep,
46-
TypeConverter::ForArgument);
46+
auto bridged = getLoweredBridgedType(pattern, param.getPlainType(), bridging,
47+
rep, TypeConverter::ForArgument);
4748
if (!bridged) {
4849
Context.Diags.diagnose(SourceLoc(), diag::could_not_find_bridge_type,
4950
param.getPlainType());
@@ -59,20 +60,23 @@ void TypeConverter::
5960
getBridgedParams(SILFunctionTypeRepresentation rep,
6061
AbstractionPattern pattern,
6162
ArrayRef<AnyFunctionType::Param> params,
62-
SmallVectorImpl<AnyFunctionType::Param> &bridgedParams) {
63+
SmallVectorImpl<AnyFunctionType::Param> &bridgedParams,
64+
Bridgeability bridging) {
6365
for (unsigned i : indices(params)) {
6466
auto paramPattern = pattern.getFunctionParamType(i);
65-
bridgedParams.push_back(getBridgedParam(rep, paramPattern, params[i]));
67+
auto bridgedParam = getBridgedParam(rep, paramPattern, params[i], bridging);
68+
bridgedParams.push_back(bridgedParam);
6669
}
6770
}
6871

6972
/// Bridge a result type.
7073
CanType TypeConverter::getBridgedResultType(SILFunctionTypeRepresentation rep,
7174
AbstractionPattern pattern,
7275
CanType result,
76+
Bridgeability bridging,
7377
bool suppressOptional) {
7478
auto loweredType =
75-
getLoweredBridgedType(pattern, result, rep,
79+
getLoweredBridgedType(pattern, result, bridging, rep,
7680
suppressOptional
7781
? TypeConverter::ForNonOptionalResult
7882
: TypeConverter::ForResult);
@@ -89,6 +93,7 @@ CanType TypeConverter::getBridgedResultType(SILFunctionTypeRepresentation rep,
8993

9094
Type TypeConverter::getLoweredBridgedType(AbstractionPattern pattern,
9195
Type t,
96+
Bridgeability bridging,
9297
SILFunctionTypeRepresentation rep,
9398
BridgedTypePurpose purpose) {
9499
switch (rep) {
@@ -104,39 +109,46 @@ Type TypeConverter::getLoweredBridgedType(AbstractionPattern pattern,
104109
case SILFunctionTypeRepresentation::Block:
105110
// Map native types back to bridged types.
106111

107-
bool canBridgeBool = (rep == SILFunctionTypeRepresentation::ObjCMethod);
108-
109112
// Look through optional types.
110113
if (auto valueTy = t->getOptionalObjectType()) {
111114
pattern = pattern.getOptionalObjectType();
112-
auto ty = getLoweredCBridgedType(pattern, valueTy, canBridgeBool, false);
115+
auto ty = getLoweredCBridgedType(pattern, valueTy, bridging, rep,
116+
BridgedTypePurpose::ForNonOptionalResult);
113117
return ty ? OptionalType::get(ty) : ty;
114118
}
115-
return getLoweredCBridgedType(pattern, t, canBridgeBool,
116-
purpose == ForResult);
119+
return getLoweredCBridgedType(pattern, t, bridging, rep, purpose);
117120
}
118121

119122
llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch.");
120123
};
121124

122125
Type TypeConverter::getLoweredCBridgedType(AbstractionPattern pattern,
123-
Type t,
124-
bool canBridgeBool,
125-
bool bridgedCollectionsAreOptional) {
126+
Type t, Bridgeability bridging,
127+
SILFunctionTypeRepresentation rep,
128+
BridgedTypePurpose purpose) {
126129
auto clangTy = pattern.isClangType() ? pattern.getClangType() : nullptr;
127130

128131
// Bridge Bool back to ObjC bool, unless the original Clang type was _Bool
129132
// or the Darwin Boolean type.
130133
auto nativeBoolTy = getBoolType();
131134
if (nativeBoolTy && t->isEqual(nativeBoolTy)) {
135+
// If we have a Clang type that was imported as Bool, it had better be
136+
// one of a small set of types.
132137
if (clangTy) {
133-
if (clangTy->isBooleanType())
138+
auto builtinTy = clangTy->castAs<clang::BuiltinType>();
139+
if (builtinTy->getKind() == clang::BuiltinType::Bool)
134140
return t;
135-
if (clangTy->isSpecificBuiltinType(clang::BuiltinType::UChar))
141+
if (builtinTy->getKind() == clang::BuiltinType::UChar)
136142
return getDarwinBooleanType();
143+
assert(builtinTy->getKind() == clang::BuiltinType::SChar);
144+
return getObjCBoolType();
137145
}
138-
if (clangTy || canBridgeBool)
146+
147+
// Otherwise, always assume ObjC methods should use ObjCBool.
148+
if (bridging != Bridgeability::None &&
149+
rep == SILFunctionTypeRepresentation::ObjCMethod)
139150
return getObjCBoolType();
151+
140152
return t;
141153
}
142154

@@ -180,12 +192,13 @@ Type TypeConverter::getLoweredCBridgedType(AbstractionPattern pattern,
180192
// so we use the ObjCMethod representation.
181193
SmallVector<AnyFunctionType::Param, 8> newParams;
182194
getBridgedParams(SILFunctionType::Representation::ObjCMethod,
183-
pattern, funTy->getParams(), newParams);
195+
pattern, funTy->getParams(), newParams, bridging);
184196

185197
Type newResult =
186198
getBridgedResultType(SILFunctionType::Representation::ObjCMethod,
187199
pattern.getFunctionResultType(),
188200
funTy->getResult()->getCanonicalType(),
201+
bridging,
189202
/*non-optional*/false);
190203

191204
return FunctionType::get(newParams, newResult,
@@ -213,7 +226,7 @@ Type TypeConverter::getLoweredCBridgedType(AbstractionPattern pattern,
213226
M.getASTContext().Id_ObjectiveCType,
214227
nullptr);
215228
assert(bridgedTy && "Missing _ObjectiveCType witness?");
216-
if (bridgedCollectionsAreOptional && clangTy)
229+
if (purpose == BridgedTypePurpose::ForResult && clangTy)
217230
bridgedTy = OptionalType::get(bridgedTy);
218231
return bridgedTy;
219232
}

lib/SIL/SILFunctionType.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2530,7 +2530,8 @@ SILFunctionType::substGenericArgs(SILModule &silModule,
25302530
CanAnyFunctionType
25312531
TypeConverter::getBridgedFunctionType(AbstractionPattern pattern,
25322532
CanAnyFunctionType t,
2533-
AnyFunctionType::ExtInfo extInfo) {
2533+
AnyFunctionType::ExtInfo extInfo,
2534+
Bridgeability bridging) {
25342535
// Pull out the generic signature.
25352536
CanGenericSignature genericSig = t.getOptGenericSignature();
25362537

@@ -2551,12 +2552,13 @@ TypeConverter::getBridgedFunctionType(AbstractionPattern pattern,
25512552
case SILFunctionTypeRepresentation::Block:
25522553
case SILFunctionTypeRepresentation::ObjCMethod: {
25532554
SmallVector<AnyFunctionType::Param, 8> params;
2554-
getBridgedParams(rep, pattern, t->getParams(), params);
2555+
getBridgedParams(rep, pattern, t->getParams(), params, bridging);
25552556

25562557
bool suppressOptional = pattern.hasForeignErrorStrippingResultOptionality();
25572558
auto result = getBridgedResultType(rep,
25582559
pattern.getFunctionResultType(),
25592560
t.getResult(),
2561+
bridging,
25602562
suppressOptional);
25612563

25622564
return CanAnyFunctionType::get(genericSig, llvm::makeArrayRef(params),
@@ -2627,6 +2629,10 @@ getAbstractionPatternForConstant(ASTContext &ctx, SILDeclRef constant,
26272629
TypeConverter::LoweredFormalTypes
26282630
TypeConverter::getLoweredFormalTypes(SILDeclRef constant,
26292631
CanAnyFunctionType fnType) {
2632+
// We always use full bridging when importing a constant because we can
2633+
// directly bridge its arguments and results when calling it.
2634+
auto bridging = Bridgeability::Full;
2635+
26302636
unsigned numParameterLists = constant.getParameterListCount();
26312637
auto extInfo = fnType->getExtInfo();
26322638

@@ -2638,7 +2644,7 @@ TypeConverter::getLoweredFormalTypes(SILDeclRef constant,
26382644
// Fast path: no uncurrying required.
26392645
if (numParameterLists == 1) {
26402646
auto bridgedFnType =
2641-
getBridgedFunctionType(bridgingFnPattern, fnType, extInfo);
2647+
getBridgedFunctionType(bridgingFnPattern, fnType, extInfo, bridging);
26422648
bridgingFnPattern.rewriteType(bridgingFnPattern.getGenericSignature(),
26432649
bridgedFnType);
26442650
return { bridgingFnPattern, bridgedFnType };
@@ -2685,17 +2691,18 @@ TypeConverter::getLoweredFormalTypes(SILDeclRef constant,
26852691
// The "self" parameter should not get bridged unless it's a metatype.
26862692
if (selfParam.getPlainType()->is<AnyMetatypeType>()) {
26872693
auto selfPattern = bridgingFnPattern.getFunctionParamType(0);
2688-
selfParam = getBridgedParam(rep, selfPattern, selfParam);
2694+
selfParam = getBridgedParam(rep, selfPattern, selfParam, bridging);
26892695
}
26902696
}
26912697

26922698
auto partialFnPattern = bridgingFnPattern.getFunctionResultType();
2693-
getBridgedParams(rep, partialFnPattern, methodParams, bridgedParams);
2699+
getBridgedParams(rep, partialFnPattern, methodParams, bridgedParams,
2700+
bridging);
26942701

26952702
bridgedResultType =
26962703
getBridgedResultType(rep,
26972704
partialFnPattern.getFunctionResultType(),
2698-
resultType, suppressOptionalResult);
2705+
resultType, bridging, suppressOptionalResult);
26992706
break;
27002707
}
27012708

lib/SIL/TypeLowering.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1472,9 +1472,16 @@ CanType TypeConverter::getLoweredRValueType(AbstractionPattern origType,
14721472
auto extInfo = substFnType->getExtInfo();
14731473
if (getSILFunctionLanguage(extInfo.getSILRepresentation())
14741474
== SILFunctionLanguage::C) {
1475+
// The importer only applies fully-reversible bridging to the
1476+
// component types of C function pointers.
1477+
auto bridging = Bridgeability::Full;
1478+
if (extInfo.getSILRepresentation()
1479+
== SILFunctionTypeRepresentation::CFunctionPointer)
1480+
bridging = Bridgeability::None;
1481+
14751482
// Bridge the parameters and result of the function type.
14761483
auto bridgedFnType = getBridgedFunctionType(origType, substFnType,
1477-
extInfo);
1484+
extInfo, bridging);
14781485
substFnType = bridgedFnType;
14791486

14801487
// Also rewrite the type of the abstraction pattern.

lib/SILGen/SILGenApply.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ getIndirectApplyAbstractionPattern(SILGenFunction &SGF,
7676
// bridged to a foreign type.
7777
auto bridgedType =
7878
SGF.SGM.Types.getBridgedFunctionType(pattern, fnType,
79-
fnType->getExtInfo());
79+
fnType->getExtInfo(),
80+
Bridgeability::Full);
8081
pattern.rewriteType(CanGenericSignature(), bridgedType);
8182
return pattern;
8283
}

lib/SILGen/SILGenBridging.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ expandTupleTypes(AnyFunctionType::CanParamArrayRef params) {
358358
static CanAnyFunctionType getBridgedBlockType(SILGenModule &SGM,
359359
CanAnyFunctionType blockType) {
360360
return SGM.Types.getBridgedFunctionType(AbstractionPattern(blockType),
361-
blockType, blockType->getExtInfo());
361+
blockType, blockType->getExtInfo(),
362+
Bridgeability::Full);
362363
}
363364

364365
static void buildFuncToBlockInvokeBody(SILGenFunction &SGF,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
typedef unsigned long size_t;
2+
typedef _Bool (^predicate_t)(size_t);
3+
typedef struct {
4+
void (*takePredicate)(predicate_t);
5+
} Aggregate;

test/ClangImporter/Inputs/custom-modules/module.map

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ module ObjCBridgeNonconforming {
203203
header "ObjCBridgeNonconforming.h"
204204
}
205205

206+
module BlocksReturningBool {
207+
header "BlocksReturningBool.h"
208+
}
209+
206210
module Warnings1 { header "Warnings1.h" }
207211
module Warnings2 { header "Warnings2.h" }
208212
module Warnings3 { header "Warnings3.h" }
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen %s -I %S/Inputs/ | %FileCheck %s
2+
3+
// REQUIRES: objc_interop
4+
5+
import Foundation
6+
import BlocksReturningBool
7+
8+
// rdar://43656704
9+
10+
// CHECK-LABEL: sil {{.*}} @$sSo9Aggregatea13takePredicateABySbSicSgXCSg_tcfC
11+
// CHECK-SAME: Optional<@convention(c) (Optional<@convention(block) (Int) -> Bool>) -> ()>
12+
func foo() -> Aggregate {
13+
return Aggregate(takePredicate: nil)
14+
}

test/SILOptimizer/pound_assert.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ func test_infiniteLoop() {
4040
}
4141

4242
func recursive(a: Int) -> Int {
43-
if a == 0 { return 0 } // expected-note {{exceeded instruction limit: 512 when evaluating the expression at compile time}}
44-
return recursive(a: a-1)
43+
// expected-note@+1 {{exceeded instruction limit: 512 when evaluating the expression at compile time}}
44+
return a == 0 ? 0 : recursive(a: a-1)
4545
}
4646

4747
func test_recursive() {

0 commit comments

Comments
 (0)