mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
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:
parent
ce02fe8660
commit
afc5b2827d
28 changed files with 805 additions and 800 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
///@}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
147
tools/qfcc/source/obj_stub.c
Normal file
147
tools/qfcc/source/obj_stub.c
Normal 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)
|
||||
{
|
||||
}
|
|
@ -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 ();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue