From 2cd716176a89bf5db33032e852e772a18ddabc91 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 10 May 2002 00:00:23 +0000 Subject: [PATCH] more progress --- tools/qfcc/include/class.h | 26 ++- tools/qfcc/include/method.h | 8 +- tools/qfcc/include/struct.h | 10 +- tools/qfcc/include/type.h | 1 + tools/qfcc/source/class.c | 134 +++++++++++--- tools/qfcc/source/expr.c | 14 +- tools/qfcc/source/method.c | 26 ++- tools/qfcc/source/qc-parse.y | 331 ++++++++++++++++++----------------- tools/qfcc/source/struct.c | 25 ++- tools/qfcc/source/type.c | 26 +-- 10 files changed, 372 insertions(+), 229 deletions(-) diff --git a/tools/qfcc/include/class.h b/tools/qfcc/include/class.h index 9134817dd..4bc62cdab 100644 --- a/tools/qfcc/include/class.h +++ b/tools/qfcc/include/class.h @@ -32,29 +32,27 @@ #ifndef __class_h #define __class_h -#include "method.h" - typedef struct class_s { + int defined; const char *name; struct class_s *base; - methodlist_t methods; + struct methodlist_s *methods; + struct type_s *ivars; } class_t; typedef struct protocol_s { const char *name; - methodlist_t methods; + struct methodlist_s *methods; } protocol_t; -typedef struct category_s { - const char *name; - class_t *klass; - methodlist_t methods; -} category_t; +class_t *get_class (const char *name, int create); +void class_add_methods (class_t *class, struct methodlist_s *methods); +void class_add_protocol_methods (class_t *class, expr_t *protocols); +struct def_s *class_def (class_t *class); -class_t *new_class (const char *name, class_t *base); -protocol_t *new_protocol (const char *name); -category_t *new_category (const char *name, class_t *klass); -class_t *find_class (const char *name); -protocol_t *find_protocol (const char *name); +protocol_t *get_protocol (const char *name, int create); +void protocol_add_methods (protocol_t *protocol, struct methodlist_s *methods); +void protocol_add_protocol_methods (protocol_t *protocol, expr_t *protocols); +struct def_s *protocol_def (protocol_t *protocol); #endif//__class_h diff --git a/tools/qfcc/include/method.h b/tools/qfcc/include/method.h index 147d37c25..14bc82b86 100644 --- a/tools/qfcc/include/method.h +++ b/tools/qfcc/include/method.h @@ -43,7 +43,7 @@ typedef struct method_s { def_t *def; } method_t; -typedef struct { +typedef struct methodlist_s { method_t *head; method_t **tail; } methodlist_t; @@ -57,15 +57,17 @@ typedef struct keywordarg_s { } keywordarg_t; struct class_s; -struct category_s; struct expr_s; struct dstring_s; method_t *new_method (type_t *ret_type, param_t *selector, param_t *opt_parms); void add_method (methodlist_t *methodlist, method_t *method); -def_t *method_def (struct class_s *klass, struct category_s *category, +def_t *method_def (struct class_s *class, struct class_s *category, method_t *method); +methodlist_t *new_methodlist (void); +void copy_methods (methodlist_t *dst, methodlist_t *src); + keywordarg_t *new_keywordarg (const char *selector, struct expr_s *expr); struct expr_s *send_message (void); diff --git a/tools/qfcc/include/struct.h b/tools/qfcc/include/struct.h index 69c169d05..3a00933d6 100644 --- a/tools/qfcc/include/struct.h +++ b/tools/qfcc/include/struct.h @@ -32,18 +32,26 @@ #ifndef __struct_h #define __struct_h +typedef enum { + vis_private, + vis_protected, + vis_public, +} visibility_t; + typedef struct struct_field_s { struct struct_field_s *next; const char *name; struct type_s *type; int offset; + visibility_t visibility; } struct_field_t; struct_field_t *new_struct_field (struct type_s *strct, struct type_s *type, - const char *name); + const char *name, visibility_t visibility); struct_field_t *struct_find_field (struct type_s *strct, const char *name); 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); 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 58dcba5b5..406969715 100644 --- a/tools/qfcc/include/type.h +++ b/tools/qfcc/include/type.h @@ -48,6 +48,7 @@ extern type_t type_short; extern type_t type_struct; extern type_t type_id; 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; diff --git a/tools/qfcc/source/class.c b/tools/qfcc/source/class.c index bdf40354e..0c237bad8 100644 --- a/tools/qfcc/source/class.c +++ b/tools/qfcc/source/class.c @@ -31,55 +31,135 @@ static const char rcsid[] = "$Id$"; #include "QF/dstring.h" +#include "QF/hash.h" #include "qfcc.h" #include "class.h" +#include "method.h" #include "type.h" -class_t * -new_class (const char *name, class_t *base) -{ - class_t *c = malloc (sizeof (class_t)); +static hashtab_t *class_hash; +static hashtab_t *protocol_hash; +static const char * +class_get_key (void *class, void *unused) +{ + return ((class_t *) class)->name; +} + +static const char * +protocol_get_key (void *protocol, void *unused) +{ + return ((protocol_t *) protocol)->name; +} + +class_t * +get_class (const char *name, int create) +{ + class_t *c; + + if (!class_hash) + class_hash = Hash_NewTable (1021, class_get_key, 0, 0); + if (name) { + c = Hash_Find (class_hash, name); + if (c || !create) + return c; + } + + c = calloc (sizeof (class_t), 1); c->name = name; - c->base = base; - c->methods.head = 0; - c->methods.tail = &c->methods.head; + Hash_Add (class_hash, c); return c; } -protocol_t * -new_protocol (const char *name) +void +class_add_methods (class_t *class, methodlist_t *methods) { - protocol_t *p = malloc (sizeof (protocol_t)); + if (!methods) + return; + if (!class->methods) + class->methods = new_methodlist (); + *class->methods->tail = methods->head; + class->methods->tail = methods->tail; + free (methods); +} +void +class_add_protocol_methods (class_t *class, expr_t *protocols) +{ + expr_t *e; + protocol_t *p; + + if (!protocol_hash) + protocol_hash = Hash_NewTable (1021, protocol_get_key, 0, 0); + if (!class->methods) + class->methods = new_methodlist (); + + for (e = protocols; e; e = e->next) { + if (!(p = get_protocol (e->e.string_val, 0))) { + error (e, "undefined protocol `%s'", e->e.string_val); + continue; + } + copy_methods (class->methods, p->methods); + } +} + +def_t * +class_def (class_t *class) +{ + return PR_GetDef (&type_Class, class->name, 0, &numpr_globals); +} + +protocol_t * +get_protocol (const char *name, int create) +{ + protocol_t *p; + + if (name) { + p = Hash_Find (protocol_hash, name); + if (p || !create) + return p; + } + + p = calloc (sizeof (protocol_t), 1); p->name = name; - p->methods.head = 0; - p->methods.tail = &p->methods.head; + Hash_Add (protocol_hash, p); return p; } -category_t * -new_category (const char *name, class_t *klass) +void +protocol_add_methods (protocol_t *protocol, methodlist_t *methods) { - category_t *c = malloc (sizeof (category_t)); - - c->name = name; - c->klass = klass; - c->methods.head = 0; - c->methods.tail = &c->methods.head; - return c; + if (!methods) + return; + if (!protocol->methods) + protocol->methods = new_methodlist (); + *protocol->methods->tail = methods->head; + protocol->methods->tail = methods->tail; + free (methods); } -class_t * -find_class (const char *name) +void +protocol_add_protocol_methods (protocol_t *protocol, expr_t *protocols) { - return 0; + expr_t *e; + protocol_t *p; + + if (!protocol->methods) + protocol->methods = new_methodlist (); + + for (e = protocols; e; e = e->next) { + if (!(p = get_protocol (e->e.string_val, 0))) { + error (e, "undefined protocol `%s'", e->e.string_val); + continue; + } + copy_methods (protocol->methods, p->methods); + } } -protocol_t * -find_protocol (const char *name) +def_t * +protocol_def (protocol_t *protocol) { - return 0; + return PR_GetDef (&type_Protocol, protocol->name, 0, &numpr_globals); } diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 471be745c..ab688424f 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -39,6 +39,7 @@ static const char rcsid[] = #include "qfcc.h" #include "function.h" +#include "class.h" #include "method.h" #include "struct.h" #include "type.h" @@ -107,9 +108,17 @@ convert_name (expr_t *e) { if (e->type == ex_name) { const char *name = e->e.string_val; - def_t *d = PR_GetDef (NULL, name, pr_scope, 0); + def_t *d; expr_t *enm; + class_t *class; + class = get_class (name, 0); + if (class) { + e->type = ex_def; + e->e.def = class_def (class); + return; + } + d = PR_GetDef (NULL, name, pr_scope, 0); if (d) { e->type = ex_def; e->e.def = d; @@ -198,7 +207,6 @@ error (expr_t *e, const char *fmt, ...) pr_error_count++; if (e) { - e = new_expr (); e->type = ex_error; } return e; @@ -1444,6 +1452,8 @@ function_expr (expr_t *e1, expr_t *e2) if (e1->type == ex_error) return e1; + for (e = e2; e; e = e->next) + convert_name (e); for (e = e2; e; e = e->next) { if (e->type == ex_error) return e; diff --git a/tools/qfcc/source/method.c b/tools/qfcc/source/method.c index 5b1f2e2f1..849ce2fc6 100644 --- a/tools/qfcc/source/method.c +++ b/tools/qfcc/source/method.c @@ -77,7 +77,7 @@ add_method (methodlist_t *methodlist, method_t *method) } def_t * -method_def (class_t *klass, category_t *category, method_t *method) +method_def (class_t *class, class_t *category, method_t *method) { dstring_t *str = dstring_newstr (); dstring_t *sel = dstring_newstr (); @@ -87,7 +87,7 @@ method_def (class_t *klass, category_t *category, method_t *method) selector_name (sel, (keywordarg_t *)method->selector); dsprintf (str, "_%c_%s_%s_%s", method->instance ? 'i' : 'c', - klass->name, + class->name, category ? category->name : "", sel->str); for (s = str->str; *s; s++) @@ -101,6 +101,28 @@ method_def (class_t *klass, category_t *category, method_t *method) return def; } +methodlist_t * +new_methodlist (void) +{ + methodlist_t *l = malloc (sizeof (methodlist_t)); + l->head = 0; + l->tail = &l->head; + return l; +} + +void +copy_methods (methodlist_t *dst, methodlist_t *src) +{ + method_t *s, *d; + + for (s = src->head; s; s++) { + d = malloc (sizeof (method_t)); + *d = *s; + d->next = 0; + add_method (dst, d); + } +} + keywordarg_t * new_keywordarg (const char *selector, struct expr_s *expr) { diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 6564ac47c..6254bfd4c 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -64,16 +64,10 @@ hashtab_t *merge_local_inits (hashtab_t *dl_1, hashtab_t *dl_2); void restore_local_inits (hashtab_t *def_list); void free_local_inits (hashtab_t *def_list); -typedef struct { - type_t *type; - def_t *scope; -} scope_t; - %} %union { int op; - def_t *scope; def_t *def; struct hashtab_s *def_list; type_t *type; @@ -87,10 +81,10 @@ typedef struct { struct switch_block_s *switch_block; struct param_s *param; struct method_s *method; - struct class_s *klass; + struct class_s *class; struct protocol_s *protocol; - struct category_s *category; struct keywordarg_s *keywordarg; + struct methodlist_s *methodlist; } %right '=' ASX PAS /* pointer assign */ @@ -131,14 +125,17 @@ typedef struct { %type begin_function %type save_inits %type switch_block -%type param_scope %type selector reserved_word %type optparmlist unaryselector keyworddecl keywordselector %type methodproto methoddecl %type obj_expr identifier_list obj_messageexpr obj_string receiver +%type protocolrefs %type messageargs keywordarg keywordarglist selectorarg %type keywordnamelist keywordname +%type class_name new_class_name +%type protocol_name +%type methodprotolist methodprotolist2 %expect 2 // statement : if | if else, defs : defs def ';' | defs obj_def @@ -150,12 +147,12 @@ function_t *current_func; param_t *current_params; expr_t *current_init; class_t *current_class; -methodlist_t *current_methodlist; expr_t *local_expr; expr_t *break_label; expr_t *continue_label; switch_block_t *switch_block; type_t *struct_type; +visibility_t current_visibility; def_t *pr_scope; // the function being parsed, or NULL string_t s_file; // filename for function definition @@ -190,6 +187,16 @@ def struct_defs : /* empty */ | struct_defs struct_def ';' + | DEFS '(' NAME ')' + { + class_t *class = get_class ($3, 0); + + if (class) { + copy_struct_fields (struct_type, class->ivars); + } else { + error (0, "undefined symbol `%s'", $3); + } + } ; struct_def @@ -242,44 +249,20 @@ type_name ; function_decl - : '(' param_scope param_list + : '(' param_list ')' { $$ = reverse_params ($2); } + | '(' param_list ',' ELLIPSIS ')' { - PR_FlushScope (pr_scope, 1); - pr_scope = $2; - } - ')' - { - $$ = reverse_params ($3); - } - | '(' param_scope param_list ',' ELLIPSIS ')' - { - PR_FlushScope (pr_scope, 1); - pr_scope = $2; - $$ = new_param (0, 0, 0); - $$->next = $3; + $$->next = $2; $$ = reverse_params ($$); } - | '(' ELLIPSIS ')' - { - $$ = new_param (0, 0, 0); - } + | '(' ELLIPSIS ')' { $$ = new_param (0, 0, 0); } | '(' ')' { $$ = 0; } ; -param_scope - : /* empty */ - { - $$ = pr_scope; - pr_scope = PR_NewDef (0, 0, 0); - pr_scope->alloc = &pr_scope->locals; - *pr_scope->alloc = 0; - } - ; - param_list : param | param_list ',' param @@ -312,7 +295,7 @@ struct_def_list ; struct_def_item - : NAME { new_struct_field (struct_type, current_type, $1); } + : NAME { new_struct_field (struct_type, current_type, $1, vis_public); } ; def_list @@ -887,132 +870,147 @@ identifier_list } ; -classdecl /* XXX */ +classdecl : CLASS identifier_list { expr_t *e; for (e = $2->e.block.head; e; e = e->next) - new_class (e->e.string_val, 0); + get_class (e->e.string_val, 1); } ; -classdef /* XXX */ - : INTERFACE NAME - protocolrefs +class_name + : NAME { - $$ = new_class ($2, 0); - current_methodlist = &$$->methods; - } - '{' ivar_decl_list '}' - methodprotolist - END - | INTERFACE NAME - protocolrefs - { - $$ = new_class ($2, 0); - current_methodlist = &$$->methods; - } - methodprotolist - END - | INTERFACE NAME ':' NAME - protocolrefs - { - class_t *base = find_class ($4); - $$ = new_class ($2, base); - current_methodlist = &$$->methods; - } - '{' ivar_decl_list '}' - methodprotolist - END - | INTERFACE NAME ':' NAME - protocolrefs - { - class_t *base = find_class ($4); - $$ = new_class ($2, base); - current_methodlist = &$$->methods; - } - methodprotolist - END - | INTERFACE NAME '(' NAME ')' - { - class_t *klass = find_class ($4); - $$ = new_category ($2, klass); - current_methodlist = &$$->methods; - } - protocolrefs - methodprotolist - END - | IMPLEMENTATION NAME - { - current_class = new_class ($2, 0); - } - '{' ivar_decl_list '}' - | IMPLEMENTATION NAME - { - current_class = new_class ($2, 0); - } - | IMPLEMENTATION NAME ':' NAME - { - class_t *base = find_class ($4); - current_class = new_class ($2, base); - } - '{' ivar_decl_list '}' - | IMPLEMENTATION NAME ':' NAME - { - class_t *base = find_class ($4); - current_class = new_class ($2, base); - } - | IMPLEMENTATION NAME '(' NAME ')' - ; - -protocoldef /* XXX */ - : PROTOCOL NAME - { - $$ = new_protocol ($2); - current_methodlist = &$$->methods; - } - protocolrefs - methodprotolist END - ; - -protocolrefs /* XXX */ - : /* emtpy */ - | LT identifier_list GT - { - expr_t *e; - for (e = $2->e.block.head; e; e = e->next) { - //puts (e->e.string_val); + current_visibility = vis_private; + $$ = get_class ($1, 0); + if (!$$) { + error (0, "undefined symbol `%s'", $1); + $$ = get_class (0, 1); } } ; -ivar_decl_list /* XXX */ +new_class_name + : NAME + { + $$ = get_class ($1, 1); + if ($$->defined) { + error (0, "redefinition of `%s'", $1); + $$ = get_class (0, 1); + } + current_class = $$; + } + +protocol_name + : NAME + { + $$ = get_protocol ($1, 1); + if ($$->methods) { + error (0, "redefinition of %s", $1); + $$ = get_protocol (0, 1); + } + } + +classdef /* XXX */ + : INTERFACE new_class_name + protocolrefs { class_add_protocol_methods ($2, $3); } + '{' { $2->ivars = new_struct (0); } + ivar_decl_list '}' + methodprotolist { class_add_methods ($2, $9); } + END + | INTERFACE new_class_name + protocolrefs { class_add_protocol_methods ($2, $3); } + methodprotolist { class_add_methods ($2, $5); } + END + | INTERFACE new_class_name ':' class_name + protocolrefs { class_add_protocol_methods ($2, $5); } + '{' + { + $2->ivars = new_struct (0); + copy_struct_fields ($2->ivars, $4->ivars); + } + ivar_decl_list '}' + methodprotolist { class_add_methods ($2, $11); } + END + | INTERFACE new_class_name ':' class_name + protocolrefs { class_add_protocol_methods ($2, $5); } + methodprotolist { class_add_methods ($2, $7); } + END + | INTERFACE new_class_name '(' class_name ')' + protocolrefs { class_add_protocol_methods ($2, $6); } + methodprotolist { class_add_methods ($2, $8); } + END + | IMPLEMENTATION class_name '{' + { + $2->ivars = new_struct (0); + current_class = $2; + } + ivar_decl_list '}' + | IMPLEMENTATION class_name { current_class = $2; } + | IMPLEMENTATION class_name ':' class_name '{' + { + if ($4 != $2->base) + warning (0, "%s is not a super class of %s", + $4->name, $2->name); + $2->ivars = new_struct (0); + copy_struct_fields ($2->ivars, $4->ivars); + current_class = $2; + } + ivar_decl_list '}' + | IMPLEMENTATION class_name ':' class_name + { + if ($4 != $2->base) + warning (0, "%s is not a super class of %s", + $4->name, $2->name); + current_class = $2; + } + | IMPLEMENTATION class_name '(' class_name ')' { current_class = $2; } + ; + +protocoldef + : PROTOCOL protocol_name + protocolrefs { protocol_add_protocol_methods ($2, $3); } + methodprotolist { protocol_add_methods ($2, $5); } + END + ; + +protocolrefs + : /* emtpy */ { $$ = 0; } + | LT identifier_list GT { $$ = $2->e.block.head; } + ; + +ivar_decl_list : ivar_decl_list visibility_spec ivar_decls | ivar_decls ; -visibility_spec /* XXX */ - : PRIVATE - | PROTECTED - | PUBLIC +visibility_spec + : PRIVATE { current_visibility = vis_private; } + | PROTECTED { current_visibility = vis_protected; } + | PUBLIC { current_visibility = vis_public; } ; -ivar_decls /* XXX */ +ivar_decls : /* empty */ | ivar_decls ivar_decl ';' ; -ivar_decl /* XXX */ - : type ivars {} +ivar_decl + : type ivars { current_type = $1 } ; -ivars /* XXX */ +ivars : ivar_declarator | ivars ',' ivar_declarator ; -ivar_declarator /* XXX */ - : NAME {} +ivar_declarator + : NAME + { + new_struct_field (current_class->ivars, current_type, + $1, current_visibility); + } ; methoddef @@ -1055,13 +1053,21 @@ methoddef ; methodprotolist - : /* emtpy */ + : /* emtpy */ { $$ = 0; } | methodprotolist2 ; methodprotolist2 - : methodproto { add_method (current_methodlist, $1); } - | methodprotolist2 methodproto { add_method (current_methodlist, $2); } + : methodproto + { + $$ = new_methodlist (); + add_method ($$, $1); + } + | methodprotolist2 methodproto + { + add_method ($1, $2); + $$ = $1; + } ; methodproto @@ -1089,12 +1095,9 @@ methoddecl ; optparmlist - : /* empty */ - { $$ = 0; } - | ',' ELLIPSIS - { $$ = new_param (0, 0, 0); } - | ',' param_list - { $$ = $2; } + : /* empty */ { $$ = 0; } + | ',' ELLIPSIS { $$ = new_param (0, 0, 0); } + | ',' param_list { $$ = $2; } | ',' param_list ',' ELLIPSIS { $$ = new_param (0, 0, 0); @@ -1103,7 +1106,7 @@ optparmlist ; unaryselector - : selector { $$ = new_param ($1, 0, 0); } + : selector { $$ = new_param ($1, 0, 0); } ; keywordselector @@ -1113,27 +1116,27 @@ keywordselector selector : NAME - | TYPE { $$ = strdup (yytext); } + | TYPE { $$ = strdup (yytext); } | reserved_word ; reserved_word - : LOCAL { $$ = strdup (yytext); } - | RETURN { $$ = strdup (yytext); } - | WHILE { $$ = strdup (yytext); } - | DO { $$ = strdup (yytext); } - | IF { $$ = strdup (yytext); } - | ELSE { $$ = strdup (yytext); } - | FOR { $$ = strdup (yytext); } - | BREAK { $$ = strdup (yytext); } - | CONTINUE { $$ = strdup (yytext); } - | SWITCH { $$ = strdup (yytext); } - | CASE { $$ = strdup (yytext); } - | DEFAULT { $$ = strdup (yytext); } - | NIL { $$ = strdup (yytext); } - | STRUCT { $$ = strdup (yytext); } - | ENUM { $$ = strdup (yytext); } - | TYPEDEF { $$ = strdup (yytext); } + : LOCAL { $$ = strdup (yytext); } + | RETURN { $$ = strdup (yytext); } + | WHILE { $$ = strdup (yytext); } + | DO { $$ = strdup (yytext); } + | IF { $$ = strdup (yytext); } + | ELSE { $$ = strdup (yytext); } + | FOR { $$ = strdup (yytext); } + | BREAK { $$ = strdup (yytext); } + | CONTINUE { $$ = strdup (yytext); } + | SWITCH { $$ = strdup (yytext); } + | CASE { $$ = strdup (yytext); } + | DEFAULT { $$ = strdup (yytext); } + | NIL { $$ = strdup (yytext); } + | STRUCT { $$ = strdup (yytext); } + | ENUM { $$ = strdup (yytext); } + | TYPEDEF { $$ = strdup (yytext); } ; keyworddecl diff --git a/tools/qfcc/source/struct.c b/tools/qfcc/source/struct.c index fbb4c7b50..a162f9243 100644 --- a/tools/qfcc/source/struct.c +++ b/tools/qfcc/source/struct.c @@ -68,13 +68,15 @@ enums_get_key (void *e, void *unused) } struct_field_t * -new_struct_field (type_t *strct, type_t *type, const char *name) +new_struct_field (type_t *strct, type_t *type, const char *name, + visibility_t visibility) { struct_field_t *field; if (!strct) return 0; field = malloc (sizeof (struct_field_t)); + field->visibility = visibility; field->name = name; field->type = type; field->offset = strct->num_parms; @@ -102,10 +104,12 @@ new_struct (const char *name) if (!structs) { structs = Hash_NewTable (16381, structs_get_key, 0, 0); } - strct = (struct_t *) Hash_Find (structs, name); - if (strct) { - error (0, "duplicate struct definition"); - return 0; + if (name) { + strct = (struct_t *) Hash_Find (structs, name); + if (strct) { + error (0, "duplicate struct definition"); + return 0; + } } strct = malloc (sizeof (struct_t)); strct->name = name; @@ -130,6 +134,17 @@ find_struct (const char *name) return 0; } +void +copy_struct_fields (type_t *dst, type_t *src) +{ + struct_field_t *s; + + if (!src) + return; + for (s = src->struct_head; s; s = s->next) + new_struct_field (dst, s->type, s->name, s->visibility); +} + void process_enum (expr_t *enm) { diff --git a/tools/qfcc/source/type.c b/tools/qfcc/source/type.c index 06dc48519..e57e3e269 100644 --- a/tools/qfcc/source/type.c +++ b/tools/qfcc/source/type.c @@ -63,6 +63,7 @@ type_t type_struct = { ev_struct }; // these will be built up further type_t type_id = { ev_pointer }; 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 }; @@ -257,29 +258,32 @@ init_types (void) chain_type (&type_IMP); type = type_SEL.aux_type = new_struct ("SEL"); - new_struct_field (type, &type_string, "sel_id"); - new_struct_field (type, &type_string, "sel_types"); + new_struct_field (type, &type_string, "sel_id", vis_public); + new_struct_field (type, &type_string, "sel_types", vis_public); chain_type (&type_SEL); type_method = new_struct ("obj_method"); - new_struct_field (type_method, &type_SEL, "method_name"); - new_struct_field (type_method, &type_string, "method_types"); - new_struct_field (type_method, &type_IMP, "method_imp"); + 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"); - new_struct_field (type, &type_integer, "method_count"); + 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"); + "method_list", vis_public); chain_type (&type_method_list); type = type_Class.aux_type = new_struct ("Class"); - new_struct_field (type, &type_Class, "super_class"); - new_struct_field (type, &type_Class, "methods"); + new_struct_field (type, &type_Class, "super_class", vis_public); + new_struct_field (type, &type_Class, "methods", vis_public); chain_type (&type_Class); + type = type_Protocol.aux_type = new_struct ("Protocol"); + chain_type (&type_Protocol); + type = type_id.aux_type = new_struct ("id"); - new_struct_field (type, &type_Class, "class_pointer"); + new_struct_field (type, &type_Class, "class_pointer", vis_public); chain_type (&type_id); }