Skip to content

Commit 340090c

Browse files
committed
[PrintAsObjC] Refactor printing of property ownership attributes
Exhaustively switch over reference types, so that we'll know if any new ones are added, and factor out a repeated check to see if something's a retainable object type. No functionality change.
1 parent 0bcf355 commit 340090c

File tree

1 file changed

+47
-21
lines changed

1 file changed

+47
-21
lines changed

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,17 +1027,40 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
10271027
return true;
10281028
}
10291029

1030+
/// Returns whether \p ty is the C type \c CFTypeRef, or some typealias
1031+
/// thereof.
10301032
bool isCFTypeRef(Type ty) {
1031-
if (ID_CFTypeRef.empty())
1032-
ID_CFTypeRef = M.getASTContext().getIdentifier("CFTypeRef");
1033-
10341033
const TypeAliasDecl *TAD = nullptr;
10351034
while (auto aliasTy = dyn_cast<NameAliasType>(ty.getPointer())) {
10361035
TAD = aliasTy->getDecl();
10371036
ty = aliasTy->getSinglyDesugaredType();
10381037
}
10391038

1040-
return TAD && TAD->getName() == ID_CFTypeRef && TAD->hasClangNode();
1039+
if (!TAD || !TAD->hasClangNode())
1040+
return false;
1041+
1042+
if (ID_CFTypeRef.empty())
1043+
ID_CFTypeRef = M.getASTContext().getIdentifier("CFTypeRef");
1044+
return TAD->getName() == ID_CFTypeRef;
1045+
}
1046+
1047+
/// Returns true if \p ty can be used with Objective-C reference-counting
1048+
/// annotations like \c strong and \c weak.
1049+
bool isObjCReferenceCountableObjectType(Type ty) {
1050+
if (auto classDecl = ty->getClassOrBoundGenericClass()) {
1051+
switch (classDecl->getForeignClassKind()) {
1052+
case ClassDecl::ForeignKind::Normal:
1053+
case ClassDecl::ForeignKind::RuntimeOnly:
1054+
return true;
1055+
case ClassDecl::ForeignKind::CFType:
1056+
return false;
1057+
}
1058+
}
1059+
1060+
if (ty->isObjCExistentialType() && !isCFTypeRef(ty))
1061+
return true;
1062+
1063+
return false;
10411064
}
10421065

10431066
void visitVarDecl(VarDecl *VD) {
@@ -1066,20 +1089,26 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
10661089

10671090
// Print the ownership semantics, if relevant.
10681091
Type ty = VD->getInterfaceType();
1069-
if (auto weakTy = ty->getAs<WeakStorageType>()) {
1070-
auto innerTy = weakTy->getReferentType()->getOptionalObjectType();
1071-
auto innerClass = innerTy->getClassOrBoundGenericClass();
1072-
if ((innerClass &&
1073-
innerClass->getForeignClassKind()!=ClassDecl::ForeignKind::CFType) ||
1074-
(innerTy->isObjCExistentialType() && !isCFTypeRef(innerTy))) {
1075-
os << ", weak";
1092+
if (auto referenceStorageTy = ty->getAs<ReferenceStorageType>()) {
1093+
switch (referenceStorageTy->getOwnership()) {
1094+
case ReferenceOwnership::Strong:
1095+
llvm_unreachable("not represented with a ReferenceStorageType");
1096+
case ReferenceOwnership::Weak: {
1097+
auto innerTy =
1098+
referenceStorageTy->getReferentType()->getOptionalObjectType();
1099+
if (isObjCReferenceCountableObjectType(innerTy))
1100+
os << ", weak";
1101+
break;
1102+
}
1103+
case ReferenceOwnership::Unowned:
1104+
case ReferenceOwnership::Unmanaged:
1105+
// We treat "unowned" as "unsafe_unretained" (even though it's more
1106+
// like "safe_unretained") because we want people to think twice about
1107+
// allowing that object to disappear. "unowned(unsafe)" (and
1108+
// Swift.Unmanaged, handled below) really are "unsafe_unretained".
1109+
os << ", unsafe_unretained";
1110+
break;
10761111
}
1077-
} else if (ty->is<UnownedStorageType>()|| ty->is<UnmanagedStorageType>()) {
1078-
// We treat "unowned" as "unsafe_unretained" (even though it's more like
1079-
// "safe_unretained") because we want people to think twice about
1080-
// allowing that object to disappear. "unowned(unsafe)" (and Unmanaged,
1081-
// handled below) really are "unsafe_unretained".
1082-
os << ", unsafe_unretained";
10831112
} else {
10841113
Type copyTy = ty;
10851114
bool isOptional = false;
@@ -1116,10 +1145,7 @@ class ObjCPrinter : private DeclVisitor<ObjCPrinter>,
11161145
case FunctionTypeRepresentation::CFunctionPointer:
11171146
break;
11181147
}
1119-
} else if ((nominal && isa<ClassDecl>(nominal) &&
1120-
cast<ClassDecl>(nominal)->getForeignClassKind() !=
1121-
ClassDecl::ForeignKind::CFType) ||
1122-
(copyTy->isObjCExistentialType() && !isCFTypeRef(copyTy))) {
1148+
} else if (isObjCReferenceCountableObjectType(copyTy)) {
11231149
os << ", strong";
11241150
}
11251151
}

0 commit comments

Comments
 (0)