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 20 Oct 2004, at 1.06, d.ayers@inode.at wrote:



On 19 Oct 2004, at 12.56, d.ayers@inode.at wrote:


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.

But the most you can say about Proto2 in your example is that none of
the
root classes that you have seen adopt it. Does that mean that _no_ root
class in your program adopts it and/or provides the methods that Proto2
requires?

As far as the compiler is concerned, yes! Just like:


@interface MyRoot
@end
@interface MyClass

You mean '@interface MyClass: MyRoot', right? Otherwise your subsequent argument
doesn't make sense.


-method1;
@end

means that no root class implements method1.  If non is seen by the
compiler then it should  warn if it sees:

void func(Class cls)
{
  [cls method1];  /* no method found */
}

as it correctly does. It doesn't make assumptions about whether there
could be some other root class that may implement method1 that it hasn't
seen yet. But once it does, it will not warn.

But you're messaging an unadorned 'Class' here, so you immediately fall back
to the hash table lookup. This is not related to our discussion.


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.

True, true... I guess perhaps we should think of notation to denote class objects of a specific type? :-)

Like I said, this is a different issue.


[snip]

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.

But do you know that none of the root classes (even in your own translation unit, let alone others) nevertheless provide the method you're looking for?

All the compiler knows and should know, is what it has seen (see example
above). If it sees more applicable prototypes then it should (and does)
take them into account.



For your approach to be fully consistent, shouldn't you _always_ check which protocols are adopted where? For example, given

   id <Foo, Bar, Baz> obj;
   [obj mess];

shouldn't you check whether Foo, Bar and Baz have been adopted by some
class somewhere, root or non-root?  I really don't think we want to go
down this path, not least because this would entail changing the
long-established semantics of message dispatch. :-(

Why do you think I'm inferring that there should be some root/non-root
handling here? I definitely didn't mean to. 'obj' is an object, and it
should only concern itself with instance methods. There are no implicit
semantics with respect to root classes or class methods.

Your proposal introduces the principle of actually checking where a given protocol is adopted when messaging an opaque receiver, and so you should apply this principle consistently.


 I think you're implying that "we may have not seen the
header that does", and therefor we shouldn't be using that
information.

Not when we're messaging an opaque receiver such as 'Class' or 'id'.
Aside from
collecting encountered method signatures in our global hash tables, we
shouldn't
make any assumptions about the type of the receiver (and, therefore,
whether the
root class of the receiver's hierarchy adopts a given protocol or not).



I am not making assumptions about the 'Class' other than consistently transfering the existing assumptions that we make in analogous cases:

@interace MyRoot
- method1;
@end
@interface MyClass : MyRoot
- method2;
@end

void func1(Class cls)
{
  [cls method1]; /* OK */
  [cls method2]; /* No method found */
}

If the compiler sees that a root class declares method1 (an instance
method) it also inserts it into the class hash list, as it /knows/ that
some root class implements it.

Yes, but that's because it is messaging an opaque receiver, so it is satisfied
with _any_ class method it can find, including instance methods of root classes.


If it doesn't see it in a root class (ie.
method2) then it warns. It is irrelevant whether later in the translation
unit it sees:


@interface MyRoot (extensions)
- method2;
@end

which include method2 in the class hash list and from then on will not
warn about that message being sent to 'Class cls' anymore:

void func2(Class cls)
{
  [cls method1]; /* OK */
  [cls method2]; /* OK */
}

Anyway, I think we're sort of circling the drain here. :-) I'll update
my patch
to fix the type comparison snafus you found. I think that I'll also
populate
the hash tables with methods from protocols, including handling of
forward-declared
protocols adopted by root classes.



Populating the class hash with instance methods of protocols unconstrained
is better than not populating them at all.

Well, no, I never suggested that all instance methods of protocols should be
inserted into the class hash table.


 But I still think we should do
better especially since you have now conceeded to collecting the
information we need.

The reason I agreed to collecting the information is to handle the case of
forward-declared protocols. Come to think of it, though, doing this is
probably not worth the candle (since you should really declare a protocol
before using it), so I'll omit it from my patch, at least for now.


I suspect we will not reach an agreement here on the whole "protocols adopted
by root classes" business, so I ask that you defer it till another patch.


--Zem


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