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


Ziemowit Laski wrote:
> Given the code
> 
>    @protocol Proto
>     - method1;
>     + method2;
>    @end
> 
>    @interface Base <Proto>
>    @end
> 
[snip]
> 
> My proposal to attack this problem goes as follows: Whenever we see
> an interface or category declaration, we examine the protocols
> adopted by said interface/category and insert their constituent
> method signature into the global class or instance method hash tables
> (as is already being done for methods declared by the 
> interface/category directly). Also, whenever we are dealing with a
> root class (or a category of a root class), we add any instance
> methods from the adopted protocols into the global class hash table
> (just as instance methods directly declared by root classes and 
> categories already are).
> 
> Such a fix should prevent us from issuing many superfluous warnings 
> when messaging objects of type 'id', 'id <Proto>', 'Class' and (now)
> 'Class <Proto>', and will make things more consistent with what
> happens when you message a specific type (e.g., 'NSObject *').
> 
> What do you think? Does anyone have any objections to this? I'll be 
> happy to clarify things if my missive is not understandable. :-)
> 

Your approach is correct but incomplete in an important way.  It is not
just a mater of finding some method in the global class hash table, it
is a matter of finding the appropriate method and using its
corresponding signature for code generation.

As previously pointed out on the gcc-patches@ list: Given common
selector names such as:

@protocol Proto1
- (const char *)name;
- (void)set;
- (int)compare:(id)obj;
- (int)host
@end

@protocol Proto2
- (NSString *)name;
- (NSSet *)set;
- (BOOL)compare:(id)obj;
- (NSString *)host
@end

combined with the fact that currently the instance prototypes of
protocols adopted by root classes are not repeated as their class
counterparts, I find the Class <protocol> support incomplete (to say the
least) if the code below doesn't chose the correct prototype wrt code
generation, independent of whether there are diagnostics emitted due to
the fact that the protocols do not explicitly reiterate the instance
methods as class methods.

@interface MyRoot1 <Proto1>
@end
@interface MyRoot2 <Proto2>
@end

void
foo(void)
{
  Class <MyProto1> cls1 = bar();
  Class <MyProto2> cls2 = baz();

  const char *name1 = [cls1 name];
  NSString *name2 = [cls2 name];

  [cls1 set];
  NSSet *set = [cls2 set];

  int comp1 = [cls1 compare: cls2];
  BOOL comp2 = [cls2 compare: cls1];

  int host1 = [cls1 host];
  NSHost *host2 = [cls2 host];

  ...
}

Cheers,
David

PS: For those that haven't followed this on gcc-patches@, the original
patch does handle this correctly albeit it did it silently.  I've also
posted a modified patch that would emit diagnostics about the fact that
there was no explicit class method in the protocol but would still use
the instance prototype.  I even offered a third version where the
instance prototypes are unconditionally searched as the previous
versions only searched, if the protocol was indeed adopted by some root
class.  I do not understand why using the instance method prototypes for
protocols adopted by root classes seems to be controversial issue.


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