aboutsummaryrefslogtreecommitdiff
path: root/lib/ARCMigrate/Transforms.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-07-12 22:05:17 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-07-12 22:05:17 +0000
commit86625b5650cdddc38c0b4cc1eb7fb460478c9d11 (patch)
tree0163c4ca4fde1b4295691073258bb29cadfe8e35 /lib/ARCMigrate/Transforms.cpp
parentc286f3835eb6001c61664cef5d610dfaf80a6e9b (diff)
[arcmt] Before applying '__weak' check whether the objc class is annotated with objc_arc_weak_reference_unavailable
or is in a list of classes not supporting 'weak'. rdar://9489367. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135002 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ARCMigrate/Transforms.cpp')
-rw-r--r--lib/ARCMigrate/Transforms.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index 546829120c..c2f85f65b7 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/lib/ARCMigrate/Transforms.cpp
@@ -29,6 +29,61 @@ using llvm::StringRef;
// Helpers.
//===----------------------------------------------------------------------===//
+/// \brief True if the class is one that does not support weak.
+static bool isClassInWeakBlacklist(ObjCInterfaceDecl *cls) {
+ if (!cls)
+ return false;
+
+ bool inList = llvm::StringSwitch<bool>(cls->getName())
+ .Case("NSColorSpace", true)
+ .Case("NSFont", true)
+ .Case("NSFontPanel", true)
+ .Case("NSImage", true)
+ .Case("NSLazyBrowserCell", true)
+ .Case("NSWindow", true)
+ .Case("NSWindowController", true)
+ .Case("NSMenuView", true)
+ .Case("NSPersistentUIWindowInfo", true)
+ .Case("NSTableCellView", true)
+ .Case("NSATSTypeSetter", true)
+ .Case("NSATSGlyphStorage", true)
+ .Case("NSLineFragmentRenderingContext", true)
+ .Case("NSAttributeDictionary", true)
+ .Case("NSParagraphStyle", true)
+ .Case("NSTextTab", true)
+ .Case("NSSimpleHorizontalTypesetter", true)
+ .Case("_NSCachedAttributedString", true)
+ .Case("NSStringDrawingTextStorage", true)
+ .Case("NSTextView", true)
+ .Case("NSSubTextStorage", true)
+ .Default(false);
+
+ if (inList)
+ return true;
+
+ return isClassInWeakBlacklist(cls->getSuperClass());
+}
+
+bool trans::canApplyWeak(ASTContext &Ctx, QualType type) {
+ if (!Ctx.getLangOptions().ObjCRuntimeHasWeak)
+ return false;
+
+ QualType T = type;
+ while (const PointerType *ptr = T->getAs<PointerType>())
+ T = ptr->getPointeeType();
+ if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) {
+ ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl();
+ if (!Class || Class->getName() == "NSObject")
+ return false; // id/NSObject is not safe for weak.
+ if (Class->isArcWeakrefUnavailable())
+ return false;
+ if (isClassInWeakBlacklist(Class))
+ return false;
+ }
+
+ return true;
+}
+
/// \brief 'Loc' is the end of a statement range. This returns the location
/// immediately after the semicolon following the statement.
/// If no semicolon is found or the location is inside a macro, the returned