Skip to content

Commit 2c26f2b

Browse files
author
ematejska
authored
Merge pull request #4006 from jrose-apple/swift-3-weak-properties-are-weak
[ClangImporter] Don't bridge weak and unsafe_unretained properties to value types
2 parents 0003a7b + 52bed3b commit 2c26f2b

File tree

5 files changed

+451
-357
lines changed

5 files changed

+451
-357
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ static bool canBridgeTypes(ImportTypeKind importKind) {
10201020
case ImportTypeKind::CFRetainedOutParameter:
10211021
case ImportTypeKind::CFUnretainedOutParameter:
10221022
case ImportTypeKind::Property:
1023-
case ImportTypeKind::PropertyAccessor:
1023+
case ImportTypeKind::PropertyWithReferenceSemantics:
10241024
case ImportTypeKind::BridgedValue:
10251025
return true;
10261026
}
@@ -1045,7 +1045,7 @@ static bool isCFAudited(ImportTypeKind importKind) {
10451045
case ImportTypeKind::CFRetainedOutParameter:
10461046
case ImportTypeKind::CFUnretainedOutParameter:
10471047
case ImportTypeKind::Property:
1048-
case ImportTypeKind::PropertyAccessor:
1048+
case ImportTypeKind::PropertyWithReferenceSemantics:
10491049
return true;
10501050
}
10511051
}
@@ -1091,8 +1091,7 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
10911091
// 'void' can only be imported as a function result type.
10921092
if (hint == ImportHint::Void &&
10931093
(importKind == ImportTypeKind::AuditedResult ||
1094-
importKind == ImportTypeKind::Result ||
1095-
importKind == ImportTypeKind::PropertyAccessor)) {
1094+
importKind == ImportTypeKind::Result)) {
10961095
return impl.getNamedSwiftType(impl.getStdlibModule(), "Void");
10971096
}
10981097

@@ -1268,13 +1267,16 @@ static Type adjustTypeForConcreteImport(ClangImporter::Implementation &impl,
12681267

12691268
// If we have a bridged Objective-C type and we are allowed to
12701269
// bridge, do so.
1271-
if (hint == ImportHint::ObjCBridged && canBridgeTypes(importKind))
1270+
if (hint == ImportHint::ObjCBridged && canBridgeTypes(importKind) &&
1271+
importKind != ImportTypeKind::PropertyWithReferenceSemantics) {
12721272
// id and Any can be bridged without Foundation. There would be
12731273
// bootstrapping issues with the ObjectiveC module otherwise.
12741274
if (hint.BridgedType->isAny()
12751275
|| impl.tryLoadFoundationModule()
1276-
|| impl.ImportForwardDeclarations)
1276+
|| impl.ImportForwardDeclarations) {
12771277
importedType = hint.BridgedType;
1278+
}
1279+
}
12781280

