bool trans::canApplyWeak(ASTContext &Ctx, QualType type, bool AllowOnUnknownClass) { if (!Ctx.getLangOpts().ObjCARCWeak) return false; QualType T = type; if (T.isNull()) return false; // iOS is always safe to use 'weak'. if (Ctx.getTargetInfo().getTriple().getOS() == llvm::Triple::IOS) AllowOnUnknownClass = true; while (const PointerType *ptr = T->getAs<PointerType>()) T = ptr->getPointeeType(); if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) { ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl(); if (!AllowOnUnknownClass && (!Class || Class->getName() == "NSObject")) return false; // id/NSObject is not safe for weak. if (!AllowOnUnknownClass && !Class->hasDefinition()) return false; // forward classes are not verifiable, therefore not safe. if (Class && Class->isArcWeakrefUnavailable()) return false; } return true; }
bool trans::canApplyWeak(ASTContext &Ctx, QualType type, bool AllowOnUnknownClass) { if (!Ctx.getLangOptions().ObjCRuntimeHasWeak) return false; QualType T = type; if (T.isNull()) return false; while (const PointerType *ptr = T->getAs<PointerType>()) T = ptr->getPointeeType(); if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) { ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl(); if (!AllowOnUnknownClass && (!Class || Class->getName() == "NSObject")) return false; // id/NSObject is not safe for weak. if (!AllowOnUnknownClass && Class->isForwardDecl()) return false; // forward classes are not verifiable, therefore not safe. if (Class->isArcWeakrefUnavailable()) return false; if (isClassInWeakBlacklist(Class)) return false; } return true; }