> On Mar 2, 2015, at 2:25 PM, Nico Weber <[email protected]> wrote:
> 
> One more tweak: Apparently for `@interface A @end @class A;`, a lookup for A 
> finds the @interface decl, not the @class redecl.

Yeah, I think this is a longstanding hack from when we starting tracking 
redeclaration chains for Objective-C class declarations (and @class started 
being an ObjCInterfaceDecl). We (ahem, I) didn’t hunt down all of the places 
where we were expecting name lookup to return the definition.

> So for ObjCInterfaceDecls, the explicit loop is necessary – this patch adds 
> it back for that case. With this change, I can build most of chrome with this 
> warning enabled (and some declaration tweaks in chrome). (Only "most of" 
> because the build is still running – no known bugs).

Okay. Everything else LGTM, I say “go for it!”.

        - Doug

> On Sun, Mar 1, 2015 at 7:52 PM, Nico Weber <[email protected] 
> <mailto:[email protected]>> wrote:
> On Mon, Feb 2, 2015 at 10:26 PM, Douglas Gregor <[email protected] 
> <mailto:[email protected]>> wrote:
> Hi Nico,
> 
>> On Jan 8, 2015, at 6:14 PM, Nico Weber <[email protected] 
>> <mailto:[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.
> 
> Right :-)
>  
> 
>> 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.
> 
> That worked, done.
> 
> I also had to add some explicit code for handling redeclarations in 
> @interfaces, as these aren't modeled as redeclarations in the AST. I also 
> added the property note used in the other availability warnings, and I added 
> lots of tests.
> 
> <clang-redecl.diff>

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to