mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Attach protocolrefs to class types.
The protocolrefs (as protocollist_t) are attached to the type as a qualifier.
This commit is contained in:
parent
45c753f639
commit
f181772a76
5 changed files with 74 additions and 8 deletions
|
@ -102,9 +102,9 @@ extern class_type_t *current_class;
|
|||
|
||||
extern int obj_initialized;
|
||||
|
||||
struct dstring_s;
|
||||
struct expr_s;
|
||||
struct method_s;
|
||||
struct protocol_s;
|
||||
struct symbol_s;
|
||||
|
||||
class_t *extract_class (class_type_t *class_type);
|
||||
|
@ -147,7 +147,8 @@ void protocol_add_protocols (protocol_t *protocol, protocollist_t *protocols);
|
|||
struct def_s *protocol_def (protocol_t *protocol);
|
||||
protocollist_t *new_protocol_list (void);
|
||||
protocollist_t *add_protocol (protocollist_t *protocollist, const char *name);
|
||||
|
||||
int compare_protocols (protocollist_t *protos1, protocollist_t *protos2);
|
||||
void print_protocollist (struct dstring_s *dstr, protocollist_t *protocollist);
|
||||
struct def_s *emit_protocol (protocol_t *protocol);
|
||||
struct def_s *emit_protocol_list (protocollist_t *protocols, const char *name);
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ typedef struct type_s {
|
|||
struct type_s *next;
|
||||
int freeable;
|
||||
int allocated;
|
||||
struct protocollist_s *protos;
|
||||
const char *encoding; ///< Objective-QC encoding
|
||||
struct def_s *type_def; ///< offset of qfo encodoing
|
||||
} type_t;
|
||||
|
@ -154,6 +155,7 @@ int is_float (const type_t *type);
|
|||
int is_scalar (const type_t *type);
|
||||
int is_math (const type_t *type);
|
||||
int is_struct (const type_t *type);
|
||||
int is_id (const type_t *type);
|
||||
int is_class (const type_t *type);
|
||||
int is_array (const type_t *type);
|
||||
int type_assignable (const type_t *dst, const type_t *src);
|
||||
|
|
|
@ -1214,6 +1214,43 @@ add_protocol (protocollist_t *protocollist, const char *name)
|
|||
return protocollist;
|
||||
}
|
||||
|
||||
static int
|
||||
procollist_find_protocol (protocollist_t *protocollist, protocol_t *proto)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < protocollist->count; i++)
|
||||
if (protocollist->list[i] == proto)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
compare_protocols (protocollist_t *protos1, protocollist_t *protos2)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (protos2 == protos2)
|
||||
return 1;
|
||||
if (!protos1 || !protos2)
|
||||
return 0;
|
||||
if (protos1->count != protos2->count)
|
||||
return 0;
|
||||
for (i = 0; i < protos1->count; i++)
|
||||
if (!procollist_find_protocol (protos2, protos1->list[i]))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
print_protocollist (dstring_t *dstr, protocollist_t *protocollist)
|
||||
{
|
||||
int i;
|
||||
dstring_appendstr (dstr, "<");
|
||||
for (i = 0; i < protocollist->count; i++)
|
||||
dasprintf (dstr, "%s%s", i ? "," : "", protocollist->list[i]->name);
|
||||
dstring_appendstr (dstr, ">");
|
||||
}
|
||||
|
||||
def_t *
|
||||
emit_protocol (protocol_t *protocol)
|
||||
{
|
||||
|
|
|
@ -464,11 +464,23 @@ type_specifier
|
|||
}
|
||||
| OBJECT protocolrefs
|
||||
{
|
||||
$$ = make_spec (&type_id, 0, 0, 0);
|
||||
if ($2) {
|
||||
type_t type = *type_id.t.fldptr.type;
|
||||
type.protos = $2;
|
||||
$$ = make_spec (pointer_type (&type), 0, 0, 0);
|
||||
} else {
|
||||
$$ = make_spec (&type_id, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
| CLASS_NAME protocolrefs
|
||||
{
|
||||
$$ = make_spec ($1->type, 0, 0, 0);
|
||||
if ($2) {
|
||||
type_t type = *$1->type;
|
||||
type.protos = $2;
|
||||
$$ = make_spec (find_type (&type), 0, 0, 0);
|
||||
} else {
|
||||
$$ = make_spec ($1->type, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
// NOTE: fields don't parse the way they should. This is not a problem
|
||||
// for basic types, but functions need special treatment
|
||||
|
|
|
@ -237,7 +237,7 @@ types_same (type_t *a, type_t *b)
|
|||
case ev_pointer:
|
||||
if (a->t.fldptr.type != b->t.fldptr.type)
|
||||
return 0;
|
||||
return 1;
|
||||
return compare_protocols (a->protos, b->protos);
|
||||
case ev_func:
|
||||
if (a->t.func.type != b->t.func.type
|
||||
|| a->t.func.num_params != b->t.func.num_params)
|
||||
|
@ -443,8 +443,10 @@ print_type_str (dstring_t *str, const type_t *type)
|
|||
}
|
||||
break;
|
||||
case ev_pointer:
|
||||
if (type == &type_id) {
|
||||
if (is_id (type)) {
|
||||
dasprintf (str, "id");
|
||||
if (type->t.fldptr.type->protos)
|
||||
print_protocollist (str, type->t.fldptr.type->protos);
|
||||
break;
|
||||
}
|
||||
if (type == &type_SEL) {
|
||||
|
@ -692,6 +694,18 @@ is_struct (const type_t *type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
is_id (const type_t *type)
|
||||
{
|
||||
if (type == &type_id)
|
||||
return 1;
|
||||
// type may be a qualified id
|
||||
if (type->type == ev_pointer
|
||||
&& type->t.fldptr.type == type_id.t.fldptr.type)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
is_class (const type_t *type)
|
||||
{
|
||||
|
@ -720,11 +734,11 @@ type_assignable (const type_t *dst, const type_t *src)
|
|||
if (dst->type == ev_field && src->type == ev_field)
|
||||
return 1;
|
||||
// id = any class pointer
|
||||
if (dst == &type_id && src->type == ev_pointer
|
||||
if (is_id (dst) && src->type == ev_pointer
|
||||
&& (is_class (src->t.fldptr.type) || src == &type_Class))
|
||||
return 1;
|
||||
// any class pointer = id
|
||||
if (src == &type_id && dst->type == ev_pointer
|
||||
if (is_id (src) && dst->type == ev_pointer
|
||||
&& (is_class (dst->t.fldptr.type) || dst == &type_Class))
|
||||
return 1;
|
||||
// pointer = array
|
||||
|
|
Loading…
Reference in a new issue