Skip to content

Commit 5d4c456

Browse files
committed
[ClangImporter] Clean up adjustTypeForConcreteImport, part 2
(or part 4, depending on how you want to count) Move the out-parameter logic into the switch over import hints (under the OtherPointer case), and move the helper lambdas out into their own functions. They're not called from anywhere else, but adjustTypeForConcreteImport is long as it is. Additionally, avoid early returns in the import hint switch; while early returns are generally a good thing, having some cases early-return and not others seems inconsistent. The post-switch logic is pretty simple and easy to early-exit now. No intended functionality change.
1 parent c12b924 commit 5d4c456

File tree

1 file changed

+108
-94
lines changed

1 file changed

+108
-94
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 108 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,85 @@ static bool isNSString(Type type) {
11941194
return false;
11951195
}
11961196

1197+
static Type maybeImportNSErrorOutParameter(ClangImporter::Implementation &impl,
1198+
Type importedType,
1199+
bool resugarNSErrorPointer) {
1200+
PointerTypeKind PTK;
1201+
auto elementType = importedType->getAnyPointerElementType(PTK);
1202+
if (!elementType || PTK != PTK_AutoreleasingUnsafeMutablePointer)
1203+
return Type();
1204+
1205+
auto elementObj = elementType->getOptionalObjectType();
1206+
if (!elementObj)
1207+
return Type();
1208+
1209+
auto elementClass = elementObj->getClassOrBoundGenericClass();
1210+
if (!elementClass)
1211+
return Type();
1212+
1213+
// FIXME: Avoid string comparison by caching this identifier.
1214+
if (elementClass->getName().str() !=
1215+
impl.SwiftContext.getSwiftName(KnownFoundationEntity::NSError))
1216+
return Type();
1217+
1218+
ModuleDecl *foundationModule = impl.tryLoadFoundationModule();
1219+
if (!foundationModule ||
1220+
foundationModule->getName()
1221+
!= elementClass->getModuleContext()->getName())
1222+
return Type();
1223+
1224+
1225+
if (resugarNSErrorPointer)
1226+
return impl.getNamedSwiftType(
1227+
foundationModule,
1228+
impl.SwiftContext.getSwiftName(
1229+
KnownFoundationEntity::NSErrorPointer));
1230+
1231+
// The imported type is AUMP<NSError?>, but the typealias is AUMP<NSError?>?
1232+
// so we have to manually make them match. We also want to assume this in
1233+
// general for error out-parameters even if they weren't marked nullable in C.
1234+
// Or at least we do for source-compatibility reasons...
1235+
return OptionalType::get(importedType);
1236+
}
1237+
1238+
static Type maybeImportCFOutParameter(ClangImporter::Implementation &impl,
1239+
Type importedType,
1240+
ImportTypeKind importKind) {
1241+
PointerTypeKind PTK;
1242+
auto elementType = importedType->getAnyPointerElementType(PTK);
1243+
if (!elementType || PTK != PTK_UnsafeMutablePointer)
1244+
return Type();
1245+
1246+
auto insideOptionalType = elementType->getOptionalObjectType();
1247+
bool isOptional = (bool) insideOptionalType;
1248+
if (!insideOptionalType)
1249+
insideOptionalType = elementType;
1250+
1251+
auto boundGenericTy = insideOptionalType->getAs<BoundGenericType>();
1252+
if (!boundGenericTy)
1253+
return Type();
1254+
1255+
auto boundGenericBase = boundGenericTy->getDecl();
1256+
if (boundGenericBase != impl.SwiftContext.getUnmanagedDecl())
1257+
return Type();
1258+
1259+
assert(boundGenericTy->getGenericArgs().size() == 1 &&
1260+
"signature of Unmanaged has changed");
1261+
1262+
auto resultTy = boundGenericTy->getGenericArgs().front();
1263+
if (isOptional)
1264+
resultTy = OptionalType::get(resultTy);
1265+
1266+
PointerTypeKind pointerKind;
1267+
if (importKind == ImportTypeKind::CFRetainedOutParameter)
1268+
pointerKind = PTK_UnsafeMutablePointer;
1269+
else
1270+
pointerKind = PTK_AutoreleasingUnsafeMutablePointer;
1271+
1272+
resultTy = getPointerTo(resultTy, pointerKind);
1273+
return resultTy;
1274+
}
1275+
11971276
static ImportedType adjustTypeForConcreteImport(
11981277
ClangImporter::Implementation &impl,
11991278
ImportResult importResult, ImportTypeKind importKind,
@@ -1217,7 +1296,6 @@ static ImportedType adjustTypeForConcreteImport(
12171296

12181297
case ImportHint::ObjCPointer:
12191298
case ImportHint::CFunctionPointer:
1220-
case ImportHint::OtherPointer:
12211299
break;
12221300

12231301
case ImportHint::Void:
@@ -1234,7 +1312,9 @@ static ImportedType adjustTypeForConcreteImport(
12341312
if (isNSString(importedType)) {
12351313
if (importKind == ImportTypeKind::Variable ||
12361314
importKind == ImportTypeKind::AuditedVariable) {
1237-
return {hint.BridgedType, false};
1315+
importedType = hint.BridgedType;
1316+
optKind = OTK_None;
1317+
break;
12381318
}
12391319
}
12401320

@@ -1292,14 +1372,14 @@ static ImportedType adjustTypeForConcreteImport(
12921372
// Turn BOOL and DarwinBoolean into Bool in contexts that can bridge types
12931373
// losslessly.
12941374
if (bridging == Bridgeability::Full && canBridgeTypes(importKind))
1295-
return {impl.SwiftContext.getBoolDecl()->getDeclaredType(), false};
1375+
importedType = impl.SwiftContext.getBoolDecl()->getDeclaredType();
12961376
break;
12971377

12981378
case ImportHint::NSUInteger:
12991379
// When NSUInteger is used as an enum's underlying type or if it does not
13001380
// come from a system module, make sure it stays unsigned.
13011381
if (importKind == ImportTypeKind::Enum || !allowNSUIntegerAsInt)
1302-
return {impl.SwiftContext.getUIntDecl()->getDeclaredType(), false};
1382+
importedType = impl.SwiftContext.getUIntDecl()->getDeclaredType();
13031383
break;
13041384

13051385
case ImportHint::CFPointer:
@@ -1328,99 +1408,33 @@ static ImportedType adjustTypeForConcreteImport(
13281408
optKind = OTK_None;
13291409
}
13301410
break;
1331-
}
1332-
1333-
assert(importedType);
1334-
1335-
// Special case AutoreleasingUnsafeMutablePointer<NSError?> parameters.
1336-
auto maybeImportNSErrorPointer = [&]() -> Type {
1337-
if (importKind != ImportTypeKind::Parameter)
1338-
return Type();
1339-
1340-
PointerTypeKind PTK;
1341-
auto elementType = importedType->getAnyPointerElementType(PTK);
1342-
if (!elementType || PTK != PTK_AutoreleasingUnsafeMutablePointer)
1343-
return Type();
1344-
1345-
auto elementObj = elementType->getOptionalObjectType();
1346-
if (!elementObj)
1347-
return Type();
1348-
1349-
auto elementClass = elementObj->getClassOrBoundGenericClass();
1350-
if (!elementClass)
1351-
return Type();
1352-
1353-
// FIXME: Avoid string comparison by caching this identifier.
1354-
if (elementClass->getName().str() !=
1355-
impl.SwiftContext.getSwiftName(KnownFoundationEntity::NSError))
1356-
return Type();
1357-
1358-
ModuleDecl *foundationModule = impl.tryLoadFoundationModule();
1359-
if (!foundationModule ||
1360-
foundationModule->getName()
1361-
!= elementClass->getModuleContext()->getName())
1362-
return Type();
13631411

1364-
1365-
if (resugarNSErrorPointer)
1366-
return impl.getNamedSwiftType(
1367-
foundationModule,
1368-
impl.SwiftContext.getSwiftName(
1369-
KnownFoundationEntity::NSErrorPointer));
1370-
1371-
// The imported type is AUMP<NSError?>, but the typealias is AUMP<NSError?>?
1372-
// so we have to manually make them match.
1373-
return OptionalType::get(importedType);
1374-
};
1375-
1376-
if (Type result = maybeImportNSErrorPointer()) {
1377-
return {result, false};
1378-
}
1379-
1380-
auto maybeImportCFOutParameter = [&]() -> Type {
1381-
if (importKind != ImportTypeKind::CFRetainedOutParameter &&
1382-
importKind != ImportTypeKind::CFUnretainedOutParameter) {
1383-
return Type();
1412+
case ImportHint::OtherPointer:
1413+
// Special-case AutoreleasingUnsafeMutablePointer<NSError?> parameters.
1414+
if (importKind == ImportTypeKind::Parameter) {
1415+
if (Type result = maybeImportNSErrorOutParameter(impl, importedType,
1416+
resugarNSErrorPointer)) {
1417+
importedType = result;
1418+
optKind = OTK_None;
1419+
break;
1420+
}
13841421
}
13851422

1386-
PointerTypeKind PTK;
1387-
auto elementType = importedType->getAnyPointerElementType(PTK);
1388-
if (!elementType || PTK != PTK_UnsafeMutablePointer)
1389-
return Type();
1390-
1391-
auto insideOptionalType = elementType->getOptionalObjectType();
1392-
bool isOptional = (bool) insideOptionalType;
1393-
if (!insideOptionalType)
1394-
insideOptionalType = elementType;
1395-
1396-
auto boundGenericTy = insideOptionalType->getAs<BoundGenericType>();
1397-
if (!boundGenericTy)
1398-
return Type();
1399-
1400-
auto boundGenericBase = boundGenericTy->getDecl();
1401-
if (boundGenericBase != impl.SwiftContext.getUnmanagedDecl())
1402-
return Type();
1403-
1404-
assert(boundGenericTy->getGenericArgs().size() == 1 &&
1405-
"signature of Unmanaged has changed");
1406-
1407-
auto resultTy = boundGenericTy->getGenericArgs().front();
1408-
if (isOptional)
1409-
resultTy = OptionalType::get(resultTy);
1410-
1411-
PointerTypeKind pointerKind;
1412-
if (importKind == ImportTypeKind::CFRetainedOutParameter)
1413-
pointerKind = PTK_UnsafeMutablePointer;
1414-
else
1415-
pointerKind = PTK_AutoreleasingUnsafeMutablePointer;
1423+
// Remove 'Unmanaged' from audited CF out-parameters.
1424+
if (importKind == ImportTypeKind::CFRetainedOutParameter ||
1425+
importKind == ImportTypeKind::CFUnretainedOutParameter) {
1426+
if (Type outParamTy = maybeImportCFOutParameter(impl, importedType,
1427+
importKind)) {
1428+
importedType = outParamTy;
1429+
break;
1430+
}
1431+
}
14161432

1417-
resultTy = getPointerTo(resultTy, pointerKind);
1418-
return resultTy;
1419-
};
1420-
if (Type outParamTy = maybeImportCFOutParameter()) {
1421-
importedType = outParamTy;
1433+
break;
14221434
}
14231435

1436+
assert(importedType);
1437+
14241438
if (importKind == ImportTypeKind::RecordField &&
14251439
importedType->isAnyClassReferenceType()) {
14261440
// Wrap retainable struct fields in Unmanaged.
@@ -1435,10 +1449,10 @@ static ImportedType adjustTypeForConcreteImport(
14351449
// Wrap class, class protocol, function, and metatype types in an
14361450
// optional type.
14371451
bool isIUO = false;
1438-
if (importKind != ImportTypeKind::Typedef && canImportAsOptional(hint)) {
1452+
if (importKind != ImportTypeKind::Typedef && optKind != OTK_None &&
1453+
canImportAsOptional(hint)) {
14391454
isIUO = optKind == OTK_ImplicitlyUnwrappedOptional;
1440-
if (optKind != OTK_None)
1441-
importedType = OptionalType::get(importedType);
1455+
importedType = OptionalType::get(importedType);
14421456
}
14431457

14441458
return {importedType, isIUO};

0 commit comments

Comments
 (0)