12791281
if (!importedType)
12801282
return importedType;
@@ -1399,8 +1401,38 @@ bool ClangImporter::Implementation::shouldAllowNSUIntegerAsInt(
13991401
Type ClangImporter::Implementation::importPropertyType(
14001402
const clang::ObjCPropertyDecl *decl,
14011403
bool isFromSystemModule) {
1404+
const auto assignOrUnsafeUnretained =
1405+
clang::ObjCPropertyDecl::OBJC_PR_assign |
1406+
clang::ObjCPropertyDecl::OBJC_PR_unsafe_unretained;
1407+
1408+
ImportTypeKind importKind;
1409+
// HACK: Accessibility decls are always imported using bridged types,
1410+
// because they're inconsistent between properties and methods.
1411+
if (isAccessibilityDecl(decl)) {
1412+
importKind = ImportTypeKind::Property;
1413+
} else {
1414+
switch (decl->getSetterKind()) {
1415+
case clang::ObjCPropertyDecl::Assign:
1416+
// If it's readonly, this might just be returned as a default.
1417+
if (decl->isReadOnly() &&
1418+
(decl->getPropertyAttributes() & assignOrUnsafeUnretained) == 0) {
1419+
importKind = ImportTypeKind::Property;
1420+
} else {
1421+
importKind = ImportTypeKind::PropertyWithReferenceSemantics;
1422+
}
1423+
break;
1424+
case clang::ObjCPropertyDecl::Retain:
1425+
case clang::ObjCPropertyDecl::Copy:
1426+
importKind = ImportTypeKind::Property;
1427+
break;
1428+
case clang::ObjCPropertyDecl::Weak:
1429+
importKind = ImportTypeKind::PropertyWithReferenceSemantics;
1430+
break;
1431+
}
1432+
}
1433+
14021434
OptionalTypeKind optionality = OTK_ImplicitlyUnwrappedOptional;
1403-
return importType(decl->getType(), ImportTypeKind::Property,
1435+
return importType(decl->getType(), importKind,
14041436
shouldAllowNSUIntegerAsInt(isFromSystemModule, decl),
14051437
/*isFullyBridgeable*/ true, optionality);
14061438
}
@@ -2173,9 +2205,7 @@ Type ClangImporter::Implementation::importMethodType(
21732205
// returning CF types as a workaround for ARC not managing CF
21742206
// objects
21752207
ImportTypeKind resultKind;
2176-
if (kind == SpecialMethodKind::PropertyAccessor)
2177-
resultKind = ImportTypeKind::PropertyAccessor;
2178-
else if (isObjCMethodResultAudited(clangDecl))
2208+
if (isObjCMethodResultAudited(clangDecl))
21792209
resultKind = ImportTypeKind::AuditedResult;
21802210
else
21812211
resultKind = ImportTypeKind::Result;
@@ -2335,12 +2365,6 @@ Type ClangImporter::Implementation::importMethodType(
23352365
swiftParamTy = getOptionalType(getNSCopyingType(),
23362366
ImportTypeKind::Parameter,
23372367
optionalityOfParam);
2338-
} else if (kind == SpecialMethodKind::PropertyAccessor) {
2339-
swiftParamTy = importType(paramTy,
2340-
ImportTypeKind::PropertyAccessor,
2341-
allowNSUIntegerAsIntInParam,
2342-
/*isFullyBridgeable*/true,
2343-
optionalityOfParam);
23442368
} else {
23452369
ImportTypeKind importKind = ImportTypeKind::Parameter;
23462370
if (param->hasAttr<clang::CFReturnsRetainedAttr>())

lib/ClangImporter/ImporterImpl.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,12 @@ enum class ImportTypeKind {
164164
/// considered CF-audited.
165165
Property,
166166

167-
/// \brief Import the type of an ObjC property accessor.
167+
/// \brief Import the type of an ObjC property accessor marked 'weak',
168+
/// 'assign', or 'unsafe_unretained'.
168169
///
169-
/// This behaves exactly like Property except that it accepts Void.
170-
PropertyAccessor,
170+
/// Like Property, but doesn't allow bridging to a value type, since that
171+
/// would discard the ownership.
172+
PropertyWithReferenceSemantics,
171173

172174
/// \brief Import the underlying type of an enum.
173175
///

test/IDE/print_clang_decls_AppKit.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@
3434
// APPKIT-NEXT: unowned(unsafe) var menu: @sil_unmanaged NSMenu?
3535
// APPKIT-NEXT: var title: String
3636
// APPKIT-NEXT: @NSCopying var attributedTitle: NSAttributedString?
37-
// TODO: Weak properties should not be bridged.
38-
// APPKIT-NEXT: var target: Any!
37+
// APPKIT-NEXT: weak var target: @sil_weak AnyObject!
3938
// APPKIT-NEXT: var action: Selector
4039
// APPKIT: {{^}}}{{$}}
4140
// APPKIT: extension NSNotification.Name {

0 commit comments

Comments
 (0)