Commit 143dc646 by Kresten Krab Thorup

(-Wprotocol): added

(-Wprotocol): added
(flag_warn_protocol): New variable
(check_methods_accessible): New function
(check_protocol): Use check_methods or check_methods_accessible
depending on flag_warn_protocol to check protocol conformance.

(start_class): For class implementations Assign
SUPER_CLASS_NAME from interface specification if not present.

From-SVN: r4121
parent b800a01b
...@@ -445,6 +445,12 @@ FILE *gen_declaration_file; ...@@ -445,6 +445,12 @@ FILE *gen_declaration_file;
int warn_selector = 0; int warn_selector = 0;
/* Warn if methods required by a protocol are not implemented in the
class adopting it. When turned off, methods inherited to that
class are also considered implemented */
int flag_warn_protocol = 1;
/* tells "encode_pointer/encode_aggregate" whether we are generating /* tells "encode_pointer/encode_aggregate" whether we are generating
type descriptors for instance variables (as opposed to methods). type descriptors for instance variables (as opposed to methods).
Type descriptors for instance variables contain more information Type descriptors for instance variables contain more information
...@@ -533,6 +539,10 @@ lang_decode_option (p) ...@@ -533,6 +539,10 @@ lang_decode_option (p)
warn_selector = 1; warn_selector = 1;
else if (!strcmp (p, "-Wno-selector")) else if (!strcmp (p, "-Wno-selector"))
warn_selector = 0; warn_selector = 0;
else if (!strcmp (p, "-Wprotocol"))
flag_warn_protocol = 1;
else if (!strcmp (p, "-Wno-protocol"))
flag_warn_protocol = 0;
else if (!strcmp (p, "-fgnu-runtime")) else if (!strcmp (p, "-fgnu-runtime"))
flag_next_runtime = 0; flag_next_runtime = 0;
else if (!strcmp (p, "-fno-next-runtime")) else if (!strcmp (p, "-fno-next-runtime"))
...@@ -5280,6 +5290,69 @@ tree protocol; ...@@ -5280,6 +5290,69 @@ tree protocol;
return 1; return 1;
} }
/* Make sure all methods in CHAIN are accessible as MTYPE methods in
CONTEXT. This is one of two mechanisms to check protocol integrity
*/
static int
check_methods_accessible (chain, context, mtype)
tree chain;
tree context; /* implementation_context */
int mtype;
{
int first = 1;
tree list;
while (chain)
{
while (context)
{
if (mtype == '+')
list = CLASS_CLS_METHODS (context);
else
list = CLASS_NST_METHODS (context);
if (lookup_method (list, chain))
break;
else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE)
context = (CLASS_SUPER_NAME (context)
? lookup_interface (CLASS_SUPER_NAME (context))
: NULL_TREE);
else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE)
context = (CLASS_NAME (context)
? lookup_interface (CLASS_NAME (context))
: NULL_TREE);
else
abort ();
}
if (context == NULL_TREE)
{
if (first)
{
if (TREE_CODE (implementation_context)
== CLASS_IMPLEMENTATION_TYPE)
warning ("incomplete implementation of class `%s'",
IDENTIFIER_POINTER
(CLASS_NAME (implementation_context)));
else if (TREE_CODE (implementation_context)
== CATEGORY_IMPLEMENTATION_TYPE)
warning ("incomplete implementation of category `%s'",
IDENTIFIER_POINTER
(CLASS_SUPER_NAME (implementation_context)));
first = 0;
}
warning ("method definition for `%c%s' not found",
mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
}
chain = TREE_CHAIN (chain); /* next method... */
}
return first;
}
static void static void
check_protocols (proto_list, type, name) check_protocols (proto_list, type, name)
tree proto_list; tree proto_list;
...@@ -5295,12 +5368,21 @@ check_protocols (proto_list, type, name) ...@@ -5295,12 +5368,21 @@ check_protocols (proto_list, type, name)
int f1, f2; int f1, f2;
/* Ensure that all protocols have bodies! */ /* Ensure that all protocols have bodies! */
if (flag_warn_protocol) {
f1 = check_methods (PROTOCOL_CLS_METHODS (p), f1 = check_methods (PROTOCOL_CLS_METHODS (p),
CLASS_CLS_METHODS (implementation_context), CLASS_CLS_METHODS (implementation_context),
'+'); '+');
f2 = check_methods (PROTOCOL_NST_METHODS (p), f2 = check_methods (PROTOCOL_NST_METHODS (p),
CLASS_NST_METHODS (implementation_context), CLASS_NST_METHODS (implementation_context),
'-'); '-');
} else {
f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
implementation_context,
'+');
f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
implementation_context,
'-');
}
if (!f1 || !f2) if (!f1 || !f2)
warning ("%s `%s' does not fully implement the `%s' protocol", warning ("%s `%s' does not fully implement the `%s' protocol",
...@@ -5411,6 +5493,11 @@ start_class (code, class_name, super_name, protocol_list) ...@@ -5411,6 +5493,11 @@ start_class (code, class_name, super_name, protocol_list)
IDENTIFIER_POINTER (super_name)); IDENTIFIER_POINTER (super_name));
error ("previous declaration of `%s'", name); error ("previous declaration of `%s'", name);
} }
else if (! super_name)
{
CLASS_SUPER_NAME (implementation_context)
= CLASS_SUPER_NAME (implementation_template);
}
} }
else if (code == CLASS_INTERFACE_TYPE) else if (code == CLASS_INTERFACE_TYPE)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment