diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-07-12 22:05:17 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-07-12 22:05:17 +0000 |
commit | ce9b73999974bf2efae2dd614dcec67017b817fe (patch) | |
tree | e14d2658166b51d3f944ebc90a6d5af5a87c67ad /clang/lib/ARCMigrate/Transforms.cpp | |
parent | c0f6af21037789f7fc6c1c44014d3c527482e574 (diff) | |
download | bcm5719-llvm-ce9b73999974bf2efae2dd614dcec67017b817fe.tar.gz bcm5719-llvm-ce9b73999974bf2efae2dd614dcec67017b817fe.zip |
[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.
llvm-svn: 135002
Diffstat (limited to 'clang/lib/ARCMigrate/Transforms.cpp')
-rw-r--r-- | clang/lib/ARCMigrate/Transforms.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp index 546829120c0..c2f85f65b76 100644 --- a/clang/lib/ARCMigrate/Transforms.cpp +++ b/clang/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 |