[qfcc] Implement @protocol(foo)

Unlike gcc, qfcc requires foo to be defined, not just declared (I
suspect this is a bug in gcc, or even the ObjC spec), because allowing
forward declarations causes an empty (no methods) protocol to be
emitted, and then when the protocol is actually defined, one with
methods, resulting in two different versions of the same protocol, which
comments in the gnu objc runtime specifically state is a problem but is
not checked because it "never happens in practice" (found while
investigating gcc's behavior with @protocol and just what some of the
comments about static instance lists meant).
This commit is contained in:
Bill Currie 2020-03-02 10:42:26 +09:00
parent 254bf29bd4
commit 544d7de1ec
3 changed files with 14 additions and 4 deletions

View file

@ -74,6 +74,7 @@ typedef struct protocol_s {
const char *name;
struct methodlist_s *methods;
struct protocollist_s *protocols;
struct def_s *def;
class_type_t class_type;
} protocol_t;

View file

@ -1387,8 +1387,10 @@ protocol_add_protocols (protocol_t *protocol, protocollist_t *protocols)
def_t *
protocol_def (protocol_t *protocol)
{
return make_symbol (protocol->name, &type_obj_protocol,
pr.far_data, sc_static)->s.def;
if (!protocol->def) {
protocol->def = emit_protocol (protocol);
}
return protocol->def;
}
protocollist_t *

View file

@ -2470,9 +2470,16 @@ selector_expr (keywordarg_t *selector)
}
expr_t *
protocol_expr (const char *protocol)
protocol_expr (const char *protocol_name)
{
return error (0, "not implemented");
protocol_t *protocol = get_protocol (protocol_name, 0);
if (!protocol) {
return error (0, "cannot find protocol declaration for `%s'",
protocol_name);
}
class_t *proto_class = get_class (new_symbol ("Protocol"), 1);
return new_pointer_expr (0, proto_class->type, protocol_def (protocol));
}
expr_t *