From 73f4cb4c0302abfa389d7211a9c979ef2a8da71f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 15 May 2002 23:24:19 +0000 Subject: [PATCH] it seems object info emition works (needs more testing) --- tools/qfcc/include/class.h | 8 +++ tools/qfcc/include/method.h | 3 + tools/qfcc/include/qfcc.h | 2 +- tools/qfcc/include/struct.h | 2 + tools/qfcc/include/type.h | 4 +- tools/qfcc/source/class.c | 114 +++++++++++++++++++++++++++++++++++ tools/qfcc/source/expr.c | 2 +- tools/qfcc/source/method.c | 68 +++++++++++++++++++++ tools/qfcc/source/pr_def.c | 18 ++---- tools/qfcc/source/qc-parse.y | 40 +++++++----- tools/qfcc/source/struct.c | 40 +++++++++++- tools/qfcc/source/type.c | 91 +++++++++++++++++++++++----- 12 files changed, 344 insertions(+), 48 deletions(-) diff --git a/tools/qfcc/include/class.h b/tools/qfcc/include/class.h index c61a0dc96..7bca53a21 100644 --- a/tools/qfcc/include/class.h +++ b/tools/qfcc/include/class.h @@ -40,8 +40,10 @@ typedef struct class_s { struct type_s *ivars; struct methodlist_s *methods; struct protocollist_s *protocols; + struct def_s *def; } class_t; +struct method_s; struct protocol_s; struct type_s; @@ -50,6 +52,8 @@ void class_add_methods (class_t *class, struct methodlist_s *methods); void class_add_protocol_methods (class_t *class, expr_t *protocols); void class_add_protocol (class_t *class, struct protocol_s *protocol); void class_check_ivars (class_t *class, struct type_s *ivars); +void class_finish (class_t *class); +struct method_s *class_find_method (class_t *class, struct method_s *method); struct def_s *class_def (class_t *class); class_t *get_category (const char *class_name, const char *category_name, int create); @@ -57,6 +61,7 @@ class_t *get_category (const char *class_name, const char *category_name, typedef struct protocol_s { const char *name; struct methodlist_s *methods; + struct protocollist_s *protocols; } protocol_t; typedef struct protocollist_s { @@ -71,4 +76,7 @@ struct def_s *protocol_def (protocol_t *protocol); protocollist_t *new_protocollist (void); void add_protocol (protocollist_t *protocollist, protocol_t *protocol); +int emit_protocol (protocol_t *protocol); +int emit_protocol_list (protocollist_t *protocols, const char *name); + #endif//__class_h diff --git a/tools/qfcc/include/method.h b/tools/qfcc/include/method.h index ec8214eed..62b4dd65c 100644 --- a/tools/qfcc/include/method.h +++ b/tools/qfcc/include/method.h @@ -66,6 +66,7 @@ def_t *method_def (struct class_s *class, method_t *method); methodlist_t *new_methodlist (void); void copy_methods (methodlist_t *dst, methodlist_t *src); +int method_compare (method_t *m1, method_t *m2); keywordarg_t *new_keywordarg (const char *selector, struct expr_s *expr); @@ -75,4 +76,6 @@ void selector_name (struct dstring_s *sel_id, keywordarg_t *selector); void selector_types (struct dstring_s *sel_types, keywordarg_t *selector); struct def_s *selector_def (const char *sel_id, const char *sel_types); +int emit_methods (methodlist_t *methods, const char *name, int instance); + #endif//__method_h diff --git a/tools/qfcc/include/qfcc.h b/tools/qfcc/include/qfcc.h index 477fa006a..04e3aff14 100644 --- a/tools/qfcc/include/qfcc.h +++ b/tools/qfcc/include/qfcc.h @@ -419,7 +419,6 @@ extern int pr_source_line; extern def_t *pr_scope; extern int pr_error_count; -int PR_GetTypeSize (type_t *type); def_t *PR_GetArray (type_t *etype, const char *name, int size, def_t *scope, int *allocate); @@ -439,6 +438,7 @@ void PR_DefInitialized (def_t *d); #define G_VECTOR(o) (&pr_globals[o]) #define G_STRING(o) (strings + *(string_t *)&pr_globals[o]) #define G_FUNCTION(o) (*(func_t *)&pr_globals[o]) +#define G_STRUCT(t,o) (*(t *)&pr_globals[o]) extern string_t s_file; // filename for function definition diff --git a/tools/qfcc/include/struct.h b/tools/qfcc/include/struct.h index d05589310..55f4f1108 100644 --- a/tools/qfcc/include/struct.h +++ b/tools/qfcc/include/struct.h @@ -54,6 +54,8 @@ struct type_s *new_struct (const char *name); struct type_s *find_struct (const char *name); void copy_struct_fields (struct type_s *dst, struct type_s *src); +int emit_struct (struct type_s *strct, const char *name); + void process_enum (struct expr_s *enm); expr_t *get_enum (const char *name); diff --git a/tools/qfcc/include/type.h b/tools/qfcc/include/type.h index e0d6be3c3..1b80771d7 100644 --- a/tools/qfcc/include/type.h +++ b/tools/qfcc/include/type.h @@ -51,8 +51,9 @@ extern type_t type_Class; extern type_t type_Protocol; extern type_t type_SEL; extern type_t type_IMP; -extern type_t type_method_list; extern type_t *type_method; +extern type_t *type_category; +extern type_t *type_ivar; extern def_t def_void; extern def_t def_function; @@ -65,6 +66,7 @@ type_t *get_typedef (const char *name); type_t *pointer_type (type_t *aux); void print_type (type_t *type); void encode_type (struct dstring_s *encodking, type_t *type); +int type_size (type_t *type); void init_types (void); diff --git a/tools/qfcc/source/class.c b/tools/qfcc/source/class.c index 945f1ba9f..3d54a407e 100644 --- a/tools/qfcc/source/class.c +++ b/tools/qfcc/source/class.c @@ -32,6 +32,8 @@ static const char rcsid[] = #include "QF/dstring.h" #include "QF/hash.h" +#include "QF/pr_obj.h" +#include "QF/va.h" #include "qfcc.h" @@ -116,6 +118,71 @@ class_add_protocol (class_t *class, protocol_t *protocol) add_protocol (class->protocols, protocol); } +void +class_finish (class_t *class) +{ + if (class->def) + return; + if (class->class_name && class->category_name) { + def_t *category_def; + pr_category_t *category; + + category_def = PR_GetDef (type_category, + va ("_OBJ_CATEGORY_%s_%s", + class->class_name, + class->category_name), + 0, &numpr_globals); + category = &G_STRUCT (pr_category_t, category_def->ofs); + } else if (class->class_name) { + def_t *meta_def; + pr_class_t *meta; + pr_class_t *cls; + + meta_def = PR_GetDef (type_Class.aux_type, + va ("_OBJ_METACLASS_%s", class->class_name), + 0, &numpr_globals); + meta = &G_STRUCT (pr_class_t, meta_def->ofs); + memset (meta, 0, sizeof (*meta)); + meta->class_pointer = ReuseString (class->class_name); + meta->name = meta->class_pointer; + meta->instance_size = type_size (type_Class.aux_type); + meta->ivars = emit_struct (type_Class.aux_type, "Class"); + meta->methods = emit_methods (class->methods, class->class_name, 0); + meta->protocols = emit_protocol_list (class->protocols, + class->class_name); + + class->def = PR_GetDef (type_Class.aux_type, + va ("_OBJ_METACLASS_%s", class->class_name), + 0, &numpr_globals); + cls = &G_STRUCT (pr_class_t, class->def->ofs); + cls->class_pointer = meta_def->ofs; + if (class->super_class) + cls->super_class = class->super_class->def->ofs; + cls->name = meta->name; + cls->instance_size = type_size (class->ivars); + cls->ivars = emit_struct (class->ivars, class->class_name); + cls->methods = emit_methods (class->methods, class->class_name, 1); + cls->protocols = meta->protocols; + } +} + +method_t * +class_find_method (class_t *class, method_t *method) +{ + method_t *m; + dstring_t *sel; + + for (m = class->methods->head; m; m = m->next) + if (method_compare (method, m)) + return m; + sel = dstring_newstr (); + selector_name (sel, (keywordarg_t *)method->selector); + warning (0, "method %s not in %s%s", sel->str, class->class_name, + class->category_name ? va (" (%s)", class->category_name) : ""); + dstring_delete (sel); + return method; +} + static unsigned long category_get_hash (void *_c, void *unused) { @@ -244,3 +311,50 @@ add_protocol (protocollist_t *protocollist, protocol_t *protocol) * sizeof (protocollist_t)); protocollist->list[protocollist->count++] = protocol; } + +int +emit_protocol (protocol_t *protocol) +{ + def_t *proto_def; + pr_protocol_t *proto; + + proto_def = PR_GetDef (type_Protocol.aux_type, + va ("_OBJ_PROTOCOL_%s", protocol->name), + 0, &numpr_globals); + proto = &G_STRUCT (pr_protocol_t, proto_def->ofs); + proto->class_pointer = 0; + proto->protocol_name = ReuseString (protocol->name); + proto->protocol_list = + emit_protocol_list (protocol->protocols, + va ("PROTOCOL_%s", protocol->name)); + proto->instance_methods = emit_methods (protocol->methods, + protocol->name, 1); + proto->class_methods = emit_methods (protocol->methods, protocol->name, 0); + return proto_def->ofs; +} + +int +emit_protocol_list (protocollist_t *protocols, const char *name) +{ + def_t *proto_list_def; + type_t *protocol_list; + pr_protocol_list_t *proto_list; + int i; + + if (!protocols) + return 0; + protocol_list = new_struct (0); + new_struct_field (protocol_list, &type_pointer, "next", vis_public); + new_struct_field (protocol_list, &type_integer, "count", vis_public); + for (i = 0; i < protocols->count; i++) + new_struct_field (protocol_list, &type_pointer, 0, vis_public); + proto_list_def = PR_GetDef (type_Protocol.aux_type, + va ("_OBJ_PROTOCOLS_%s", name), + 0, &numpr_globals); + proto_list = &G_STRUCT (pr_protocol_list_t, proto_list_def->ofs); + proto_list->next = 0; + proto_list->count = protocols->count; + for (i = 0; i < protocols->count; i++) + proto_list->list[i] = emit_protocol (protocols->list[i]); + return proto_list_def->ofs; +} diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 95f3d5496..78f27862b 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -1693,7 +1693,7 @@ array_expr (expr_t *array, expr_t *index) && index->type >= ex_integer && index->e.uinteger_val >= array_type->num_parms) return error (index, "array index out of bounds"); - size = PR_GetTypeSize (array_type->aux_type); + size = type_size (array_type->aux_type); if (size > 1) { scale = new_expr (); scale->type = expr_types[index_type->type]; diff --git a/tools/qfcc/source/method.c b/tools/qfcc/source/method.c index 43c156c7f..93b7242f8 100644 --- a/tools/qfcc/source/method.c +++ b/tools/qfcc/source/method.c @@ -32,11 +32,14 @@ static const char rcsid[] = #include "QF/dstring.h" #include "QF/hash.h" +#include "QF/pr_obj.h" +#include "QF/va.h" #include "qfcc.h" #include "class.h" #include "method.h" +#include "struct.h" #include "type.h" static def_t *send_message_def; @@ -123,6 +126,31 @@ copy_methods (methodlist_t *dst, methodlist_t *src) } } +int +method_compare (method_t *m1, method_t *m2) +{ + dstring_t *s1 = dstring_newstr (); + dstring_t *s2 = dstring_newstr (); + dstring_t *t1 = dstring_newstr (); + dstring_t *t2 = dstring_newstr (); + int res; + + selector_name (s1, (keywordarg_t *)m1->selector); + selector_name (s2, (keywordarg_t *)m2->selector); + selector_types (t1, (keywordarg_t *)m1->selector); + selector_types (t2, (keywordarg_t *)m2->selector); + + res = strcmp (s1->str, s2->str) == 0 + && strcmp (t1->str, t2->str) == 0; + + dstring_delete (s1); + dstring_delete (s2); + dstring_delete (t1); + dstring_delete (t2); + + return res; +} + keywordarg_t * new_keywordarg (const char *selector, struct expr_s *expr) { @@ -168,6 +196,7 @@ selector_name (dstring_t *sel_id, keywordarg_t *selector) void selector_types (dstring_t *sel_types, keywordarg_t *selector) { + dstring_clearstr (sel_types); } typedef struct { @@ -228,3 +257,42 @@ selector_def (const char *_sel_id, const char *_sel_types) Hash_AddElement (sel_def_hash, sel_def); return sel_def->def; } + +int +emit_methods (methodlist_t *_methods, const char *name, int instance) +{ + const char *type = instance ? "INSTANCE" : "CLASS"; + method_t *method; + int i, count; + def_t *methods_def; + pr_method_list_t *methods; + type_t *method_list; + dstring_t *tmp = dstring_newstr (); + + for (count = 0, method = _methods->head; method; method = method->next) + if (!method->instance == !instance) + count++; + method_list = new_struct (0); + new_struct_field (method_list, &type_pointer, "method_next", vis_public); + new_struct_field (method_list, &type_integer, "method_count", vis_public); + for (i = 0; i < count; i++) + new_struct_field (method_list, type_method, 0, vis_public); + methods_def = PR_GetDef (method_list, va ("_OBJ_%s_METHODS_%s", type, name), + 0, &numpr_globals); + methods = &G_STRUCT (pr_method_list_t, methods_def->ofs); + methods->method_next = 0; + methods->method_count = count; + for (i = 0, method = _methods->head; method; method = method->next) { + if (!method->instance != !instance) + continue; + selector_name (tmp, (keywordarg_t *)method->selector); + methods->method_list[i].method_name.sel_id = ReuseString (tmp->str); + selector_name (tmp, (keywordarg_t *)method->selector); + methods->method_list[i].method_name.sel_types = ReuseString (tmp->str); + methods->method_list[i].method_types = + methods->method_list[i].method_name.sel_types; + methods->method_list[i].method_imp = method->def->ofs; + } + dstring_delete (tmp); + return methods_def->ofs; +} diff --git a/tools/qfcc/source/pr_def.c b/tools/qfcc/source/pr_def.c index d3bcf25b7..41dd8892f 100644 --- a/tools/qfcc/source/pr_def.c +++ b/tools/qfcc/source/pr_def.c @@ -93,20 +93,12 @@ PR_GetArray (type_t *etype, const char *name, int size, def_t *scope, def = PR_NewDef (type, name, scope); def->ofs = *allocate; def->initialized = def->constant = 1; - *allocate += pr_type_size[type->type] * size + 1; + *allocate += type_size (type) * size + 1; pr_global_defs[def->ofs] = def; G_INT (def->ofs) = def->ofs + 1; return def; } -int -PR_GetTypeSize (type_t *type) -{ - if (type->type == ev_struct) - return type->num_parms; - return pr_type_size[type->type]; -} - /* PR_GetDef @@ -153,7 +145,7 @@ PR_GetDef (type_t *type, const char *name, def_t *scope, int *allocate) d->used = 1; d->parent = def; } else { - *allocate += PR_GetTypeSize(type); + *allocate += type_size (type); } if (type->type == ev_field) { @@ -178,16 +170,16 @@ PR_GetDef (type_t *type, const char *name, def_t *scope, int *allocate) d->parent = def; } else if (type->aux_type->type == ev_pointer) { //FIXME I don't think this is right for a field pointer - size = PR_GetTypeSize (type->aux_type->aux_type); + size = type_size (type->aux_type->aux_type); pr.size_fields += type->aux_type->num_parms * size; } else { - size = PR_GetTypeSize (type->aux_type); + size = type_size (type->aux_type); pr.size_fields += size; } } else if (type->type == ev_pointer && type->num_parms) { int ofs = *allocate; - size = PR_GetTypeSize (type->aux_type); + size = type_size (type->aux_type); *allocate += type->num_parms * size; if (pr_scope) { diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 878496d3b..1fe988386 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -869,6 +869,8 @@ obj_def { if (!current_class) PARSE_ERROR; + else + class_finish (current_class); current_class = 0; } ; @@ -1060,41 +1062,47 @@ ivar_declarator ; methoddef - : '+' - methoddecl opt_state_expr + : '+' methoddecl { $2->instance = 0; + $2 = class_find_method (current_class, $2); + } + opt_state_expr + { current_def = $2->def = method_def (current_class, $2); current_params = $2->params; } begin_function statement_block end_function { - build_function ($5); - if ($3) { - $3->next = $6; - emit_function ($5, $3); + build_function ($6); + if ($4) { + $4->next = $7; + emit_function ($6, $4); } else { - emit_function ($5, $6); + emit_function ($6, $7); } - finish_function ($5); + finish_function ($6); } - | '-' - methoddecl opt_state_expr + | '-' methoddecl { $2->instance = 1; + $2 = class_find_method (current_class, $2); + } + opt_state_expr + { current_def = $2->def = method_def (current_class, $2); current_params = $2->params; } begin_function statement_block end_function { - build_function ($5); - if ($3) { - $3->next = $6; - emit_function ($5, $3); + build_function ($6); + if ($4) { + $4->next = $7; + emit_function ($6, $4); } else { - emit_function ($5, $6); + emit_function ($6, $7); } - finish_function ($5); + finish_function ($6); } ; diff --git a/tools/qfcc/source/struct.c b/tools/qfcc/source/struct.c index f7a865e16..8950283dd 100644 --- a/tools/qfcc/source/struct.c +++ b/tools/qfcc/source/struct.c @@ -30,11 +30,15 @@ static const char rcsid[] = "$Id$"; +#include #include +#include #include +#include #include "qfcc.h" #include "struct.h" +#include "type.h" typedef struct { const char *name; @@ -80,11 +84,12 @@ new_struct_field (type_t *strct, type_t *type, const char *name, field->name = name; field->type = type; field->offset = strct->num_parms; - strct->num_parms += pr_type_size[type->type]; + strct->num_parms += type_size (type); field->next = 0; *strct->struct_tail = field; strct->struct_tail = &field->next; - Hash_Add (strct->struct_fields, field); + if (name) + Hash_Add (strct->struct_fields, field); return field; } @@ -162,6 +167,37 @@ struct_compare_fields (struct type_s *s1, struct type_s *s2) return !((!f1) ^ !(f2)); } +int +emit_struct(type_t *strct, const char *name) +{ + struct_field_t *field; + int i, count; + def_t *ivars_def; + pr_ivar_list_t *ivars; + type_t *ivar_list; + dstring_t *encoding = dstring_newstr (); + + for (count = 0, field = strct->struct_head; field; field = field->next) + count++; + ivar_list = new_struct (0); + new_struct_field (ivar_list, &type_integer, "ivar_count", vis_public); + for (i = 0; i < count; i++) + new_struct_field (ivar_list, type_ivar, 0, vis_public); + ivars_def = PR_GetDef (ivar_list, va ("_OBJ_INSTANCE_VARIABLES_%s", name), + 0, &numpr_globals); + ivars = &G_STRUCT (pr_ivar_list_t, ivars_def->ofs); + ivars->ivar_count = count; + for (i = 0, field = strct->struct_head; field; i++, field = field->next) { + encode_type (encoding, field->type); + ivars->ivar_list[i].ivar_name = ReuseString (field->name); + ivars->ivar_list[i].ivar_type = ReuseString (encoding->str); + ivars->ivar_list[i].ivar_offset = field->offset; + dstring_clearstr (encoding); + } + dstring_delete (encoding); + return ivars_def->ofs; +} + void process_enum (expr_t *enm) { diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index 638259700..4b3994455 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -39,6 +39,7 @@ static const char rcsid[] = #include "qfcc.h" #include "function.h" #include "struct.h" +#include "type.h" typedef struct { const char *name; @@ -55,7 +56,7 @@ type_t type_field = { ev_field }; // type_function is a void() function used for state defs type_t type_function = { ev_func, NULL, &type_void }; -type_t type_pointer = { ev_pointer }; +type_t type_pointer = { ev_pointer, NULL, &type_void }; type_t type_quaternion = { ev_quaternion }; type_t type_integer = { ev_integer }; type_t type_uinteger = { ev_uinteger }; @@ -67,8 +68,9 @@ type_t type_Class = { ev_pointer }; type_t type_Protocol = { ev_pointer }; type_t type_SEL = { ev_pointer }; type_t type_IMP = { ev_func, NULL, &type_id, -3, { &type_id, &type_SEL }}; -type_t type_method_list = { ev_pointer }; type_t *type_method; +type_t *type_category; +type_t *type_ivar; type_t type_floatfield = { ev_field, NULL, &type_float }; @@ -295,9 +297,11 @@ _encode_type (dstring_t *encoding, type_t *type, int level) case ev_class: dstring_appendstr (encoding, "{"); //XXX dstring_appendstr (encoding, name); - dstring_appendstr (encoding, "="); - for (field = type->struct_head; field; field = field->next) - _encode_type (encoding, field->type, level + 1); + if (level < 2) { + dstring_appendstr (encoding, "="); + for (field = type->struct_head; field; field = field->next) + _encode_type (encoding, field->type, level + 1); + } dstring_appendstr (encoding, "}"); break; case ev_sel: @@ -315,6 +319,42 @@ encode_type (dstring_t *encoding, type_t *type) _encode_type (encoding, type, 0); } +int +type_size (type_t *type) +{ + struct_field_t *field; + int size; + + if (!type) + return 0; + switch (type->type) { + case ev_void: + case ev_string: + case ev_float: + case ev_vector: + case ev_entity: + case ev_field: + case ev_func: + case ev_pointer: + case ev_quaternion: + case ev_integer: + case ev_uinteger: + case ev_short: + case ev_sel: + case ev_type_count: + return pr_type_size[type->type]; + case ev_struct: + case ev_object: + case ev_class: + for (size = 0, field = type->struct_head; + field; + field = field->next) + size += type_size (field->type); + return size; + } + return 0; +} + void init_types (void) { @@ -341,28 +381,51 @@ init_types (void) new_struct_field (type, &type_string, "sel_types", vis_public); chain_type (&type_SEL); - type_method = new_struct ("obj_method"); + type_method = new_struct (0); new_struct_field (type_method, &type_SEL, "method_name", vis_public); new_struct_field (type_method, &type_string, "method_types", vis_public); new_struct_field (type_method, &type_IMP, "method_imp", vis_public); chain_type (type_method); - type = type_method_list.aux_type = new_struct ("obj_method_list"); - new_struct_field (type, &type_method_list, "method_next", vis_public); - new_struct_field (type, &type_integer, "method_count", vis_public); - new_struct_field (type, array_type (type_method, 1), - "method_list", vis_public); - chain_type (&type_method_list); - type = type_Class.aux_type = new_struct ("Class"); + new_struct_field (type, &type_Class, "class_pointer", vis_public); new_struct_field (type, &type_Class, "super_class", vis_public); - new_struct_field (type, &type_Class, "methods", vis_public); + new_struct_field (type, &type_string, "name", vis_public); + new_struct_field (type, &type_integer, "version", vis_public); + new_struct_field (type, &type_integer, "info", vis_public); + new_struct_field (type, &type_integer, "instance_size", vis_public); + new_struct_field (type, &type_pointer, "ivars", vis_public); + new_struct_field (type, &type_pointer, "methods", vis_public); + new_struct_field (type, &type_pointer, "dtable", vis_public); + new_struct_field (type, &type_pointer, "subclass_list", vis_public); + new_struct_field (type, &type_pointer, "sibling_class", vis_public); + new_struct_field (type, &type_pointer, "protocols", vis_public); + new_struct_field (type, &type_pointer, "gc_object_type", vis_public); chain_type (&type_Class); type = type_Protocol.aux_type = new_struct ("Protocol"); + new_struct_field (type, &type_Class, "class_pointer", vis_public); + new_struct_field (type, &type_string, "protocol_name", vis_public); + new_struct_field (type, &type_pointer, "protocol_list", vis_public); + new_struct_field (type, &type_pointer, "instance_methods", vis_public); + new_struct_field (type, &type_pointer, "class_methods", vis_public); chain_type (&type_Protocol); type = type_id.aux_type = new_struct ("id"); new_struct_field (type, &type_Class, "class_pointer", vis_public); chain_type (&type_id); + + type = type_category = new_struct (0); + new_struct_field (type, &type_string, "category_name", vis_public); + new_struct_field (type, &type_string, "class_name", vis_public); + new_struct_field (type, &type_pointer, "instance_methods", vis_public); + new_struct_field (type, &type_pointer, "class_methods", vis_public); + new_struct_field (type, &type_pointer, "protocols", vis_public); + chain_type (type_category); + + type = type_ivar = new_struct (0); + new_struct_field (type, &type_string, "ivar_name", vis_public); + new_struct_field (type, &type_string, "ivar_type", vis_public); + new_struct_field (type, &type_integer, "ivar_offset", vis_public); + chain_type (type_ivar); }