This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: Enhancing ObjC message lookup in the presence of protocols


>
> On 18 Oct 2004, at 5.29, David Ayers wrote:
>
>> Let's try this example
>>
>> @protocol MyProto1
>> - (const char *)name;
>> @end
>>
>> @protocol MyProto2
>> - (NSString *)name;
>> @end
>>
>> @interface MyRootClass <MyProto1>
>> @end
>>
>> @interface OtherRootClass
>> @end
>>
>> @interface MyClass : OtherRootClass <MyProto2>
>> @end
>>
>> In this case <MyProto2> is not a protocol declared by a root class.
>> Therefor we should not be falling back to the instance methods in the
>> case of:
>>
>> Class <Proto2> clsP2;
>> [clsP2 name]; /* may not respond */
>>
>
> I guess you meant '/* not implemented by protocol(s) */', right?

Indeed, thanks.

> If we
> were _never_ to look at instance methods in these cases, then 'not
> implemented by protocol(s)' would be right.  However, since we agreed
> that we should look at instance methods in protocols should class
> method lookup fail, I do not think we should attempt to guess what type
> of object 'clsP2' is actually pointing at.
>
> So, '[clsP2 name]' above should result in the compiler telling you
> 'found -name instead of +name in protocol(s)', and then using '-
> (NSString *)name' out of Proto2.

We are not guessing what kind of object clsP2 contains.  We would be using
the information we do have about Proto2 to constrain the fallback to the
instance method search.

> Alternatively, if you know what type of object 'clsP2' was pointing at,
> then you should type it appropriately, e.g.,
>
>    SomeClass <Proto2> *clsP2;
>    [clsP2 name];  /* this will issue a more precise diagnostic */

Here you have an object, not a class anymore, but that is a different issue.

>
>> Class cls;
>> [cls name]; /* OK */
>>
>> should not be ambiguous as there is only one prototype declared by
>> MyProto1 which should be in the class hash table.
>
> Yes, it _should_ be ambiguous, since you will have two conflicting
> method signatures, just as with
>
>    id obj;
>    [obj name];
>
> which is also ambiguous.

I maintain that [cls name] in unambiguous, as we know of only one class
which implements +name.  And that is MyRootClass as it adopt my Proto1,
where as Proto2 is adopted merely by a non-root class.  It's undisputed
that [obj name] is ambigious.

> I guess my overall point is: 'Class' and 'id' may hold an object of
> _any_ ObjC type, and not just types that you happen to have seen in
> your own translation unit thus far.  Protocol lists attached to 'Class'
> or 'id' give you an opportunity to look through the protocols first,
> but again without regard to what the underlying object type might or
> might not be.

What I'm trying to show is that "to look through protocols" in the case of
'Class <protocol>' should heed the information we have about the protocols
when taking into account the sematics of instance methods of root classes.

You initially disliked the idea of "protocols adopted by root classes". 
In the absence of this infomormation, I conceeded to at least add the
instance methods search for all protocols, eventhough this approach will
induce false positives as described above.  You implicitly affirmed in
this thread that we should adorn protocols with the status "adopted by
root classes" to handle the global class cache correctly.  Now I'm saying,
if we have the infomation with the protocol, why not also use it for
lookup of protocol qualified classes to constrain the instance method
search for adorned protocols.

We "know" that no class has adopted the protocol as a root protocol if
it's not adorned.  I think you're implying that "we may have not seen the
header that does", and therefor we shouldn't be using that information.  I
hold against that, that we "never" know what other classes my implement. 
Take the example:

@interface MyRoot
@end
@interface MyClass : MyRoot
-method;
@end

void func2 (id obj, Class cls)
{
  [obj method];/* OK */
  [cls method]; /* no method found (haven't verfied the exact warning)*/
}

@interface MyRoot (extension)
-method;
@end

void func2 (id obj, Class cls)
{
  [obj method];/* OK */
  [cls method]; /* OK */
}

So, yes, you must provide all relevant declarations for correct
diagnostics (and code generation).  But I don't think we should ignoring
the information we /do/ have.

I guess what's bothering you, is that when you use
Class <Proto2> clsP2;
and you know there are certain root classes that adopt this protocol and
you expect the object to be one of them or even test with
respondsToSelector: before dispatching thje instance method, ... that you
would have to #include/#import the header of one of those root class so
that messages sent to clsP2 would use the instance methods, if we
constrained them as I described.  OTOH, if we use an instance method on a
class (Class cls) we would also have to #include/#import a root class
which declares that instance method for the compiler to produce the
correct disgonstics and select the correct prototype.  I think the same
logic applies here.

Cheers,
David




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]