Simplify def handling, use far data.

Since there is now a proper symbol table, defs are now just references to
memory locations and the symbol table takes care of duplicates.

Also, start using far data for ObjQC structures.

The qfo functions have been stubbed out until I figure out what to do with
object files in the new scheme.
This commit is contained in:
Bill Currie 2011-01-24 15:41:43 +09:00
parent ce02fe8660
commit afc5b2827d
28 changed files with 805 additions and 800 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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 {

View file

@ -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);

View file

@ -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);
///@}

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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);

View file

@ -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)

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -0,0 +1,147 @@
/*
obj_file.c
qfcc object file support
Copyright (C) 2002 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
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 <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <stdlib.h>
#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)
{
}

View file

@ -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 ();

View file

@ -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;

View file

@ -49,6 +49,7 @@ static __attribute__ ((used)) const char rcsid[] =
#include <QF/va.h>
#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;
}

View file

@ -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;}

View file

@ -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);
}
}
}

View file

@ -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;
}