Hi Nico, > On Jan 8, 2015, at 6:14 PM, Nico Weber <[email protected]> wrote: > > Hi, > > the Mac OS X and iOS SDKs add new functions in new releases. Apple recommends > using the newest SDK and setting the deployment target to whatever old OS > version one wants to support, and only calling new functions after checking > that they are available at runtime. > > In practice, we (Chromium) get this wrong. Others who support old OS X > versions get this wrong too. Hence, we (Chromium) use a very old SDK and then > manually declare new functions when we want to call them – this reduces the > chance of us forgetting if they are available at runtime considerably, in > practice. But using an old SDK has its problems – sometimes the frameworks > check which SDK an app was linked against and only then activate bug fixes, > and newer Xcodes don't ship include old SDKs.
That’s an interesting approach to handling the availability problem; I hadn’t heard of it before, but I see the logic there. > Ideally, we could use a new SDK but get a warning when we use a new API > without a manual redeclaration – this protects us against new APIs the same > way using an old SDK does without the drawbacks that this brings. > > The attached patch is a sketch how such a warning might work. How repulsive > is this idea? Are there other approaches to this problem? If the basic idea > is ok: This is a drastically different approach than I’d imagined. Whenever I’ve thought about this problem, I’ve always come back to some form of dataflow analysis that checks whether uses of “not-yet-introduced” API is used in a sane way: is it dominated by some check that implies the availability, e.g., a -respondsToSelector: check on a method with at least that availability, or checking whether “[NSFoo class]” is non-null when the class has availability. I suspect that’s the idea behind Deploymate (http://www.deploymateapp.com <http://www.deploymateapp.com/>), although I’ve never used it, and it has the benefit that it should make idiomatic code (that does the right checking) just work. It’s also a heck of a lot more work to implement than the approach you’re using. > Any comments on the implementation? The implementation generally looks fine. One minor comment: + case AR_NotYetIntroduced: { + // don't do this for enums, they can't be redeclared. + if (isa<EnumConstantDecl>(D) || isa<EnumDecl>(D)) + break; + bool FoundRedecl = false; + for (Decl *Redecl = D->getMostRecentDecl(); Redecl && !FoundRedecl; + Redecl = Redecl->getPreviousDecl()) { + if (Redecl->getAttr<AvailabilityAttr>()->isInherited()) + FoundRedecl = true; + } + if (!FoundRedecl) + S.EmitAvailabilityWarning(Sema::AD_Partial, D, Message, Loc, + UnknownObjCClass, ObjCPDecl, + ObjCPropertyAccess); + break; + } Generally speaking, name lookup will always find the most recent declaration, so you might be able to skip the D->getMostRecentDecl() bit entirely and just check that the availability attribute was inherited. - Doug
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
