This is the mail archive of the 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: Your 'Class <Protocol>' Work

David Ayers wrote:

If you need more explanations, I'll have to ask you be a little patient,
and I'll try to summarize the patch again.  Otherwise, I'd be glad to
know what you think.

So here is the overview of this patch:

It implements protocol qualified 'Class' reference for Objective-C.

It changes the formal grammar by removing the 'id' keyword which was used for the type specifier:

id [ protocol-reference-list ]

and changes this type specifier to:

typedef-name [ protocol-reference-list ]

yet the code asserts that the provided typedef-name corresponds to either 'id' or 'Class'. This change also allows us to remove a workaround for the cases that 'id' actually corresponded to a non-typedef identifier: (i.e. void foo (id id);)

lookup_method_protocol_in_list now takes either 0, 1 or 2 as the search flag. This function searches the provided protocol list for the selector. The search option 0 indicates that only instance methods are searched, 1 only class methods and 2 class methods and instance methods of protocols that have been adopted by root classes, but the class methods take precedence. When the search is done with 2 it first searches the class methods, just like option 1, yet if none is found it continues to search for instance methods in protocols which have been marked as declared by a root class. If a match is found, it emits the proposed diagnostics that the class method prototype wasn't found, yet it will use the instance methods prototype. Even though there is only one call site which explicitly uses 2 as the search option, this mechanism cannot be special cased there as l_m_p_i_l calls itself recursively with the current search option.

-> Note: This new warning implies that protocols like <NSObject> should repeat their instance method declarations as class methods to avoid this warning. This also implies that when root classes adopt such protocols, the the compiler should not warn about the class variants not being implemented if instance variants are. I think we should leave this until after this patch though.

objc_finish_interface has been adapted to call the new mark_protocols_adopted_by_root_class function to mark protocols which will be considered by lookup_method_protocol_in_list so that the fallback mechanism to instance prototypes is not unduly invoked. For marked protocols which where previously merely forward declared, we register the incorporated/inherited protocols. We also register the instance methods of the marked protocol directly with the global class method list to avoid creating a method list merely to call mark_protocols_adopted_by_root_class for the current protocol.

static void
mark_protocols_adopted_by_root_class (tree rprotos)
/* Iterates over the protocol interface list RPROTOS marking each as
   PROTOCOL_ADOPTED_BY_ROOT_CLASS.  Registers the instance methods
   prototypes of each protocol and their incorporated protocols
   recursively as potential class methods.  */

-> Note: I'm aware that you mentioned that you do not believe this is necessary, but after considering that this will allow us to better differentiate the diagnostics for categories on root classes like NSObject, also considering that few of the "root class categories" currently repeat their instance methods as class methods and considering the maintenance and processing overhead which I find minimal, I think it is legitimate. If you feel very strongly about it, I would remove this and do the extra lookup in lookup_method_protocol_in_list independent of whether a protocol is adopted by a root class.

objc_comptypes has been adapted to handle protocol qualified 'Class' type. For comments about the structure of the previous and new implementation, may I refer you to about the middle of:

I hope that this shows that extracting the protocol comparison into the new:

static inline
int objc_comptypes_proto_proto(tree lhs, tree rhs, int reflexive)
 /* Return 1 if LHS and RHS are compatible types for assignment or
    various other operations.  Return 0 if they are incompatible.
    When the operation is REFLEXIVE (typically comparisons), check
    for compatibility in either direction; when it's not (typically
    assignments), don't.

    This is a helper function for objc_comptypes to be able to test
    two protocol qualified types of the same basic type to insure
    protocol conformance and to emit the necessary warnings.  */

is the least invasive approach to objc_comptypes.

-> Note: Please let me know if you agree or whether the structure I think you wanted is indeed what you are looking for and I'll add the special case handling inline.
Yet if you agree with this structure then please indicate whether you'd prefer me to:
a) remove the IS_PROTOCOL_QUALIFIED_ID macro
c) leave the IS_PROTOCOL_QUALIFIED_ID macro untouched and handle IS_PROTOCOL_QUALIFIED_CLASS 'inline'

objc_finish_method_expr has been adapted to handle protocol qualified 'Class' types. As you requested, the hack to process 'Class' as a named class has been removed and it emits a new diagnostic "no '%c%s' method found" when no appropriate prototype has been found. It calls lookup_method_protocol_in_list with search option '2' for protocol qualified 'Class' references. The other calls to lookup_method_protocol_in_list have been updated to make the search flag explicit.

lookup_method_static has been updated to make the search flag used for calls to lookup_method_protocol_in_list explicit.

In some cases I've used the word 'incorporate' instead of 'inheritance' with respect to protocols as I'm still partial to that word now. If you feel strongly about it, I will revert that.

I offer to follow up with the identifier/naming cleanup to:

s/implemented by protocol/declared by protocol/g
insure that lhs and rhs identifier in objc_comptypes(_proto_proto) are properly named.

After the branch we can go for the following issues:

- ensure that the warning "does not fully implement the '%s' protocol" is not emitted for class methods of a protocol in a root class when an instance variant is implemented.
- have digest_init call objc_comptypes to emit diagnostics.
- cleanup digest_init to respect lhs/rhs when calling comptypes.
- make protocol qualified types their own true types
- cleanup objc_comptypes as needed
- reactivate Alexander Malmberg's patch wrt tracking conflicting prototypes
- adding objc support to the pretty printer functions (well maybe this should be moved up to ease doing the others :-) )

How does that sound?


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