diff --git a/tools/qfcc/include/class.h b/tools/qfcc/include/class.h index 0e76bd7f5..2094490b7 100644 --- a/tools/qfcc/include/class.h +++ b/tools/qfcc/include/class.h @@ -96,7 +96,7 @@ struct symbol_s; class_t *extract_class (class_type_t *class_type); const char *get_class_name (class_type_t *class_type, int pretty); -struct def_s *class_def (class_type_t *class_type, int external); +struct symbol_s *class_symbol (class_type_t *class_type, int external); void class_init (void); class_t *get_class (struct symbol_s *sym, int create); void class_add_methods (class_t *class, struct methodlist_s *methods); diff --git a/tools/qfcc/include/def.h b/tools/qfcc/include/def.h index 005d03601..0d482b963 100644 --- a/tools/qfcc/include/def.h +++ b/tools/qfcc/include/def.h @@ -36,21 +36,17 @@ #include "QF/pr_debug.h" typedef struct def_s { + struct def_s *next; ///< general purpose linking + struct type_s *type; const char *name; - int ofs; + struct defspace_s *space; + int offset; - struct reloc_s *refs; ///< for relocations + struct reloc_s *relocs; ///< for relocations - unsigned initialized:1; ///< for uninit var detection - unsigned suppress:1; ///< for uninit var detection suppression - unsigned set:1; ///< uninit var auto-inited - unsigned constant:1; ///< 1 when a declaration included "= immediate" - unsigned freed:1; ///< already freed from the scope - unsigned removed:1; ///< already removed from the symbol table - unsigned used:1; ///< unused local detection - unsigned absolute:1; ///< don't relocate (for temps for shorts) - unsigned managed:1; ///< managed temp + unsigned initialized:1; + unsigned constant:1; ///< stores constant value unsigned global:1; ///< globally declared def unsigned external:1; ///< externally declared def unsigned local:1; ///< function local def @@ -60,39 +56,12 @@ typedef struct def_s { string_t file; ///< source file int line; ///< source line - int users; ///< ref counted temps - struct expr_s *expr; ///< temp expr using this def - - struct def_s *def_next; ///< next def in scope - struct def_s *next; ///< general purpose linking - struct scope_s *scope; ///< scope the var was defined in - struct defspace_s *space; - struct def_s *parent; ///< vector/quaternion member - struct def_s *alias; ///< def for which this is an alias - int obj_def; ///< index to def in qfo defs void *return_addr; ///< who allocated this } def_t; -typedef enum { - sc_global, - sc_params, - sc_local, -} scope_type; - -typedef struct scope_s { - struct scope_s *next; - scope_type type; - struct defspace_s *space; - def_t *head; - def_t **tail; - int num_defs; - struct scope_s *parent; -} scope_t; - -typedef enum { - st_none, +typedef enum storage_class_e { st_global, st_system, st_extern, @@ -100,24 +69,9 @@ typedef enum { st_local } storage_class_t; -extern def_t def_void; -extern def_t def_invalid; -extern def_t def_function; - -scope_t *new_scope (scope_type type, struct defspace_s *space, scope_t *parent); - -def_t *field_def (const char *name); -def_t *get_def (struct type_s *type, const char *name, scope_t *scope, - storage_class_t storage); -def_t *new_def (struct type_s *type, const char *name, scope_t *scope); -void set_storage_bits (def_t *def, storage_class_t storage); -def_t *get_tempdef (struct type_s *type, scope_t *scope); -void free_tempdefs (void); -void reset_tempdefs (void); -void flush_scope (scope_t *scope, int force_used); -void def_initialized (def_t *d); - -void clear_defs (void); +def_t *new_def (const char *name, struct type_s *type, + struct defspace_s *scope, storage_class_t storage); +void free_def (def_t *def); void def_to_ddef (def_t *def, ddef_t *ddef, int aux); diff --git a/tools/qfcc/include/defspace.h b/tools/qfcc/include/defspace.h index 12e0fada5..313c57027 100644 --- a/tools/qfcc/include/defspace.h +++ b/tools/qfcc/include/defspace.h @@ -38,6 +38,8 @@ typedef struct defspace_s { struct defspace_s *next; struct locref_s *free_locs; + struct def_s *defs; + struct def_s **def_tail; pr_type_t *data; int size; int max_size; @@ -46,7 +48,7 @@ typedef struct defspace_s { defspace_t *new_defspace (void); int defspace_new_loc (defspace_t *space, int size); -void defsapce_free_loc (defspace_t *space, int ofs, int size); +void defspace_free_loc (defspace_t *space, int ofs, int size); int defspace_add_data (defspace_t *space, pr_type_t *data, int size); #endif//__defspace_h diff --git a/tools/qfcc/include/emit.h b/tools/qfcc/include/emit.h index a033f35c8..2bc6ffdc6 100644 --- a/tools/qfcc/include/emit.h +++ b/tools/qfcc/include/emit.h @@ -37,26 +37,26 @@ struct def_s *emit_statement (struct expr_s *e, opcode_t *op, struct def_s *var_ struct def_s *emit_sub_expr (struct expr_s*e, struct def_s *dest); void emit_expr (struct expr_s *e); -#define EMIT_STRING(dest,str) \ +#define EMIT_STRING(s,dest,str) \ do { \ (dest) = ReuseString (str); \ - reloc_def_string (POINTER_OFS (&(dest))); \ + reloc_def_string (POINTER_OFS (s, &(dest)));\ } while (0) -#define EMIT_DEF(dest,def) \ +#define EMIT_DEF(s,dest,def) \ do { \ def_t *d = (def); \ - (dest) = d ? d->ofs : 0; \ + (dest) = d ? d->offset : 0; \ if (d) \ - reloc_def_def (d, POINTER_OFS (&(dest))); \ + reloc_def_def (d, POINTER_OFS (s, &(dest)));\ } while (0) -#define EMIT_DEF_OFS(dest,def) \ +#define EMIT_DEF_OFS(s,dest,def) \ do { \ def_t *d = (def); \ - (dest) = d ? d->ofs : 0; \ + (dest) = d ? d->offset : 0; \ if (d) \ - reloc_def_def_ofs (d, POINTER_OFS (&(dest))); \ + reloc_def_def_ofs (d, POINTER_OFS (s, &(dest)));\ } while (0) #endif//__emit_h diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index f5597c6d7..559b4f378 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -167,7 +167,7 @@ typedef struct ex_value_s { } v; } ex_value_t; -#define POINTER_VAL(p) (((p).def ? (p).def->ofs : 0) + (p).val) +#define POINTER_VAL(p) (((p).def ? (p).def->offset : 0) + (p).val) typedef struct expr_s { struct expr_s *next; ///< the next expression in a block expression diff --git a/tools/qfcc/include/function.h b/tools/qfcc/include/function.h index e1d74178a..bb1ffbb7d 100644 --- a/tools/qfcc/include/function.h +++ b/tools/qfcc/include/function.h @@ -89,9 +89,6 @@ param_t *copy_params (param_t *params); struct type_s *parse_params (struct type_s *type, param_t *params); struct symbol_s *function_symbol (struct symbol_s *sym, int overload, int create); -struct def_s *get_function_def (const char *name, struct type_s *type, - struct scope_s *scope, storage_class_t storage, - int overload, int create); struct expr_s *find_function (struct expr_s *fexpr, struct expr_s *params); function_t *new_function (const char *name, const char *nice_name); void add_function (function_t *f); diff --git a/tools/qfcc/include/method.h b/tools/qfcc/include/method.h index f7c8c97c1..1c6a8a0d4 100644 --- a/tools/qfcc/include/method.h +++ b/tools/qfcc/include/method.h @@ -55,6 +55,8 @@ typedef struct selector_s { typedef struct methodlist_s { method_t *head; method_t **tail; + int count; ///< used only for emitting + int instance; ///< used only for emitting } methodlist_t; typedef struct keywordarg_s { diff --git a/tools/qfcc/include/qfcc.h b/tools/qfcc/include/qfcc.h index b026e454b..1a7dc79dc 100644 --- a/tools/qfcc/include/qfcc.h +++ b/tools/qfcc/include/qfcc.h @@ -98,17 +98,20 @@ extern char destfile[]; extern struct symtab_s *current_symtab; -#define G_GETSTR(s) (pr.strings->strings + (s)) -#define G_var(t, o) (pr.near_data->data[o].t##_var) -#define G_FLOAT(o) G_var (float, o) -#define G_INT(o) G_var (integer, o) -#define G_VECTOR(o) G_var (vector, o) -#define G_STRING(o) G_GETSTR (G_var (string, o)) -#define G_FUNCTION(o) G_var (func, o) -#define G_POINTER(t,o) ((t *)(pr.near_data->data + o)) -#define G_STRUCT(t,o) (*G_POINTER (t, o)) +#define GETSTR(s) (pr.strings->strings + (s)) +#define D_var(t, d) ((d)->space->data[(d)->offset].t##_var) +#define D_FLOAT(d) D_var (float, d) +#define D_INT(d) D_var (integer, d) +#define D_VECTOR(d) D_var (vector, d) +#define D_STRING(d) GETSTR (D_var (string, d)) +#define D_FUNCTION(d) D_var (func, d) +#define D_POINTER(t,d) ((t *)((d)->space->data + (d)->offset)) +#define D_STRUCT(t,d) (*D_POINTER (t, d)) -#define POINTER_OFS(p) ((pr_type_t *) (p) - pr.near_data->data) +#define G_POINTER(s,t,o) ((t *)((s)->data + o)) +#define G_STRUCT(s,t,o) (*G_POINTER (s, t, o)) + +#define POINTER_OFS(s,p) ((pr_type_t *) (p) - (s)->data) const char *strip_path (const char *filename); diff --git a/tools/qfcc/include/reloc.h b/tools/qfcc/include/reloc.h index 46fae40eb..d2fc9636b 100644 --- a/tools/qfcc/include/reloc.h +++ b/tools/qfcc/include/reloc.h @@ -44,28 +44,28 @@ */ typedef enum { rel_none, ///< no relocation - rel_op_a_def, ///< code[ref.ofs].a = def ofs - rel_op_b_def, ///< code[ref.ofs].b = def ofs - rel_op_c_def, ///< code[ref.ofs].c = def ofs - rel_op_a_op, ///< * code[ref.ofs].a = code ofs - ref.ofs - rel_op_b_op, ///< * code[ref.ofs].b = code ofs - ref.ofs - rel_op_c_op, ///< * code[ref.ofs].c = code ofs - ref.ofs - rel_def_op, ///< + data[ref.ofs] = code ofs - rel_def_def, ///< data[ref.ofs] = def ofs - rel_def_func, ///< +(sometimes) data[ref.ofs] = ofs - rel_def_string, ///< + ! data[ref.ofs] = string index - rel_def_field, ///< ! data[ref.ofs] = field def ofs - rel_op_a_def_ofs, ///< code[ref.ofs].a += def ofs - rel_op_b_def_ofs, ///< code[ref.ofs].b += def ofs - rel_op_c_def_ofs, ///< code[ref.ofs].c += def ofs - rel_def_def_ofs, ///< data[ref.ofs] += def ofs - rel_def_field_ofs, ///< data[ref.ofs] += field def ofs + rel_op_a_def, ///< code[ref.offset].a = def offset + rel_op_b_def, ///< code[ref.offset].b = def offset + rel_op_c_def, ///< code[ref.offset].c = def offset + rel_op_a_op, ///< * code[ref.offset].a = code offset - ref.offset + rel_op_b_op, ///< * code[ref.offset].b = code offset - ref.offset + rel_op_c_op, ///< * code[ref.offset].c = code offset - ref.offset + rel_def_op, ///< + data[ref.offset] = code offset + rel_def_def, ///< data[ref.offset] = def offset + rel_def_func, ///< +(sometimes) data[ref.offset] = offset + rel_def_string, ///< + ! data[ref.offset] = string index + rel_def_field, ///< ! data[ref.offset] = field def offset + rel_op_a_def_ofs, ///< code[ref.offset].a += def offset + rel_op_b_def_ofs, ///< code[ref.offset].b += def offset + rel_op_c_def_ofs, ///< code[ref.offset].c += def offset + rel_def_def_ofs, ///< data[ref.offset] += def offset + rel_def_field_ofs, ///< data[ref.offset] += field def offset } reloc_type; typedef struct reloc_s { struct reloc_s *next; struct ex_label_s *label; - int ofs; + int offset; reloc_type type; int line; string_t file; @@ -75,17 +75,17 @@ struct statement_s; struct def_s; struct function_s; -reloc_t *new_reloc (int ofs, reloc_type type); -void relocate_refs (reloc_t *refs, int ofs); -void reloc_op_def (struct def_s *def, int ofs, int field); -void reloc_op_def_ofs (struct def_s *def, int ofs, int field); -void reloc_def_def (struct def_s *def, int ofs); -void reloc_def_def_ofs (struct def_s *def, int ofs); -void reloc_def_func (struct function_s *func, int ofs); -void reloc_def_string (int ofs); -void reloc_def_field (struct def_s *def, int ofs); -void reloc_def_field_ofs (struct def_s *def, int ofs); -void reloc_def_op (struct ex_label_s *label, int ofs); +reloc_t *new_reloc (int offset, reloc_type type); +void relocate_refs (reloc_t *refs, int offset); +void reloc_op_def (struct def_s *def, int offset, int field); +void reloc_op_def_ofs (struct def_s *def, int offset, int field); +void reloc_def_def (struct def_s *def, int offset); +void reloc_def_def_ofs (struct def_s *def, int offset); +void reloc_def_func (struct function_s *func, int offset); +void reloc_def_string (int offset); +void reloc_def_field (struct def_s *def, int offset); +void reloc_def_field_ofs (struct def_s *def, int offset); +void reloc_def_op (struct ex_label_s *label, int offset); ///@} diff --git a/tools/qfcc/include/struct.h b/tools/qfcc/include/struct.h index 4f9b0e131..3ac6ebd04 100644 --- a/tools/qfcc/include/struct.h +++ b/tools/qfcc/include/struct.h @@ -32,6 +32,8 @@ #ifndef __struct_h #define __struct_h +struct def_s; +enum storage_class_e; struct symbol_s; struct symtab_s; struct type_s; @@ -39,6 +41,7 @@ struct type_s; typedef struct { const char *name; struct type_s *type; + void (*emit) (struct def_s *def, void *data, int index); } struct_def_t; struct symbol_s *find_struct (int su, struct symbol_s *tag, @@ -52,5 +55,8 @@ void add_enum (struct symbol_s *enm, struct symbol_s *name, struct symbol_s *make_structure (const char *name, int su, struct_def_t *defs, struct type_s *type); +struct def_s * emit_structure (const char *name, int su, struct_def_t *defs, + struct type_s *type, void *data, + enum storage_class_e storage); #endif//__struct_h diff --git a/tools/qfcc/include/symtab.h b/tools/qfcc/include/symtab.h index 19d1ebc93..15249ba34 100644 --- a/tools/qfcc/include/symtab.h +++ b/tools/qfcc/include/symtab.h @@ -34,6 +34,9 @@ #include "expr.h" +struct defspace_s; +enum storage_class_e; + /** \defgroup qfcc_symtab Symbol Table Management \ingroup qfcc */ @@ -58,14 +61,15 @@ typedef struct symbol_s { struct symtab_s *table; ///< symbol table that owns this symbol vis_e visibility; ///< symbol visiblity. defaults to public const char *name; ///< symbol name - sy_type_e sy_type; ///< symbol type + sy_type_e sy_type; ///< symbol type (st_type) struct type_s *type; ///< type of object to which symbol refers struct param_s *params; ///< the parameters if a function union { - int offset; - struct ex_value_s value; - struct expr_s *expr; - struct function_s *func; + int offset; ///< st_var (in a struct/union) + struct def_s *def; ///< st_var + struct ex_value_s value; ///< st_const + struct expr_s *expr; ///< st_expr + struct function_s *func; ///< st_func } s; } symbol_t; @@ -206,6 +210,9 @@ symbol_t *copy_symbol (symbol_t *symbol); */ symtab_t *symtab_flat_copy (symtab_t *symtab, symtab_t *parent); +symbol_t *make_symbol (const char *name, struct type_s *type, + struct defspace_s *space, enum storage_class_e storage); + //@} #endif//__symtab_h diff --git a/tools/qfcc/source/Makefile.am b/tools/qfcc/source/Makefile.am index cd64a52d8..387ef6a5f 100644 --- a/tools/qfcc/source/Makefile.am +++ b/tools/qfcc/source/Makefile.am @@ -55,7 +55,7 @@ common_src=\ class.c codespace.c constfold.c cpp.c debug.c def.c defspace.c dot_expr.c \ dot_flow.c emit.c \ expr.c function.c grab.c idstuff.c immediate.c linker.c method.c \ - obj_file.c opcodes.c options.c qfcc.c reloc.c statements.c strpool.c \ + obj_stub.c opcodes.c options.c qfcc.c reloc.c statements.c strpool.c \ struct.c switch.c symtab.c type.c qfcc_SOURCES= qc-lex.l qc-parse.y $(common_src) @@ -67,7 +67,7 @@ qfpc_LDADD= $(QFCC_LIBS) qfpc_DEPENDENCIES= $(QFCC_DEPS) qfprogs_SOURCES= \ - disassemble.c globals.c lines.c modules.c obj_file.c stub.c qfprogs.c strings.c + disassemble.c globals.c lines.c modules.c obj_stub.c stub.c qfprogs.c strings.c qfprogs_LDADD= $(QFCC_LIBS) qfprogs_DEPENDENCIES= $(QFCC_DEPS) diff --git a/tools/qfcc/source/class.c b/tools/qfcc/source/class.c index 392d841e8..708842de7 100644 --- a/tools/qfcc/source/class.c +++ b/tools/qfcc/source/class.c @@ -117,12 +117,11 @@ class_init (void) class_Class.methods = new_methodlist (); } -def_t * -class_def (class_type_t *class_type, int external) +symbol_t * +class_symbol (class_type_t *class_type, int external) { const char *name = 0; type_t *type = 0; - storage_class_t storage = external ? st_extern : st_global; switch (class_type->type) { case ct_category: @@ -138,7 +137,8 @@ class_def (class_type_t *class_type, int external) case ct_protocol: return 0; // probably in error recovery } - return get_def (type, name, pr.scope, storage); + return make_symbol (name, type, pr.far_data, + external ? st_extern : st_global); } class_t * @@ -226,58 +226,118 @@ begin_category (category_t *category) { pr_category_t *pr_category; class_t *class = category->class; + symbol_t *sym; + def_t *def; + defspace_t *space; current_class = &category->class_type; - category->def = class_def (current_class, 0); - category->def->initialized = category->def->constant = 1; - category->def->nosave = 1; - pr_category = &G_STRUCT (pr_category_t, category->def->ofs); - EMIT_STRING (pr_category->category_name, category->name); - EMIT_STRING (pr_category->class_name, class->name); - EMIT_DEF (pr_category->protocols, + sym = class_symbol (current_class, 0); + category->def = def = sym->s.def; + def->initialized = def->constant = def->nosave = 1; + space = def->space; + + pr_category = &D_STRUCT (pr_category_t, def); + EMIT_STRING (space, pr_category->category_name, category->name); + EMIT_STRING (space, pr_category->class_name, class->name); + EMIT_DEF (space, pr_category->protocols, emit_protocol_list (category->protocols, va ("%s_%s", class->name, category->name))); } +static def_t * +emit_ivars (symtab_t *ivars, const char *name) +{ + static struct_def_t ivar_list_struct[] = { + {"ivar_count", &type_integer}, + {"ivar_list", 0}, // type filled in at runtime + {0, 0} + }; + dstring_t *encoding = dstring_newstr (); + symbol_t *sym; + symbol_t *s; + def_t *def; + defspace_t *space; + int count; + int i; + type_t new; + type_t *type; + pr_ivar_list_t *pr_ivar_list; + + for (s = ivars->symbols; s; s = s->next) + if (s->sy_type == sy_var) + count++; + ivar_list_struct[1].type = array_type (&type_ivar, count); + make_structure (0, 's', ivar_list_struct, &new); + type = find_type (&new); + + sym = make_symbol (va ("_OBJ_INSTANCE_VARIABLES_%s", name), type, + pr.far_data, st_global); + def = sym->s.def; + space = def->space; + if (def->initialized) + goto done; + def->initialized = def->constant = def->nosave = 1; + + pr_ivar_list = &D_STRUCT (pr_ivar_list_t, def); + pr_ivar_list->ivar_count = count; + for (i = 0, s = ivars->symbols; s; s = s->next) { + if (s->sy_type != sy_var) + continue; + encode_type (encoding, s->type); + EMIT_STRING (space, pr_ivar_list->ivar_list[i].ivar_name, s->name); + EMIT_STRING (space, pr_ivar_list->ivar_list[i].ivar_type, + encoding->str); + pr_ivar_list->ivar_list[i].ivar_offset = s->s.offset; + dstring_clearstr (encoding); + i++; + } +done: + dstring_delete (encoding); + return def; +} + static void begin_class (class_t *class) { def_t *meta_def; pr_class_t *meta; - pr_class_t *cls; + pr_class_t *pr_class; + symbol_t *sym; + def_t *def; + defspace_t *space; - current_class = &class->class_type; - class->def = class_def (current_class, 0); - meta_def = get_def (type_Class.t.fldptr.type, - va ("_OBJ_METACLASS_%s", class->name), - pr.scope, st_static); - meta_def->initialized = meta_def->constant = 1; - meta_def->nosave = 1; - meta = &G_STRUCT (pr_class_t, meta_def->ofs); - EMIT_STRING (meta->class_pointer, class->name); + sym = make_symbol (va ("_OBJ_METACLASS_%s", class->name), + type_Class.t.fldptr.type, pr.far_data, st_static); + meta_def = sym->s.def; + meta_def->initialized = meta_def->constant = meta_def->nosave = 1; + space = meta_def->space; + meta = &D_STRUCT (pr_class_t, meta_def); + EMIT_STRING (space, meta->class_pointer, class->name); if (class->super_class) - EMIT_STRING (meta->super_class, class->super_class->name); - EMIT_STRING (meta->name, class->name); + EMIT_STRING (space, meta->super_class, class->super_class->name); + EMIT_STRING (space, meta->name, class->name); meta->info = _PR_CLS_META; meta->instance_size = type_size (type_Class.t.fldptr.type); -#if 0 //FIXME - EMIT_DEF (meta->ivars, - emit_struct (type_Class.t.fldptr.type->t.class->ivars, + EMIT_DEF (space, meta->ivars, + emit_ivars (type_Class.t.fldptr.type->t.class->ivars, "Class")); -#endif - class->def->initialized = class->def->constant = 1; - class->def->nosave = 1; - cls = &G_STRUCT (pr_class_t, class->def->ofs); - EMIT_DEF (cls->class_pointer, meta_def); + current_class = &class->class_type; + sym = class_symbol (current_class, 0); + class->def = def = sym->s.def; + def->initialized = def->constant = def->nosave = 1; + space = def->space; + + pr_class = &D_STRUCT (pr_class_t, def); + EMIT_DEF (space, pr_class->class_pointer, meta_def); if (class->super_class) { class_type_t class_type = {ct_class, {0}}; class_type.c.class = class->super_class; - EMIT_STRING (cls->super_class, class->super_class->name); - class_def (&class_type, 1); + EMIT_STRING (space, pr_class->super_class, class->super_class->name); + class_symbol (&class_type, 1); } - EMIT_STRING (cls->name, class->name); - cls->info = _PR_CLS_CLASS; - EMIT_DEF (cls->protocols, + EMIT_STRING (space, pr_class->name, class->name); + pr_class->info = _PR_CLS_CLASS; + EMIT_DEF (space, pr_class->protocols, emit_protocol_list (class->protocols, class->name)); } @@ -302,17 +362,16 @@ emit_class_ref (const char *class_name) def_t *def; def_t *ref; - def = get_def (&type_pointer, va (".obj_class_ref_%s", class_name), - pr.scope, st_static); + def = make_symbol (va (".obj_class_ref_%s", class_name), &type_pointer, + pr.far_data, st_static)->s.def; if (def->initialized) return; - def->initialized = def->constant = 1; - def->nosave = 1; - ref = get_def (&type_integer, va (".obj_class_name_%s", class_name), - pr.scope, st_extern); + def->initialized = def->constant = def->nosave = 1; + ref = make_symbol (va (".obj_class_name_%s", class_name), &type_pointer, + pr.far_data, st_extern)->s.def; if (!ref->external) - G_INT (def->ofs) = ref->ofs; - reloc_def_def (ref, def->ofs); + D_INT (def) = ref->offset; + reloc_def_def (ref, def->offset); } static void @@ -320,13 +379,13 @@ emit_class_name (const char *class_name) { def_t *def; - def = get_def (&type_integer, va (".obj_class_name_%s", class_name), - pr.scope, st_global); + def = make_symbol (va (".obj_class_name_%s", class_name), &type_pointer, + pr.far_data, st_global)->s.def; if (def->initialized) return; def->initialized = def->constant = 1; def->nosave = 1; - G_INT (def->ofs) = 0; + D_INT (def) = 0; } void @@ -335,19 +394,19 @@ emit_category_ref (const char *class_name, const char *category_name) def_t *def; def_t *ref; - def = get_def (&type_pointer, - va (".obj_category_ref_%s_%s", class_name, category_name), - pr.scope, st_static); + def = make_symbol (va (".obj_category_ref_%s_%s", + class_name, category_name), + &type_pointer, pr.far_data, st_static)->s.def; if (def->initialized) return; def->initialized = def->constant = 1; def->nosave = 1; - ref = get_def (&type_integer, - va (".obj_category_name_%s_%s", class_name, category_name), - pr.scope, st_extern); + ref = make_symbol (va (".obj_category_name_%s_%s", + class_name, category_name), + &type_pointer, pr.far_data, st_extern)->s.def; if (!ref->external) - G_INT (def->ofs) = ref->ofs; - reloc_def_def (ref, def->ofs); + D_INT (def) = ref->offset; + reloc_def_def (ref, def->offset); } static void @@ -355,14 +414,14 @@ emit_category_name (const char *class_name, const char *category_name) { def_t *def; - def = get_def (&type_integer, - va (".obj_category_name_%s_%s", class_name, category_name), - pr.scope, st_global); + def = make_symbol (va (".obj_category_name_%s_%s", + class_name, category_name), + &type_pointer, pr.far_data, st_global)->s.def; if (def->initialized) return; def->initialized = def->constant = 1; def->nosave = 1; - G_INT (def->ofs) = 0; + D_INT (def) = 0; } static void @@ -371,14 +430,16 @@ finish_category (category_t *category) pr_category_t *pr_category; class_t *class = category->class; char *name; + defspace_t *space; if (!category->def) // probably in error recovery return; name = nva ("%s_%s", class->name, category->name); - pr_category = &G_STRUCT (pr_category_t, category->def->ofs); - EMIT_DEF (pr_category->instance_methods, + pr_category = &D_STRUCT (pr_category_t, category->def); + space = category->def->space; + EMIT_DEF (space, pr_category->instance_methods, emit_methods (category->methods, name, 1)); - EMIT_DEF (pr_category->class_methods, + EMIT_DEF (space, pr_category->class_methods, emit_methods (category->methods, name, 0)); free (name); emit_class_ref (class->name); @@ -390,22 +451,22 @@ finish_class (class_t *class) { pr_class_t *meta; pr_class_t *cls; + defspace_t *space; if (!class->def) // probably in error recovery return; - cls = &G_STRUCT (pr_class_t, class->def->ofs); + space = class->def->space; + cls = &D_STRUCT (pr_class_t, class->def); - meta = &G_STRUCT (pr_class_t, cls->class_pointer); + meta = &G_STRUCT (space, pr_class_t, cls->class_pointer); - EMIT_DEF (meta->methods, emit_methods (class->methods, - class->name, 0)); + EMIT_DEF (space, meta->methods, emit_methods (class->methods, + class->name, 0)); cls->instance_size = class->ivars ? class->ivars->size : 0; -#if 0 // FIXME - EMIT_DEF (cls->ivars, emit_struct (class->ivars, class->name)); -#endif - EMIT_DEF (cls->methods, emit_methods (class->methods, - class->name, 1)); + EMIT_DEF (space, cls->ivars, emit_ivars (class->ivars, class->name)); + EMIT_DEF (space, cls->methods, emit_methods (class->methods, + class->name, 1)); if (class->super_class) emit_class_ref (class->super_class->name); emit_class_name (class->name); @@ -718,18 +779,18 @@ class_pointer_def (class_t *class) class_type.c.class = class; - def = get_def (pointer_type (class->type), - va ("_OBJ_CLASS_POINTER_%s", class->name), - pr.scope, st_static); + def = make_symbol (va ("_OBJ_CLASS_POINTER_%s", class->name), + pointer_type (class->type), + pr.far_data, st_static)->s.def; if (def->initialized) return def; def->initialized = def->constant = 1; def->nosave = 1; if (!class->def) - class->def = class_def (&class_type, 1); + class->def = class_symbol (&class_type, 1)->s.def; if (!class->def->external) - G_INT (def->ofs) = class->def->ofs; - reloc_def_def (class->def, def->ofs); + D_INT (def) = class->def->offset; + reloc_def_def (class->def, def->offset); return def; } @@ -752,6 +813,7 @@ class_finish_module (void) type_t *symtab_type; //symbol_t *symtab_sym; def_t *symtab_def; + defspace_t *space; pr_symtab_t *symtab; pointer_t *def_ptr; symbol_t *module_sym; @@ -779,13 +841,15 @@ class_finish_module (void) symtab_struct[4].type = array_type (&type_pointer, num_classes + num_categories); symtab_type = make_structure (0, 's', symtab_struct, 0)->type; - symtab_def = get_def (symtab_type, "_OBJ_SYMTAB", pr.scope, st_static); + symtab_def = make_symbol ("_OBJ_SYMTAB", symtab_type, + pr.far_data, st_static)->s.def; symtab_def->initialized = symtab_def->constant = 1; symtab_def->nosave = 1; - symtab = &G_STRUCT (pr_symtab_t, symtab_def->ofs); + space = symtab_def->space; + symtab = &D_STRUCT (pr_symtab_t, symtab_def); if (selector_table_def) { symtab->sel_ref_cnt = selector_table_def->type->t.array.size; - EMIT_DEF (symtab->refs, selector_table_def); + EMIT_DEF (space, symtab->refs, selector_table_def); } symtab->cls_def_cnt = num_classes; symtab->cat_def_cnt = num_categories; @@ -793,16 +857,16 @@ class_finish_module (void) if (classes) { for (cl = classes; *cl; cl++) { if ((*cl)->def && !(*cl)->def->external) { - reloc_def_def ((*cl)->def, POINTER_OFS (def_ptr)); - *def_ptr++ = (*cl)->def->ofs; + reloc_def_def ((*cl)->def, POINTER_OFS (space, def_ptr)); + *def_ptr++ = (*cl)->def->offset; } } } if (categories) { for (ca = categories; *ca; ca++) { if ((*ca)->def && !(*ca)->def->external) { - reloc_def_def ((*ca)->def, POINTER_OFS (def_ptr)); - *def_ptr++ = (*ca)->def->ofs; + reloc_def_def ((*ca)->def, POINTER_OFS (space, def_ptr)); + *def_ptr++ = (*ca)->def->offset; } } } @@ -873,7 +937,8 @@ protocol_add_protocols (protocol_t *protocol, protocollist_t *protocols) def_t * protocol_def (protocol_t *protocol) { - return get_def (&type_Protocol, protocol->name, pr.scope, st_static); + return make_symbol (protocol->name, &type_Protocol, + pr.far_data, st_static)->s.def; } protocollist_t * @@ -907,26 +972,24 @@ emit_protocol (protocol_t *protocol) { def_t *proto_def; pr_protocol_t *proto; + defspace_t *space; - proto_def = get_def (&type_Protocol, - va ("_OBJ_PROTOCOL_%s", protocol->name), - pr.scope, st_none); - if (proto_def) + proto_def = make_symbol (va ("_OBJ_PROTOCOL_%s", protocol->name), + &type_Protocol, pr.far_data, st_static)->s.def; + if (proto_def->initialized) return proto_def; - proto_def = get_def (&type_Protocol, - va ("_OBJ_PROTOCOL_%s", protocol->name), - pr.scope, st_static); proto_def->initialized = proto_def->constant = 1; proto_def->nosave = 1; - proto = &G_STRUCT (pr_protocol_t, proto_def->ofs); + space = proto_def->space; + proto = &D_STRUCT (pr_protocol_t, proto_def); proto->class_pointer = 0; - EMIT_STRING (proto->protocol_name, protocol->name); - EMIT_DEF (proto->protocol_list, + EMIT_STRING (space, proto->protocol_name, protocol->name); + EMIT_DEF (space, proto->protocol_list, emit_protocol_list (protocol->protocols, va ("PROTOCOL_%s", protocol->name))); - EMIT_DEF (proto->instance_methods, + EMIT_DEF (space, proto->instance_methods, emit_method_descriptions (protocol->methods, protocol->name, 1)); - EMIT_DEF (proto->class_methods, + EMIT_DEF (space, proto->class_methods, emit_method_descriptions (protocol->methods, protocol->name, 0)); emit_class_ref ("Protocol"); return proto_def; @@ -943,7 +1006,7 @@ emit_protocol_list (protocollist_t *protocols, const char *name) }; type_t *proto_list_type; def_t *proto_list_def; - //symbol_t *proto_list_sym; + defspace_t *space; pr_protocol_list_t *proto_list; int i; @@ -951,16 +1014,18 @@ emit_protocol_list (protocollist_t *protocols, const char *name) return 0; proto_list_struct[2].type = array_type (&type_pointer, protocols->count); proto_list_type = make_structure (0, 's', proto_list_struct, 0)->type; - proto_list_def = get_def (proto_list_type, - va ("_OBJ_PROTOCOLS_%s", name), - pr.scope, st_static); + proto_list_def = make_symbol (va ("_OBJ_PROTOCOLS_%s", name), + proto_list_type, + pr.far_data, st_static)->s.def; proto_list_def->initialized = proto_list_def->constant = 1; proto_list_def->nosave = 1; - proto_list = &G_STRUCT (pr_protocol_list_t, proto_list_def->ofs); + space = proto_list_def->space; + proto_list = &D_STRUCT (pr_protocol_list_t, proto_list_def); proto_list->next = 0; proto_list->count = protocols->count; for (i = 0; i < protocols->count; i++) - EMIT_DEF (proto_list->list[i], emit_protocol (protocols->list[i])); + EMIT_DEF (space, proto_list->list[i], + emit_protocol (protocols->list[i])); return proto_list_def; } diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c index e6fc8af78..095d1d74b 100644 --- a/tools/qfcc/source/def.c +++ b/tools/qfcc/source/def.c @@ -58,75 +58,12 @@ static __attribute__ ((used)) const char rcsid[] = #include "struct.h" #include "type.h" -//FIXME -//def_t def_void = { type_void, "def void" }; -//def_t def_invalid = { type_invalid, "def invalid" }; -//def_t def_function = { type_function, "def function" }; - -static def_t *free_temps[4]; // indexted by type size -static int tempdef_counter; -static def_t temp_scope; static def_t *free_defs; -static scope_t *free_scopes; -static hashtab_t *defs_by_name; -static hashtab_t *field_defs; - -static const char * -defs_get_key (void *_def, void *unused) -{ - def_t *def = (def_t *) _def; - return def->name; -} - -static def_t * -check_for_name (type_t *type, const char *name, scope_t *scope, - storage_class_t storage) -{ - def_t *def; - - if (!defs_by_name) { - defs_by_name = Hash_NewTable (16381, defs_get_key, 0, 0); - field_defs = Hash_NewTable (16381, defs_get_key, 0, 0); - } - if (!name) - return 0; - // see if the name is already in use - def = (def_t *) Hash_Find (defs_by_name, name); - if (def) { - if (storage != st_none && scope == def->scope) - if (type && def->type != type) { - expr_t *e = new_expr (); - e->line = def->line; - e->file = def->file; - error (0, "Type mismatch on redeclaration of %s", name); - error (e, "previous declaration"); - } - if (storage == st_none || def->scope == scope) - return def; - } - return 0; -} - -scope_t * -new_scope (scope_type type, defspace_t *space, scope_t *parent) -{ - scope_t *scope; - - ALLOC (1024, scope_t, scopes, scope); - scope->type = type; - scope->space = space; - scope->parent = parent; - scope->tail = &scope->head; - return scope; -} - -void +static void set_storage_bits (def_t *def, storage_class_t storage) { switch (storage) { - case st_none: - break; case st_system: def->system = 1; // fall through @@ -154,300 +91,50 @@ set_storage_bits (def_t *def, storage_class_t storage) def->initialized = 0; } -static const char *vector_component_names[] = {"%s_x", "%s_y", "%s_z"}; - -static void -vector_component (int is_field, def_t *vec, int comp, scope_t *scope, - storage_class_t storage) -{ - def_t *d; - const char *name; - - name = save_string (va (vector_component_names[comp], vec->name)); - d = get_def (is_field ? &type_floatfield : &type_float, name, scope, - st_none); - if (d && d->scope == scope) { - if (vec->external) { - error (0, "internal error"); - abort (); - } - } else { - d = new_def (is_field ? &type_floatfield : &type_float, name, scope); - } - d->used = 1; - d->parent = vec; - d->ofs = vec->ofs + comp; - set_storage_bits (d, storage); - if (is_field && (storage == st_global || storage == st_static)) { - G_INT (d->ofs) = G_INT (vec->ofs) + comp; - reloc_def_field (d, d->ofs); - } - Hash_Add (defs_by_name, d); - if (is_field) - Hash_Add (field_defs, d); -} - def_t * -field_def (const char *name) -{ - return Hash_Find (field_defs, name); -} - -/* - get_def - - If type is NULL, it will match any type - If allocate is true, a new def will be allocated if it can't be found -*/ -def_t * -get_def (type_t *type, const char *name, scope_t *scope, +new_def (const char *name, type_t *type, defspace_t *space, storage_class_t storage) -{ - def_t *def = check_for_name (type, name, scope, storage); - defspace_t *space = NULL; - - if (storage == st_none) - return def; - - if (def) { - if (storage != st_extern && !def->initialized) { - def->file = pr.source_file; - def->line = pr.source_line; - } - if (!def->external || storage == st_extern) - return def; - } else { - // allocate a new def - def = new_def (type, name, scope); - if (name) - Hash_Add (defs_by_name, def); - } - - switch (storage) { - case st_none: - case st_global: - case st_local: - case st_system: - space = scope->space; - break; - case st_extern: - space = 0; - break; - case st_static: - space = pr.near_data; - break; - } - // new_def sets def->space to the scope's space, but that is generally - // not valid for st_static or st_extern - def->space = space; - if (space) { - if (type->type == ev_field && type->t.fldptr.type == &type_vector) - def->ofs = defspace_new_loc (space, - type_size (type->t.fldptr.type)); - else - def->ofs = defspace_new_loc (space, type_size (type)); - } - - set_storage_bits (def, storage); - - if (name) { - // make automatic defs for the vectors elements .origin can be accessed - // as .origin_x, .origin_y, and .origin_z - if (type->type == ev_vector) { - vector_component (0, def, 0, scope, storage); - vector_component (0, def, 1, scope, storage); - vector_component (0, def, 2, scope, storage); - } - - if (type->type == ev_field) { - if (storage == st_global || storage == st_static) { - G_INT (def->ofs) = defspace_new_loc (pr.entity_data, - type_size (type->t.fldptr.type)); - reloc_def_field (def, def->ofs); - def->constant = 1; - def->nosave = 1; - } - - if (type->t.fldptr.type->type == ev_vector) { - vector_component (1, def, 0, scope, storage); - vector_component (1, def, 1, scope, storage); - vector_component (1, def, 2, scope, storage); - } - Hash_Add (field_defs, def); - } - } - - return def; -} - -def_t * -new_def (type_t *type, const char *name, scope_t *scope) { def_t *def; ALLOC (16384, def_t, defs, def); - if (scope) { - *scope->tail = def; - scope->tail = &def->def_next; - scope->num_defs++; - } + if (!space && storage != st_extern) + internal_error (0, "non-external def with no storage space"); def->return_addr = __builtin_return_address (0); def->name = name ? save_string (name) : 0; def->type = type; + def->space = space; - if (scope) { - def->scope = scope; - def->space = scope->space; + if (storage != st_extern) { + *space->def_tail = def; + space->def_tail = &def->next; + def->offset = defspace_new_loc (space, type_size (type)); } def->file = pr.source_file; def->line = pr.source_line; - return def; -} + set_storage_bits (def, storage); -def_t * -get_tempdef (type_t *type, scope_t *scope) -{ - int size = type_size (type) - 1; - def_t *def; - - if (free_temps[size]) { - def = free_temps[size]; - free_temps[size] = def->next; - def->type = type; - } else { - def = new_def (type, va (".tmp%d", tempdef_counter++), scope); - def->ofs = defspace_new_loc (scope->space, type_size (type)); - } - def->return_addr = __builtin_return_address (0); - def->freed = def->removed = def->users = 0; - def->next = temp_scope.next; - set_storage_bits (def, st_local); - temp_scope.next = def; return def; } void -free_tempdefs (void) +free_def (def_t *def) { - def_t **def, *d; - int size; + if (def->space) { + def_t **d; - def = &temp_scope.next; - while (*def) { - if ((*def)->users <= 0) { - d = *def; - *def = d->next; - - if (d->users < 0) { - expr_t e; - e.file = d->file; - e.line = d->line; - notice (&e, "temp def over-freed:%s offs:%d users:%d " - "managed:%d %s", - pr_type_name[d->type->type], - d->ofs, d->users, d->managed, - d->name); - } - size = type_size (d->type) - 1; - //if (d->expr) - // d->expr->e.temp.def = 0; - - if (!d->freed) { - d->next = free_temps[size]; - free_temps[size] = d; - d->freed = 1; - } - } else { - def = &(*def)->next; - } + for (d = &def->space->defs; *d && *d != def; d = &(*d)->next) + ; + *d = def->next; + defspace_free_loc (def->space, def->offset, type_size (def->type)); } -} - -void -reset_tempdefs (void) -{ - size_t i; - def_t *d; - - tempdef_counter = 0; - for (i = 0; i < sizeof (free_temps) / sizeof (free_temps[0]); i++) { - free_temps[i] = 0; - } - - for (d = temp_scope.next; d; d = d->next) { - expr_t e; - e.file = d->file; - e.line = d->line; - notice (&e, "temp def under-freed:%s ofs:%d users:%d managed:%d %s", - pr_type_name[d->type->type], - d->ofs, d->users, d->managed, d->name); - } - temp_scope.next = 0; -} - -void -flush_scope (scope_t *scope, int force_used) -{ - def_t *def; - - for (def = scope->head; def; def = def->def_next) { - if (def->name) { - if (!force_used && !def->used) { - expr_t e; - - e.line = def->line; - e.file = def->file; - if (options.warnings.unused) - warning (&e, "unused variable `%s'", def->name); - } - if (!def->removed) { - Hash_Del (defs_by_name, def->name); - if (def->type->type == ev_field) { - if (Hash_Find (field_defs, def->name) == def) - Hash_Del (field_defs, def->name); - } - def->removed = 1; - } - } - } -} - -void -def_initialized (def_t *d) -{ - d->initialized = 1; - if (d->type == &type_vector - || (d->type->type == ev_field - && d->type->t.fldptr.type == &type_vector)) { - d = d->def_next; - d->initialized = 1; - d = d->def_next; - d->initialized = 1; - d = d->def_next; - d->initialized = 1; - } - if (d->parent) { - d = d->parent; - if (d->type == &type_vector - && d->def_next->initialized - && d->def_next->def_next->initialized - && d->def_next->def_next->def_next->initialized) - d->initialized = 1; - } -} - -void -clear_defs (void) -{ - if (field_defs) - Hash_FlushTable (field_defs); - if (defs_by_name) - Hash_FlushTable (defs_by_name); + def->next = free_defs; + free_defs = def; } void @@ -458,6 +145,6 @@ def_to_ddef (def_t *def, ddef_t *ddef, int aux) if (aux) type = type->t.fldptr.type; // aux is true only for fields ddef->type = type->type; - ddef->ofs = def->ofs; + ddef->ofs = def->offset; ddef->s_name = ReuseString (def->name); } diff --git a/tools/qfcc/source/defspace.c b/tools/qfcc/source/defspace.c index ce1f3be0a..75b188999 100644 --- a/tools/qfcc/source/defspace.c +++ b/tools/qfcc/source/defspace.c @@ -116,7 +116,7 @@ defspace_new_loc (defspace_t *space, int size) } void -defsapce_free_loc (defspace_t *space, int ofs, int size) +defspace_free_loc (defspace_t *space, int ofs, int size) { locref_t **l; locref_t *loc; diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index fe9d72e3e..b8328df40 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -2320,7 +2320,7 @@ selector_expr (keywordarg_t *selector) { dstring_t *sel_id = dstring_newstr (); expr_t *sel; - def_t *sel_def; + symbol_t *sel_sym; int index; selector = copy_keywordargs (selector); @@ -2328,9 +2328,9 @@ selector_expr (keywordarg_t *selector) selector_name (sel_id, selector); index = selector_index (sel_id->str); index *= type_size (type_SEL.t.fldptr.type); - sel_def = get_def (type_SEL.t.fldptr.type, "_OBJ_SELECTOR_TABLE", pr.scope, - st_extern); - sel = 0; //FIXME new_def_expr (sel_def); + sel_sym = make_symbol ("_OBJ_SELECTOR_TABLE", type_SEL.t.fldptr.type, + 0, st_extern); + sel = new_symbol_expr (sel_sym); dstring_delete (sel_id); return address_expr (sel, new_short_expr (index), 0); } @@ -2372,7 +2372,6 @@ super_expr (class_type_t *class_type) return error (0, "%s has no super class", class->name); super_d = 0;//FIXME get_def (&type_Super, ".super", current_func->scope, st_local); - def_initialized (super_d); super = 0; //FIXME new_def_expr (super_d); super_block = new_block_expr (); @@ -2382,7 +2381,7 @@ super_expr (class_type_t *class_type) _class_type.type = ct_class; _class_type.c.class = class; - e = 0; //FIXME new_def_expr (class_def (&_class_type, 1)); + e = new_symbol_expr (class_symbol (&_class_type, 1)); e = assign_expr (binary_expr ('.', super, new_name_expr ("class")), binary_expr ('.', e, new_name_expr ("super_class"))); append_expr (super_block, e); @@ -2493,18 +2492,18 @@ report_function (expr_t *e) if (file != last_file) { for (srcline = pr.srcline_stack; srcline; srcline = srcline->next) fprintf (stderr, "In file included from %s:%d:\n", - G_GETSTR (srcline->source_file), srcline->source_line); + GETSTR (srcline->source_file), srcline->source_line); } last_file = file; if (current_func != last_func) { if (current_func) { - fprintf (stderr, "%s: In function `%s':\n", G_GETSTR (file), + fprintf (stderr, "%s: In function `%s':\n", GETSTR (file), current_func->name); } else if (current_class) { - fprintf (stderr, "%s: In class `%s':\n", G_GETSTR (file), + fprintf (stderr, "%s: In class `%s':\n", GETSTR (file), get_class_name (current_class, 1)); } else { - fprintf (stderr, "%s: At top level:\n", G_GETSTR (file)); + fprintf (stderr, "%s: At top level:\n", GETSTR (file)); } } last_func = current_func; @@ -2527,7 +2526,7 @@ _warning (expr_t *e, const char *fmt, va_list args) file = e->file; line = e->line; } - fprintf (stderr, "%s:%d: warning: ", G_GETSTR (file), line); + fprintf (stderr, "%s:%d: warning: ", GETSTR (file), line); vfprintf (stderr, fmt, args); fputs ("\n", stderr); } @@ -2552,7 +2551,7 @@ notice (expr_t *e, const char *fmt, ...) file = e->file; line = e->line; } - fprintf (stderr, "%s:%d: notice: ", G_GETSTR (file), line); + fprintf (stderr, "%s:%d: notice: ", GETSTR (file), line); vfprintf (stderr, fmt, args); fputs ("\n", stderr); } @@ -2583,7 +2582,7 @@ _error (expr_t *e, const char *err, const char *fmt, va_list args) file = e->file; line = e->line; } - fprintf (stderr, "%s:%d: %s%s", G_GETSTR (file), line, err, + fprintf (stderr, "%s:%d: %s%s", GETSTR (file), line, err, fmt ? ": " : ""); if (fmt) vfprintf (stderr, fmt, args); diff --git a/tools/qfcc/source/function.c b/tools/qfcc/source/function.c index 0e06a2483..c79a48dfb 100644 --- a/tools/qfcc/source/function.c +++ b/tools/qfcc/source/function.c @@ -255,20 +255,6 @@ function_symbol (symbol_t *sym, int overload, int create) return s; } -def_t * -get_function_def (const char *name, struct type_s *type, - scope_t *scope, storage_class_t storage, - int overload, int create) -{ - overloaded_function_t *func; - - func = get_function (name, type, overload, create); - - if (func && func->overloaded) - name = func->full_name; - return get_def (type, name, scope, storage); -} - // NOTE sorts the list in /reverse/ order static int func_compare (const void *a, const void *b) diff --git a/tools/qfcc/source/idstuff.c b/tools/qfcc/source/idstuff.c index 28ff33475..a4f099f43 100644 --- a/tools/qfcc/source/idstuff.c +++ b/tools/qfcc/source/idstuff.c @@ -193,7 +193,7 @@ WriteFiles (const char *sourcedir) int WriteProgdefs (const char *filename) { - def_t *d; +// def_t *d; FILE *f; unsigned short crc; int c; @@ -206,7 +206,7 @@ WriteProgdefs (const char *filename) fprintf (f, "\n/* file generated by qcc, do not modify */" "\n\ntypedef struct\n{\tint\tpad[%i];\n", RESERVED_OFS); - +#if 0 //FIXME for (d = pr.scope->head; d; d = d->def_next) { if (d->name && !strcmp (d->name, "end_sys_globals")) break; @@ -274,7 +274,7 @@ WriteProgdefs (const char *filename) } } fprintf (f, "} entvars_t;\n\n"); - +#endif fclose (f); // do a crc of the file diff --git a/tools/qfcc/source/immediate.c b/tools/qfcc/source/immediate.c index 4dc905dd2..f3f46146a 100644 --- a/tools/qfcc/source/immediate.c +++ b/tools/qfcc/source/immediate.c @@ -233,16 +233,16 @@ ReuseConstant (expr_t *expr, def_t *def) if (imm) { cn = imm->def; if (def) { - defsapce_free_loc (def->space, def->ofs, type_size (def->type)); - def->ofs = cn->ofs; + defspace_free_loc (def->space, def->offset, type_size (def->type)); + def->offset = cn->offset; def->initialized = def->constant = 1; def->nosave = 1; def->local = 0; cn = def; } else { if (cn->type != type) { - def = new_def (type, ".imm", pr.scope); - def->ofs = cn->ofs; + def = new_def (".imm", type, pr.near_data, st_static); + def->offset = cn->offset; cn = def; } } @@ -252,34 +252,34 @@ ReuseConstant (expr_t *expr, def_t *def) // always share immediates if (def) { if (def->type != type) { - cn = new_def (type, ".imm", pr.scope); - cn->ofs = def->ofs; + cn = new_def (".imm", type, pr.near_data, st_static); + cn->offset = def->offset; } else { cn = def; } } else { - cn = new_def (type, ".imm", pr.scope); - cn->ofs = defspace_new_loc (pr.near_data, type_size (type)); + cn = new_def (".imm", type, pr.near_data, st_static); + cn->offset = defspace_new_loc (pr.near_data, type_size (type)); } cn->initialized = cn->constant = 1; cn->nosave = 1; // copy the immediate to the global area switch (e.e.value.type) { case ev_string: - reloc = new_reloc (cn->ofs, rel_def_string); + reloc = new_reloc (cn->offset, rel_def_string); break; case ev_func: if (e.e.value.v.func_val) - reloc = new_reloc (cn->ofs, rel_def_func); + reloc = new_reloc (cn->offset, rel_def_func); break; case ev_field: if (e.e.value.v.pointer.def) - reloc_def_field_ofs (e.e.value.v.pointer.def, cn->ofs); + reloc_def_field_ofs (e.e.value.v.pointer.def, cn->offset); break; case ev_pointer: if (e.e.value.v.pointer.def) { - EMIT_DEF_OFS (G_INT (cn->ofs), e.e.value.v.pointer.def); - e.e.value.v.pointer.def->users--; + EMIT_DEF_OFS (pr.near_data, D_INT (cn), + e.e.value.v.pointer.def); } break; default: @@ -290,7 +290,7 @@ ReuseConstant (expr_t *expr, def_t *def) pr.relocs = reloc; } - memcpy (G_POINTER (void, cn->ofs), &e.e, 4 * type_size (type)); + memcpy (D_POINTER (void, cn), &e.e, 4 * type_size (type)); imm = malloc (sizeof (immediate_t)); imm->def = cn; @@ -347,7 +347,7 @@ clear_immediates (void) } imm = calloc (1, sizeof (immediate_t)); - imm->def = get_def (&type_zero, ".zero", pr.scope, st_extern); + imm->def = 0;//FIXME get_def (&type_zero, ".zero", pr.scope, st_extern); imm->def->nosave = 1; Hash_AddElement (string_imm_defs, imm); diff --git a/tools/qfcc/source/method.c b/tools/qfcc/source/method.c index cf4417b28..7434786a2 100644 --- a/tools/qfcc/source/method.c +++ b/tools/qfcc/source/method.c @@ -169,8 +169,9 @@ method_def (class_type_t *class_type, method_t *method) for (s = str->str; *s; s++) if (*s == ':') *s = '_'; - //printf ("%s %s %s %ld\n", method->name, method->types, str->str, str->size); - def = get_def (method->type, str->str, pr.scope, st_static); + //printf ("%s %s %s %ld\n", method->name, method->types, str->str, + // str->size); + def = make_symbol (str->str, method->type, pr.far_data, st_static)->s.def; dstring_delete (str); return def; } @@ -370,116 +371,167 @@ emit_selectors (void) return 0; sel_type = array_type (type_SEL.t.fldptr.type, sel_index); - sel_def = get_def (type_SEL.t.fldptr.type, "_OBJ_SELECTOR_TABLE", pr.scope, - st_extern); - sel_def->type = sel_type; - sel_def->ofs = defspace_new_loc (pr.near_data, type_size (sel_type)); - set_storage_bits (sel_def, st_static); - sel = G_POINTER (pr_sel_t, sel_def->ofs); + sel_def = make_symbol ("_OBJ_SELECTOR_TABLE", type_SEL.t.fldptr.type, + pr.far_data, st_static)->s.def; + sel_def->initialized = sel_def->constant = 1; + sel_def->nosave = 1; + + sel = D_POINTER (pr_sel_t, sel_def); + selectors = (selector_t **) Hash_GetList (sel_hash); for (s = selectors; *s; s++) { - EMIT_STRING (sel[(*s)->index].sel_id, (*s)->name); - EMIT_STRING (sel[(*s)->index].sel_types, (*s)->types); + EMIT_STRING (sel_def->space, sel[(*s)->index].sel_id, (*s)->name); + EMIT_STRING (sel_def->space, sel[(*s)->index].sel_types, (*s)->types); } free (selectors); return sel_def; } +static void +emit_methods_next (def_t *def, void *data, int index) +{ + if (def->type != &type_pointer) + internal_error (0, "%s: expected pointer def", __FUNCTION__); + D_INT (def) = 0; +} + +static void +emit_methods_count (def_t *def, void *data, int index) +{ + methodlist_t *methods = (methodlist_t *) data; + + if (def->type != &type_integer) + internal_error (0, "%s: expected integer def", __FUNCTION__); + D_INT (def) = methods->count; +} + +static void +emit_methods_list_item (def_t *def, void *data, int index) +{ + methodlist_t *methods = (methodlist_t *) data; + method_t *m; + pr_method_t *meth; + + if (def->type != &type_method_description) + internal_error (0, "%s: expected method_descripting def", + __FUNCTION__); + if (index < 0 || index >= methods->count) + internal_error (0, "%s: out of bounds index: %d %d", + __FUNCTION__, index, methods->count); + + meth = D_POINTER (pr_method_t, def); + + for (m = methods->head; m; m = m->next) { + if (!m->instance != !methods->instance || !m->def) + continue; + if (!index--) + break; + } + EMIT_STRING (def->space, meth->method_name, m->name); + EMIT_STRING (def->space, meth->method_types, m->types); + meth->method_imp = D_FUNCTION (m->def); + if (m->func) + reloc_def_func (m->func, POINTER_OFS (def->space, &meth->method_imp)); +} + def_t * -emit_methods (methodlist_t *_methods, const char *name, int instance) +emit_methods (methodlist_t *methods, const char *name, int instance) { static struct_def_t methods_struct[] = { - {"method_next", &type_pointer}, - {"method_count", &type_integer}, - {"method_list", 0}, // type will be filled in at run time + {"method_next", &type_pointer, emit_methods_next}, + {"method_count", &type_integer, emit_methods_count}, + {"method_list", 0, emit_methods_list_item}, {0, 0} }; const char *type = instance ? "INSTANCE" : "CLASS"; - method_t *method; - int i, count; - def_t *methods_def; - type_t *methods_type; - pr_method_list_t *methods; + method_t *m; + int count; - if (!_methods) + if (!methods) return 0; - for (count = 0, method = _methods->head; method; method = method->next) - if (!method->instance == !instance) { - if (!method->def && options.warnings.unimplemented) { + for (count = 0, m = methods->head; m; m = m->next) + if (!m->instance == !instance) { + if (!m->def && options.warnings.unimplemented) { warning (0, "Method `%c%s' not implemented", - method->instance ? '-' : '+', method->name); + m->instance ? '-' : '+', m->name); } count++; } if (!count) return 0; + methods->count = count; + methods_struct[2].type = array_type (&type_integer, count); - methods_type = make_structure (0, 's', methods_struct, 0)->type; - methods_def = get_def (methods_type, - va ("_OBJ_%s_METHODS_%s", type, name), - pr.scope, st_static); - methods_def->initialized = methods_def->constant = 1; - methods_def->nosave = 1; - 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 || !method->def) + return emit_structure (va ("_OBJ_%s_METHODS_%s", type, name), 's', + methods_struct, 0, methods, st_static); +} + +static void +emit_method_list_count (def_t *def, void *data, int index) +{ + methodlist_t *methods = (methodlist_t *) data; + + if (def->type != &type_integer) + internal_error (0, "%s: expected integer def", __FUNCTION__); + D_INT (def) = methods->count; +} + +static void +emit_method_list_item (def_t *def, void *data, int index) +{ + methodlist_t *methods = (methodlist_t *) data; + method_t *m; + pr_method_description_t *desc; + + if (def->type != &type_method_description) + internal_error (0, "%s: expected method_descripting def", + __FUNCTION__); + if (index < 0 || index >= methods->count) + internal_error (0, "%s: out of bounds index: %d %d", + __FUNCTION__, index, methods->count); + + desc = D_POINTER (pr_method_description_t, def); + + for (m = methods->head; m; m = m->next) { + if (!m->instance != !methods->instance || !m->def) continue; - EMIT_STRING (methods->method_list[i].method_name, method->name); - EMIT_STRING (methods->method_list[i].method_types, method->types); - methods->method_list[i].method_imp = G_FUNCTION (method->def->ofs); - if (method->func) { - reloc_def_func (method->func, - POINTER_OFS (&methods->method_list[i].method_imp)); - } - i++; + if (!index--) + break; } - return methods_def; + EMIT_STRING (def->space, desc->name, m->name); + EMIT_STRING (def->space, desc->types, m->types); } def_t * -emit_method_descriptions (methodlist_t *_methods, const char *name, +emit_method_descriptions (methodlist_t *methods, const char *name, int instance) { + static struct_def_t method_list_struct[] = { + {"count", &type_integer, emit_method_list_count}, + {"method_list", 0, emit_method_list_item}, + {0, 0} + }; const char *type = instance ? "PROTOCOL_INSTANCE" : "PROTOCOL_CLASS"; - method_t *method; - int i, count; - def_t *methods_def; - pr_method_description_list_t *methods; - symtab_t *method_list; - symbol_t *method_list_sym; + method_t *m; + int count; - if (!_methods) + if (!methods) return 0; - for (count = 0, method = _methods->head; method; method = method->next) - if (!method->instance == !instance) + for (count = 0, m = methods->head; m; m = m->next) + if (!m->instance == !instance && m->def) count++; if (!count) return 0; - method_list = new_symtab (0, stab_local); - symtab_addsymbol (method_list, new_symbol_type ("count", &type_integer)); - symtab_addsymbol (method_list, new_symbol_type ("method_list", - array_type (&type_method_description, count))); - method_list_sym = build_struct ('s', 0, method_list, 0); - methods_def = get_def (method_list_sym->type, - va ("_OBJ_%s_METHODS_%s", type, name), - pr.scope, st_static); - methods_def->initialized = methods_def->constant = 1; - methods_def->nosave = 1; - methods = &G_STRUCT (pr_method_description_list_t, methods_def->ofs); + methods->count = count; - for (i = 0, method = _methods->head; method; method = method->next) { - if (!method->instance != !instance || !method->def) - continue; - EMIT_STRING (methods->list[i].name, method->name); - EMIT_STRING (methods->list[i].types, method->types); - i++; - } - return methods_def; + methods->instance = instance; + + method_list_struct[1].type = array_type (&type_method_description, count); + return emit_structure (va ("_OBJ_%s_METHODS_%s", type, name), 's', + method_list_struct, 0, methods, st_static); } void diff --git a/tools/qfcc/source/obj_file.c b/tools/qfcc/source/obj_file.c index 4e130be1d..36458edb1 100644 --- a/tools/qfcc/source/obj_file.c +++ b/tools/qfcc/source/obj_file.c @@ -89,19 +89,17 @@ allocate_stuff (pr_info_t *pr) num_funcs = pr->num_functions - 1; num_relocs = 0; for (def = pr->scope->head; def; def = def->def_next) { - if (def->alias) - continue; num_defs++; - num_relocs += count_relocs (def->refs); + num_relocs += count_relocs (def->relocs); } for (func = pr->func_head; func; func = func->next) { num_relocs += count_relocs (func->refs); - //FIXME if (func->scope) { - //FIXME num_defs += func->scope->num_defs; - //FIXME for (def = func->scope->head; def; def = def->def_next) { - //FIXME num_relocs += count_relocs (def->refs); - //FIXME } - //FIXME } + if (func->scope) { + num_defs += func->scope->num_defs; + for (def = func->scope->head; def; def = def->def_next) { + num_relocs += count_relocs (def->relocs); + } + } } num_relocs += count_relocs (pr->relocs); if (num_defs) @@ -133,8 +131,6 @@ flags (def_t *d) flags |= QFOD_INITIALIZED; if (d->constant) flags |= QFOD_CONSTANT; - if (d->absolute) - flags |= QFOD_ABSOLUTE; if (d->global) flags |= QFOD_GLOBAL; if (d->external) @@ -173,13 +169,13 @@ write_def (def_t *d, qfo_def_t *def, qfo_reloc_t **reloc) def->basic_type = LittleLong (d->type->type); def->full_type = LittleLong (type_encoding (d->type)); def->name = LittleLong (ReuseString (d->name)); - def->ofs = LittleLong (d->ofs); + def->ofs = LittleLong (d->offset); def->relocs = LittleLong (*reloc - relocs); - def->num_relocs = LittleLong (count_relocs (d->refs)); + def->num_relocs = LittleLong (count_relocs (d->relocs)); def->flags = LittleLong (flags (d)); def->file = LittleLong (d->file); def->line = LittleLong (d->line); - write_relocs (d->refs, reloc, d->obj_def); + write_relocs (d->relocs, reloc, d->obj_def); } static void @@ -196,25 +192,24 @@ setup_data (pr_info_t *pr) pr_lineno_t *line; for (d = pr->scope->head; d; d = d->def_next) - if (!d->alias) - write_def (d, def++, &reloc); + write_def (d, def++, &reloc); for (f = pr->func_head; f; f = f->next, func++) { func->name = LittleLong (f->s_name); func->file = LittleLong (f->s_file); - //FIXME func->line = LittleLong (f->def->line); + func->line = LittleLong (f->def->line); func->builtin = LittleLong (f->builtin); func->code = LittleLong (f->code); - //FIXME if (f->def->obj_def) - //FIXME func->def = LittleLong (f->def->obj_def); - //FIXMEelse { - //FIXME func->def = LittleLong (def - defs); - //FIXME write_def (f->def, def++, &reloc); - //FIXME} - //FIXME if (f->scope) { - //FIXME func->locals_size = LittleLong (f->scope->space->size); - //FIXME func->local_defs = LittleLong (def - defs); - //FIXME func->num_local_defs = LittleLong (f->scope->num_defs); - //FIXME } + if (f->def->obj_def) + = LittleLong (f->def->obj_def); + else { + func->def = LittleLong (def - defs); + write_def (f->def, def++, &reloc); + } + if (f->scope) { + func->locals_size = LittleLong (f->scope->space->size); + func->local_defs = LittleLong (def - defs); + func->num_local_defs = LittleLong (f->scope->num_defs); + } if (f->aux) func->line_info = LittleLong (f->aux->line_info); func->num_parms = LittleLong (function_parms (f, func->parm_size)); @@ -222,14 +217,14 @@ setup_data (pr_info_t *pr) func->num_relocs = LittleLong (count_relocs (f->refs)); write_relocs (f->refs, &reloc, func - funcs); - //FIXME if (f->scope) - //FIXME for (d = f->scope->head; d; d = d->def_next) - //FIXME write_def (d, def++, &reloc); + if (f->scope) + for (d = f->scope->head; d; d = d->def_next) + write_def (d, def++, &reloc); } for (r = pr->relocs; r; r = r->next) - //FIXME if (r->type == rel_def_op) - //FIXME write_one_reloc (r, &reloc, r->label->ofs); - //FIXME else + if (r->type == rel_def_op) + write_one_reloc (r, &reloc, r->label->ofs); + else write_one_reloc (r, &reloc, 0); for (st = pr->code->code; st - pr->code->code < pr->code->size; st++) { st->op = LittleLong (st->op); @@ -541,14 +536,13 @@ qfo_to_progs (qfo_t *qfo, pr_info_t *pr) pr->scope->tail = &pd->def_next; pd->type = parse_type (qfo->types + qd->full_type); pd->name = qd->name ? qfo->strings + qd->name : 0; - pd->ofs = qd->ofs; + pd->offset = qd->ofs; if (qd->num_relocs) { - pd->refs = relocs + qd->relocs; - pd->refs[qd->num_relocs - 1].next = 0; + pd->relocs = relocs + qd->relocs; + pd->relocs[qd->num_relocs - 1].next = 0; } pd->initialized = (qd->flags & QFOD_INITIALIZED) != 0; pd->constant = (qd->flags & QFOD_CONSTANT) != 0; - pd->absolute = (qd->flags & QFOD_ABSOLUTE) != 0; pd->global = (qd->flags & QFOD_GLOBAL) != 0; pd->external = (qd->flags & QFOD_EXTERNAL) != 0; pd->local = (qd->flags & QFOD_LOCAL) != 0; @@ -567,34 +561,34 @@ qfo_to_progs (qfo_t *qfo, pr_info_t *pr) i < qfo->num_funcs; i++, pf++, qf++) { *pr->func_tail = pf; pr->func_tail = &pf->next; - //FIXME pf->def = pr->scope->head + qf->def; + pf->def = pr->scope->head + qf->def; pf->aux = new_auxfunction (); pf->aux->function = i + 1; pf->aux->source_line = qf->line; pf->aux->line_info = qf->line_info; pf->aux->local_defs = 0; pf->aux->num_locals = 0; - //FIXME pf->aux->return_type = pf->def->type->t.func.type->type; + pf->aux->return_type = pf->def->type->t.func.type->type; pf->builtin = qf->builtin; pf->code = qf->code; pf->function_num = i + 1; pf->s_file = qf->file; pf->s_name = qf->name; - //FIXME pf->scope = new_scope (sc_params, init_space (qf->locals_size, 0), - //FIXME pr->scope); + pf->scope = new_scope (sc_params, init_space (qf->locals_size, 0), + pr->scope); if (qf->num_local_defs) { if (first_local > qf->local_defs) first_local = qf->local_defs; - //FIXME pf->scope->head = pr->scope->head + qf->local_defs; - //FIXME pf->scope->tail = &pf->scope->head[qf->num_local_defs - 1].def_next; - //FIXME *pf->scope->tail = 0; + pf->scope->head = pr->scope->head + qf->local_defs; + pf->scope->tail = &pf->scope->head[qf->num_local_defs - 1].def_next; + *pf->scope->tail = 0; pf->aux->local_defs = pr->num_locals; - //FIXME for (pd = pf->scope->head; pd; pd = pd->def_next) { - //FIXME if (pd->name) { - //FIXME def_to_ddef (pd, new_local (), 0); - //FIXME pf->aux->num_locals++; - //FIXME } - //FIXME } + for (pd = pf->scope->head; pd; pd = pd->def_next) { + if (pd->name) { + def_to_ddef (pd, new_local (), 0); + pf->aux->num_locals++; + } + } } if (qf->num_relocs) { pf->refs = relocs + qf->relocs; diff --git a/tools/qfcc/source/obj_stub.c b/tools/qfcc/source/obj_stub.c new file mode 100644 index 000000000..faad49223 --- /dev/null +++ b/tools/qfcc/source/obj_stub.c @@ -0,0 +1,147 @@ +/* + obj_file.c + + qfcc object file support + + Copyright (C) 2002 Bill Currie + + Author: Bill Currie + Date: 2002/6/21 + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +static __attribute__ ((used)) const char rcsid[] = "$Id$"; + +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#include + +#include "QF/dstring.h" +#include "QF/qendian.h" +#include "QF/quakeio.h" + +#include "codespace.h" +#include "debug.h" +#include "def.h" +#include "defspace.h" +#include "emit.h" +#include "expr.h" +#include "function.h" +#include "immediate.h" +#include "obj_file.h" +#include "options.h" +#include "qfcc.h" +#include "reloc.h" +#include "strpool.h" +#include "type.h" + +qfo_t * +qfo_from_progs (pr_info_t *pr) +{ + return 0; +} + +int +qfo_write (qfo_t *qfo, const char *filename) +{ + return 0; +} + +qfo_t * +qfo_read (QFile *file) +{ + return 0; +} + +qfo_t * +qfo_open (const char *filename) +{ + return 0; +} + +int +qfo_to_progs (qfo_t *qfo, pr_info_t *pr) +{ + return 0; +} + +qfo_t * +qfo_new (void) +{ + return 0; +} + +void +qfo_add_code (qfo_t *qfo, dstatement_t *code, int code_size) +{ +} + +void +qfo_add_data (qfo_t *qfo, pr_type_t *data, int data_size) +{ +} + +void +qfo_add_far_data (qfo_t *qfo, pr_type_t *far_data, int far_data_size) +{ +} + +void +qfo_add_strings (qfo_t *qfo, const char *strings, int strings_size) +{ +} + +void +qfo_add_relocs (qfo_t *qfo, qfo_reloc_t *relocs, int num_relocs) +{ +} + +void +qfo_add_defs (qfo_t *qfo, qfo_def_t *defs, int num_defs) +{ +} + +void +qfo_add_funcs (qfo_t *qfo, qfo_func_t *funcs, int num_funcs) +{ +} + +void +qfo_add_lines (qfo_t *qfo, pr_lineno_t *lines, int num_lines) +{ +} + +void +qfo_add_types (qfo_t *qfo, const char *types, int types_size) +{ +} + +void +qfo_delete (qfo_t *qfo) +{ +} diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index bacb3c0cb..a9fcfa559 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -339,11 +339,13 @@ InitData (void) pr.strings = strpool_new (); pr.num_functions = 1; + pr.far_data = new_defspace (); + pr.near_data = new_defspace (); pr.near_data->data = calloc (65536, sizeof (pr_type_t)); pr.near_data->max_size = 65536; pr.near_data->grow = 0; - pr.scope = new_scope (sc_global, pr.near_data, 0); + //FIXME pr.scope = new_scope (sc_global, pr.near_data, 0); pr.entity_data = new_defspace (); @@ -355,6 +357,7 @@ InitData (void) static int WriteData (int crc) { +#if 0 //FIXME def_t *def; ddef_t *dd; dprograms_t progs; @@ -531,6 +534,7 @@ WriteData (int crc) Qseek (h, 0, SEEK_SET); Qwrite (h, &debug, sizeof (debug)); Qclose (h); +#endif return 0; } @@ -570,15 +574,16 @@ setup_param_block (void) static qboolean finish_compilation (void) { - def_t *d; + //FIXME def_t *d; qboolean errors = false; function_t *f; - def_t *def; + //FIXME def_t *def; expr_t e; //FIXME ex_label_t *l; dfunction_t *df; // check to make sure all functions prototyped have code +#if 0 //FIXME if (options.warnings.undefined_function) for (d = pr.scope->head; d; d = d->def_next) { if (d->type->type == ev_func && d->global) { @@ -604,23 +609,24 @@ finish_compilation (void) } } } +#endif if (errors) return !errors; if (options.code.progsversion != PROG_ID_VERSION) { e = *new_integer_expr (type_size (&type_param)); - ReuseConstant (&e, get_def (&type_integer, ".param_size", pr.scope, - st_global)); + //FIXME ReuseConstant (&e, get_def (&type_integer, ".param_size", pr.scope, + //FIXME st_global)); } if (options.code.debug) { e = *new_string_expr (debugfile); - ReuseConstant (&e, get_def (&type_string, ".debug_file", pr.scope, - st_global)); + //FIXME ReuseConstant (&e, get_def (&type_string, ".debug_file", pr.scope, + //FIXME st_global)); } - for (def = pr.scope->head; def; def = def->def_next) - relocate_refs (def->refs, def->ofs); + //FIXME for (def = pr.scope->head; def; def = def->def_next) + //FIXME relocate_refs (def->refs, def->ofs); pr.functions = calloc (pr.num_functions + 1, sizeof (dfunction_t)); for (df = pr.functions + 1, f = pr.func_head; f; df++, f = f->next) { @@ -658,7 +664,7 @@ finish_compilation (void) int ofs; for (ofs = defspace_new_loc (pr.near_data, num_localdefs); ofs < pr.near_data->size; ofs++) - G_INT (ofs) = 0; + pr.near_data->data[ofs].integer_var = 0; } //FIXME for (l = pr.labels; l; l = l->next) @@ -720,7 +726,6 @@ compile_to_obj (const char *file, const char *obj) setup_param_block (); clear_frame_macros (); clear_classes (); - clear_defs (); clear_immediates (); clear_selectors (); chain_initial_types (); diff --git a/tools/qfcc/source/reloc.c b/tools/qfcc/source/reloc.c index ff750785f..488203b10 100644 --- a/tools/qfcc/source/reloc.c +++ b/tools/qfcc/source/reloc.c @@ -53,108 +53,110 @@ static __attribute__ ((used)) const char rcsid[] = static reloc_t *free_refs; +#define G_INT(o) pr.near_data->data[o].integer_var + void -relocate_refs (reloc_t *refs, int ofs) +relocate_refs (reloc_t *reloc, int offset) { int o; - while (refs) { - switch (refs->type) { + while (reloc) { + switch (reloc->type) { case rel_none: break; case rel_op_a_def: - if (ofs > 65535) + if (offset > 65535) error (0, "def offset too large"); else - pr.code->code[refs->ofs].a = ofs; + pr.code->code[reloc->offset].a = offset; break; case rel_op_b_def: - if (ofs > 65535) + if (offset > 65535) error (0, "def offset too large"); else - pr.code->code[refs->ofs].b = ofs; + pr.code->code[reloc->offset].b = offset; break; case rel_op_c_def: - if (ofs > 65535) + if (offset > 65535) error (0, "def offset too large"); else - pr.code->code[refs->ofs].c = ofs; + pr.code->code[reloc->offset].c = offset; break; case rel_op_a_op: - o = ofs - refs->ofs; + o = offset - reloc->offset; if (o < -32768 || o > 32767) error (0, "relative offset too large"); else - pr.code->code[refs->ofs].a = o; + pr.code->code[reloc->offset].a = o; break; case rel_op_b_op: - o = ofs - refs->ofs; + o = offset - reloc->offset; if (o < -32768 || o > 32767) error (0, "relative offset too large"); else - pr.code->code[refs->ofs].b = o; + pr.code->code[reloc->offset].b = o; break; case rel_op_c_op: - o = ofs - refs->ofs; + o = offset - reloc->offset; if (o < -32768 || o > 32767) error (0, "relative offset too large"); else - pr.code->code[refs->ofs].c = o; + pr.code->code[reloc->offset].c = o; break; case rel_def_op: - if (ofs > pr.code->size) { + if (offset > pr.code->size) { error (0, "invalid statement offset: %d >= %d, %d", - ofs, pr.code->size, refs->ofs); + offset, pr.code->size, reloc->offset); } else - G_INT (refs->ofs) = ofs; + G_INT (reloc->offset) = offset; break; case rel_def_def: case rel_def_func: - G_INT (refs->ofs) = ofs; + G_INT (reloc->offset) = offset; break; case rel_def_string: break; case rel_def_field: break; case rel_op_a_def_ofs: - o = ofs + pr.code->code[refs->ofs].a; + o = offset + pr.code->code[reloc->offset].a; if (o < 0 || o > 65535) error (0, "def offset out of range"); else - pr.code->code[refs->ofs].a = o; + pr.code->code[reloc->offset].a = o; break; case rel_op_b_def_ofs: - o = ofs + pr.code->code[refs->ofs].b; + o = offset + pr.code->code[reloc->offset].b; if (o < 0 || o > 65535) error (0, "def offset out of range"); else - pr.code->code[refs->ofs].b = o; + pr.code->code[reloc->offset].b = o; break; case rel_op_c_def_ofs: - o = ofs + pr.code->code[refs->ofs].c; + o = offset + pr.code->code[reloc->offset].c; if (o < 0 || o > 65535) error (0, "def offset out of range"); else - pr.code->code[refs->ofs].c = o; + pr.code->code[reloc->offset].c = o; break; case rel_def_def_ofs: - G_INT (refs->ofs) += ofs; + G_INT (reloc->offset) += offset; break; case rel_def_field_ofs: - G_INT (refs->ofs) += G_INT (ofs); + G_INT (reloc->offset) += G_INT (offset); break; } - refs = refs->next; + reloc = reloc->next; } } reloc_t * -new_reloc (int ofs, reloc_type type) +new_reloc (int offset, reloc_type type) { reloc_t *ref; ALLOC (16384, reloc_t, refs, ref); - ref->ofs = ofs; + ref->offset = offset; ref->type = type; ref->line = pr.source_line; ref->file = pr.source_file; @@ -162,73 +164,73 @@ new_reloc (int ofs, reloc_type type) } void -reloc_op_def (def_t *def, int ofs, int field) +reloc_op_def (def_t *def, int offset, int field) { - reloc_t *ref = new_reloc (ofs, rel_op_a_def + field); - ref->next = def->refs; - def->refs = ref; + reloc_t *ref = new_reloc (offset, rel_op_a_def + field); + ref->next = def->relocs; + def->relocs = ref; } void -reloc_op_def_ofs (def_t *def, int ofs, int field) +reloc_op_def_ofs (def_t *def, int offset, int field) { - reloc_t *ref = new_reloc (ofs, rel_op_a_def_ofs + field); - ref->next = def->refs; - def->refs = ref; + reloc_t *ref = new_reloc (offset, rel_op_a_def_ofs + field); + ref->next = def->relocs; + def->relocs = ref; } void -reloc_def_def (def_t *def, int ofs) +reloc_def_def (def_t *def, int offset) { - reloc_t *ref = new_reloc (ofs, rel_def_def); - ref->next = def->refs; - def->refs = ref; + reloc_t *ref = new_reloc (offset, rel_def_def); + ref->next = def->relocs; + def->relocs = ref; } void -reloc_def_def_ofs (def_t *def, int ofs) +reloc_def_def_ofs (def_t *def, int offset) { - reloc_t *ref = new_reloc (ofs, rel_def_def_ofs); - ref->next = def->refs; - def->refs = ref; + reloc_t *ref = new_reloc (offset, rel_def_def_ofs); + ref->next = def->relocs; + def->relocs = ref; } void -reloc_def_func (function_t *func, int ofs) +reloc_def_func (function_t *func, int offset) { - reloc_t *ref = new_reloc (ofs, rel_def_func); + reloc_t *ref = new_reloc (offset, rel_def_func); ref->next = func->refs; func->refs = ref; } void -reloc_def_string (int ofs) +reloc_def_string (int offset) { - reloc_t *ref = new_reloc (ofs, rel_def_string); + reloc_t *ref = new_reloc (offset, rel_def_string); ref->next = pr.relocs; pr.relocs = ref; } void -reloc_def_field (def_t *def, int ofs) +reloc_def_field (def_t *def, int offset) { - reloc_t *ref = new_reloc (ofs, rel_def_field); - ref->next = def->refs; - def->refs = ref; + reloc_t *ref = new_reloc (offset, rel_def_field); + ref->next = def->relocs; + def->relocs = ref; } void -reloc_def_field_ofs (def_t *def, int ofs) +reloc_def_field_ofs (def_t *def, int offset) { - reloc_t *ref = new_reloc (ofs, rel_def_field_ofs); - ref->next = def->refs; - def->refs = ref; + reloc_t *ref = new_reloc (offset, rel_def_field_ofs); + ref->next = def->relocs; + def->relocs = ref; } void -reloc_def_op (ex_label_t *label, int ofs) +reloc_def_op (ex_label_t *label, int offset) { - reloc_t *ref = new_reloc (ofs, rel_def_op); + reloc_t *ref = new_reloc (offset, rel_def_op); ref->next = pr.relocs; ref->label = label; pr.relocs = ref; diff --git a/tools/qfcc/source/struct.c b/tools/qfcc/source/struct.c index 2923e5a51..da2e98a15 100644 --- a/tools/qfcc/source/struct.c +++ b/tools/qfcc/source/struct.c @@ -49,6 +49,7 @@ static __attribute__ ((used)) const char rcsid[] = #include #include "def.h" +#include "defspace.h" #include "emit.h" #include "expr.h" #include "immediate.h" @@ -70,7 +71,7 @@ find_tag (ty_type_e ty, symbol_t *tag, type_t *type) tag_name = va ("tag %s", tag->name); else tag_name = va ("tag .%s.%d.%d", - G_GETSTR (pr.source_file), pr.source_line, tag_num++); + GETSTR (pr.source_file), pr.source_line, tag_num++); sym = symtab_lookup (current_symtab, tag_name); if (sym) { if (sym->table == current_symtab && sym->type->ty != ty) @@ -180,6 +181,8 @@ make_structure (const char *name, int su, struct_def_t *defs, type_t *type) symbol_t *field; symbol_t *sym = 0; + if (name) + sym = new_symbol (name); if (su == 'u') strct = new_symtab (0, stab_union); else @@ -190,8 +193,79 @@ make_structure (const char *name, int su, struct_def_t *defs, type_t *type) internal_error (0, "duplicate symbol: %s", defs->name); defs++; } - if (name) - sym = new_symbol (name); sym = build_struct (su, sym, strct, type); return sym; } + +def_t * +emit_structure (const char *name, int su, struct_def_t *defs, type_t *type, + void *data, storage_class_t storage) +{ + type_t new; + int i, j; + int saw_null = 0; + int saw_func = 0; + symbol_t *struct_sym; + symbol_t *field_sym; + def_t *struct_def; + def_t field_def; + + if (!type) { + type = &new; + make_structure (0, su, defs, type); + } + if (!is_struct (type) || (su == 's' && type->ty != ty_struct) + || (su == 'u' && type->ty != ty_union)) + internal_error (0, "structure %s type mismatch", name); + for (i = 0, field_sym = type->t.symtab->symbols; field_sym; + i++, field_sym = field_sym->next) { + if (!defs[i].name) + internal_error (0, "structure %s unexpected end of defs", name); + if (field_sym->type != defs[i].type) + internal_error (0, "structure %s.%s field type mismatch", name, + defs[i].name); + if ((!defs[i].emit && saw_func) || (defs[i].emit && saw_null)) + internal_error (0, "structure %s mixed emit/copy", name); + if (!defs[i].emit) + saw_null = 1; + if (defs[i].emit) + saw_func = 1; + } + if (defs[i].name) + internal_error (0, "structure %s too many defs", name); + if (storage != st_global && storage != st_static) + internal_error (0, "structure %s must be global or static", name); + + struct_sym = make_symbol (name, type, pr.far_data, storage); + + struct_def = struct_sym->s.def; + if (struct_def->initialized) + internal_error (0, "structure %s must be global or static", name); + struct_def->initialized = struct_def->constant = 1; + struct_def->nosave = 1; + + for (i = 0, field_sym = type->t.symtab->symbols; field_sym; + i++, field_sym = field_sym->next) { + field_def.type = field_sym->type; + field_def.name = save_string (va ("%s.%s", name, field_sym->name)); + field_def.space = struct_def->space; + field_def.offset = struct_def->offset + field_sym->s.offset; + if (!defs[i].emit) { + //FIXME relocs? arrays? structs? + pr_type_t *val = (pr_type_t *) data; + memcpy (D_POINTER (void, &field_def), val, + type_size (field_def.type) * sizeof (pr_type_t)); + data = &val[type_size (field_def.type)]; + } else { + if (is_array (field_def.type)) { + for (j = 0; j < field_def.type->t.array.size; j++) { + defs[i].emit (&field_def, data, 0); + field_def.offset+=type_size (field_def.type->t.array.type); + } + } else { + defs[i].emit (&field_def, data, 0); + } + } + } + return struct_def; +} diff --git a/tools/qfcc/source/stub.c b/tools/qfcc/source/stub.c index c9030bb4c..a7f581901 100644 --- a/tools/qfcc/source/stub.c +++ b/tools/qfcc/source/stub.c @@ -22,7 +22,6 @@ int num_linenos; pr_lineno_t *linenos; pr_info_t pr; defspace_t *new_defspace (void) {return 0;} -scope_t *new_scope (scope_type type, defspace_t *space, scope_t *parent) {return 0;} string_t ReuseString (const char *str) {return 0;} void encode_type (struct dstring_s *str, type_t *type) {} codespace_t *codespace_new (void) {return 0;} diff --git a/tools/qfcc/source/switch.c b/tools/qfcc/source/switch.c index 58b4b059e..849fe195d 100644 --- a/tools/qfcc/source/switch.c +++ b/tools/qfcc/source/switch.c @@ -311,8 +311,8 @@ build_switch (expr_t *sw, case_node_t *tree, int op, expr_t *sw_val, range = fold_constants (range); //FIXME unsigned int better? - def = get_def (array_type (&type_integer, high - low + 1), name, - pr.scope, st_static); + def = make_symbol (name, array_type (&type_integer, high - low + 1), + pr.near_data, st_static)->s.def; table = 0;//FIXME new_def_expr (def); if (tree->left) { @@ -334,7 +334,7 @@ build_switch (expr_t *sw, case_node_t *tree, int op, expr_t *sw_val, build_switch (sw, tree->right, op, sw_val, temp, default_label); } for (i = 0; i <= high - low; i++) { - reloc_def_op (&tree->labels[i]->e.label, def->ofs + i); + reloc_def_op (&tree->labels[i]->e.label, def->offset + i); } } } diff --git a/tools/qfcc/source/symtab.c b/tools/qfcc/source/symtab.c index 286aa8dd3..224137fa8 100644 --- a/tools/qfcc/source/symtab.c +++ b/tools/qfcc/source/symtab.c @@ -5,6 +5,7 @@ #include "class.h" #include "def.h" +#include "defspace.h" #include "function.h" #include "qfcc.h" #include "symtab.h" @@ -141,3 +142,26 @@ symtab_flat_copy (symtab_t *symtab, symtab_t *parent) newtab->symtail = symbol ? &symbol->next : &newtab->symbols; return newtab; } + +symbol_t * +make_symbol (const char *name, type_t *type, defspace_t *space, + storage_class_t storage) +{ + symbol_t *sym; + + sym = symtab_lookup (pr.symtab, name); + if (!sym) { + sym = new_symbol_type (name, type); + } + if (sym->type != type) { + error (0, "%s redefined", name); + sym = new_symbol_type (name, type); + } + if (sym->s.def && sym->s.def->external && !storage != st_extern) { + free_def (sym->s.def); + sym->s.def = 0; + } + if (!sym->s.def) + sym->s.def = new_def (name, type, space, storage); + return sym; +}