Don't map Bool back to ObjCBool for SIL types in unbridged contexts.

When the Clang importer imports the components of a C function pointer
type, it generally translates foreign types into their native equivalents,
just for the convenience of Swift code working with those functions.
However, this translation must be unambiguously reversible, so (among
other things) it cannot do this when the native type is also a valid
foreign type.  Specifically, this means that the Clang importer cannot
import ObjCBool as Swift.Bool in these positions because Swift.Bool
corresponds directly to the C type _Bool.

SIL type lowering manually reverses the type-import process using
a combination of duplicated logic and an abstraction pattern which
includes information about the original Clang type that was imported.
This abstraction pattern is generally able to tell SIL type lowering
exactly what type to reverse to.  However, @convention(c) function
types may appear in positions from which it is impossible to recover
the original Clang function type; therefore the reversal must be
faithful to the proper rules.  To do this we must propagate
bridgeability just as the imported would.

This reversal system is absolutely crazy, and we should really just
- record an unbridged function type for imported declarations and
- record an unbridged function type and Clang function type for
  @convention (c) function types whenever we create them.
But for now, it's what we've got.

rdar://43656704
This commit is contained in:
John McCall
2018-11-30 00:09:37 -05:00
parent 5c2fc6995a
commit 95297f6988
12 changed files with 115 additions and 45 deletions

View File

@@ -60,6 +60,17 @@ static const clang::Type *getClangType(const clang::Decl *decl) {
return cast<clang::ObjCPropertyDecl>(decl)->getType().getTypePtr();
}
static Bridgeability getClangDeclBridgeability(const clang::Decl *decl) {
// These declarations are always imported without bridging (for now).
if (isa<clang::VarDecl>(decl) ||
isa<clang::FieldDecl>(decl) ||
isa<clang::IndirectFieldDecl>(decl))
return Bridgeability::None;
// Functions and methods always use normal bridging.
return Bridgeability::Full;
}
AbstractionPattern
TypeConverter::getAbstractionPattern(VarDecl *var, bool isNonObjC) {
CanGenericSignature genericSig;
@@ -77,7 +88,7 @@ TypeConverter::getAbstractionPattern(VarDecl *var, bool isNonObjC) {
auto contextType = var->getDeclContext()->mapTypeIntoContext(swiftType);
swiftType = getLoweredBridgedType(
AbstractionPattern(genericSig, swiftType, clangType),
contextType,
contextType, getClangDeclBridgeability(clangDecl),
SILFunctionTypeRepresentation::CFunctionPointer,
TypeConverter::ForMemory)->getCanonicalType();
return AbstractionPattern(genericSig, swiftType, clangType);