Get function def creation working again.

This commit is contained in:
Bill Currie 2011-01-26 14:48:22 +09:00
parent 5231e8e9f8
commit 36c99a8da1
6 changed files with 74 additions and 27 deletions

View file

@ -70,6 +70,8 @@ typedef enum storage_class_e {
st_local
} storage_class_t;
extern storage_class_t current_storage;
def_t *new_def (const char *name, struct type_s *type,
struct defspace_s *space, storage_class_t storage);
def_t *alias_def (def_t *def, struct type_s *type);

View file

@ -56,6 +56,7 @@ typedef struct function_s {
int function_num;
string_t s_file; ///< source file with definition
string_t s_name;
struct def_s *def;
struct symbol_s *sym;
struct symtab_s *symtab;
struct reloc_s *refs;
@ -87,6 +88,10 @@ param_t *_reverse_params (param_t *params, param_t *next);
param_t *reverse_params (param_t *params);
param_t *copy_params (param_t *params);
struct type_s *parse_params (struct type_s *type, param_t *params);
enum storage_class_e;
void make_function (struct symbol_s *sym, const char *nice_name,
enum storage_class_e storage);
struct symbol_s *function_symbol (struct symbol_s *sym,
int overload, int create);
struct expr_s *find_function (struct expr_s *fexpr, struct expr_s *params);

View file

@ -71,9 +71,21 @@ get_operand_def (operand_t *op)
return 0;
switch (op->op_type) {
case op_symbol:
if (op->type != op->o.symbol->type->type)
return alias_def (op->o.symbol->s.def, ev_types[op->type]);
return op->o.symbol->s.def;
switch (op->o.symbol->sy_type) {
case sy_var:
if (op->type != op->o.symbol->type->type)
return alias_def (op->o.symbol->s.def,
ev_types[op->type]);
return op->o.symbol->s.def;
case sy_func:
return op->o.symbol->s.func->def;
case sy_const:
//FIXME
case sy_type:
case sy_expr:
internal_error (0, "invalid operand type");
}
break;
case op_value:
//FIXME share immediates
def = new_def (".imm", ev_types[op->type], pr.near_data,

View file

@ -465,6 +465,27 @@ new_function (const char *name, const char *nice_name)
return f;
}
void
make_function (symbol_t *sym, const char *nice_name, storage_class_t storage)
{
if (sym->sy_type != sy_func)
internal_error (0, "%s is not a function", sym->name);
if (storage == st_extern && sym->s.func)
return;
if (!sym->s.func) {
sym->s.func = new_function (sym->name, nice_name);
sym->s.func->sym = sym;
}
if (sym->s.func->def && sym->s.func->def->external
&& storage != st_extern) {
free_def (sym->s.func->def);
sym->s.func->def = 0;
}
if (!sym->s.func->def)
sym->s.func->def = new_def (sym->name, sym->type, sym->table->space,
storage);
}
void
add_function (function_t *f)
{
@ -482,29 +503,30 @@ begin_function (symbol_t *sym, const char *nicename, symtab_t *parent)
error (0, "%s is not a function", sym->name);
return 0;
}
if (sym->s.func) {
if (sym->s.func && sym->s.func->def && sym->s.func->def->initialized) {
error (0, "%s redefined", sym->name);
return 0;
}
sym->s.func = new_function (sym->name, nicename);
sym->s.func->sym = sym;
//FIXME
//if (!def->external) {
make_function (sym, nicename, current_storage);
if (!sym->s.func->def->external) {
sym->s.func->def->initialized = 1;
sym->s.func->def->constant = 1;
sym->s.func->def->nosave = 1;
add_function (sym->s.func);
//reloc_def_func (func, def->ofs);
//}
sym->s.func->code = pr.code->size;
#if 0 //FIXME
if (options.code.debug && func->aux) {
pr_lineno_t *lineno = new_lineno ();
func->aux->source_line = def->line;
func->aux->line_info = lineno - pr.linenos;
func->aux->local_defs = pr.num_locals;
func->aux->return_type = def->type->t.func.type->type;
lineno->fa.func = func->aux - pr.auxfunctions;
reloc_def_func (sym->s.func, sym->s.func->def->offset);
}
#endif
sym->s.func->code = pr.code->size;
if (options.code.debug && sym->s.func->aux) {
pr_lineno_t *lineno = new_lineno ();
sym->s.func->aux->source_line = sym->s.func->def->line;
sym->s.func->aux->line_info = lineno - pr.linenos;
sym->s.func->aux->local_defs = pr.num_locals;
sym->s.func->aux->return_type = sym->type->t.func.type->type;
lineno->fa.func = sym->s.func->aux - pr.auxfunctions;
}
build_scope (sym, parent);
return sym->s.func;
}
@ -531,7 +553,7 @@ build_builtin_function (symbol_t *sym, expr_t *bi_val)
error (bi_val, "%s is not a function", sym->name);
return 0;
}
if (sym->s.func) {
if (sym->s.func && sym->s.func->def && sym->s.func->def->initialized) {
error (bi_val, "%s redefined", sym->name);
return 0;
}
@ -539,11 +561,10 @@ build_builtin_function (symbol_t *sym, expr_t *bi_val)
error (bi_val, "invalid constant for = #");
return 0;
}
//if (sym->external)
// return 0;
make_function (sym, 0, current_storage);
if (sym->s.func->def->external)
return 0;
sym->s.func = new_function (sym->name, 0);
sym->s.func->sym = sym;
add_function (sym->s.func);
if (is_integer_val (bi_val))
@ -551,7 +572,7 @@ build_builtin_function (symbol_t *sym, expr_t *bi_val)
else
bi = expr_float (bi_val);
sym->s.func->builtin = bi;
//reloc_def_func (sym->s.func, def->ofs);
reloc_def_func (sym->s.func, sym->s.func->def->offset);
build_function (sym->s.func);
finish_function (sym->s.func);

View file

@ -284,6 +284,9 @@ simple_def
cfunction
: cfunction_def ';'
{
make_function ($1, 0, st_extern);// FIME do I really want this?
}
| cfunction_def '=' '#' fexpr ';'
{
build_builtin_function ($1, $4);
@ -584,6 +587,9 @@ non_code_func
build_builtin_function ($<symbol>0, $3);
}
| /* emtpy */
{
make_function ($<symbol>0, 0, current_storage);
}
;
code_func

View file

@ -136,6 +136,7 @@ int yylex (void);
%{
symtab_t *current_symtab;
storage_class_t current_storage = st_global;
function_t *current_func;
struct class_type_s *current_class;
expr_t *local_expr;