start implementing storage classes (extern, static, etc)

This commit is contained in:
Bill Currie 2002-06-28 17:59:32 +00:00
parent a49177c605
commit 66aa36b73f
13 changed files with 68 additions and 43 deletions

View file

@ -47,9 +47,10 @@ typedef struct def_s {
unsigned freed:1; // already freed from the scope
unsigned removed:1; // already removed from the symbol table
unsigned used:1; // unused local detection
unsigned global:1; // globally declared def
unsigned absolute:1; // don't relocate (for temps for shorts)
unsigned managed:1; // managed temp
unsigned global:1; // globally declared def
unsigned external:1; // externally declared def
string_t file; // source file
int line; // source line
@ -93,6 +94,14 @@ typedef struct scope_s {
struct scope_s *parent;
} scope_t;
typedef enum {
st_none,
st_global,
st_extern,
st_static,
st_local
} storage_class_t;
extern def_t def_ret, def_parms[MAX_PARMS];
extern def_t def_void;
extern def_t def_function;
@ -101,7 +110,7 @@ scope_t *new_scope (scope_type type, defspace_t *space, scope_t *parent);
defspace_t *new_defspace (void);
def_t *get_def (struct type_s *type, const char *name, scope_t *scope,
int allocate);
storage_class_t storage);
def_t *new_def (struct type_s *type, const char *name, scope_t *scope);
int new_location (struct type_s *type, defspace_t *space);
void free_location (def_t *def);

View file

@ -67,8 +67,9 @@ typedef struct qfo_def_s {
#define QFOD_INITIALIZED (1u<<0)
#define QFOD_CONSTANT (1u<<1)
#define QFOD_GLOBAL (1u<<2)
#define QFOD_ABSOLUTE (1u<<3)
#define QFOD_ABSOLUTE (1u<<2)
#define QFOD_GLOBAL (1u<<3)
#define QFOD_EXTERNAL (1u<<4)
typedef struct qfo_function_s {
string_t name;

View file

@ -161,7 +161,7 @@ class_begin (class_t *class)
va ("_OBJ_CATEGORY_%s_%s",
class->class_name,
class->category_name),
pr.scope, 1);
pr.scope, st_static);
class->def->initialized = class->def->constant = 1;
category = &G_STRUCT (pr_category_t, class->def->ofs);
category->category_name = ReuseString (class->category_name);
@ -177,7 +177,7 @@ class_begin (class_t *class)
meta_def = get_def (type_Class.aux_type,
va ("_OBJ_METACLASS_%s", class->class_name),
pr.scope, 1);
pr.scope, st_static);
meta_def->initialized = meta_def->constant = 1;
meta = &G_STRUCT (pr_class_t, meta_def->ofs);
meta->class_pointer = ReuseString (class->class_name);
@ -192,7 +192,7 @@ class_begin (class_t *class)
class->def = get_def (type_Class.aux_type,
va ("_OBJ_CLASS_%s", class->class_name),
pr.scope, 1);
pr.scope, st_static);
class->def->initialized = class->def->constant = 1;
cls = &G_STRUCT (pr_class_t, class->def->ofs);
cls->class_pointer = meta_def->ofs;
@ -400,7 +400,7 @@ class_def (class_t *class)
def = get_def (class->type,
va ("_OBJ_CLASS_POINTER_%s", class->class_name),
pr.scope, 1);
pr.scope, st_static);
if (def->initialized)
return def;
if (class->def) { //FIXME need externals?
@ -453,7 +453,7 @@ class_finish_module (void)
new_struct_field (symtab_type, &type_integer, "cat_def_cnt", vis_public);
for (i = 0; i < num_classes + num_categories; i++)
new_struct_field (symtab_type, &type_pointer, 0, vis_public);
symtab_def = get_def (symtab_type, "_OBJ_SYMTAB", pr.scope, 1);
symtab_def = get_def (symtab_type, "_OBJ_SYMTAB", pr.scope, st_static);
symtab_def->initialized = symtab_def->constant = 1;
symtab = &G_STRUCT (pr_symtab_t, symtab_def->ofs);
symtab->cls_def_cnt = num_classes;
@ -466,7 +466,7 @@ class_finish_module (void)
if ((*t)->def)
*def_ptr++ = (*t)->def->ofs;
module_def = get_def (type_module, "_OBJ_MODULE", pr.scope, 1);
module_def = get_def (type_module, "_OBJ_MODULE", pr.scope, st_static);
module_def->initialized = module_def->constant = 1;
module = &G_STRUCT (pr_module_t, module_def->ofs);
module->size = type_size (type_module);
@ -474,7 +474,7 @@ class_finish_module (void)
module->symtab = symtab_def->ofs;
exec_class_def = get_def (&type_obj_exec_class, "__obj_exec_class",
pr.scope, 1);
pr.scope, st_static);
exec_class_func = new_function ("__obj_exec_class");
exec_class_func->builtin = 0;
exec_class_func->def = exec_class_def;
@ -482,7 +482,7 @@ class_finish_module (void)
build_function (exec_class_func);
finish_function (exec_class_func);
init_def = get_def (&type_function, ".ctor", pr.scope, 1);
init_def = get_def (&type_function, ".ctor", pr.scope, st_static);
init_func = new_function (".ctor");
init_func->def = init_def;
init_func->refs = new_reloc (init_def->ofs, rel_def_func);
@ -548,7 +548,7 @@ protocol_add_protocol_methods (protocol_t *protocol, expr_t *protocols)
def_t *
protocol_def (protocol_t *protocol)
{
return get_def (&type_Protocol, protocol->name, pr.scope, 1);
return get_def (&type_Protocol, protocol->name, pr.scope, st_static);
}
protocollist_t *
@ -578,7 +578,7 @@ emit_protocol (protocol_t *protocol)
proto_def = get_def (type_Protocol.aux_type,
va ("_OBJ_PROTOCOL_%s", protocol->name),
pr.scope, 1);
pr.scope, st_static);
proto_def->initialized = proto_def->constant = 1;
proto = &G_STRUCT (pr_protocol_t, proto_def->ofs);
proto->class_pointer = 0;
@ -609,7 +609,7 @@ emit_protocol_list (protocollist_t *protocols, const char *name)
new_struct_field (protocol_list, &type_pointer, 0, vis_public);
proto_list_def = get_def (type_Protocol.aux_type,
va ("_OBJ_PROTOCOLS_%s", name),
pr.scope, 1);
pr.scope, st_static);
proto_list_def->initialized = proto_list_def->constant = 1;
proto_list = &G_STRUCT (pr_protocol_list_t, proto_list_def->ofs);
proto_list->next = 0;

View file

@ -73,7 +73,8 @@ defs_get_key (void *_def, void *_tab)
}
static def_t *
check_for_name (type_t *type, const char *name, scope_t *scope, int allocate)
check_for_name (type_t *type, const char *name, scope_t *scope,
storage_class_t storage)
{
def_t *def;
@ -89,10 +90,10 @@ check_for_name (type_t *type, const char *name, scope_t *scope, int allocate)
// see if the name is already in use
def = (def_t *) Hash_Find (defs_by_name, name);
if (def) {
if (allocate && scope == def->scope)
if (storage != st_none && scope == def->scope)
if (type && def->type != type)
error (0, "Type mismatch on redeclaration of %s", name);
if (!allocate || def->scope == scope)
if (storage == st_none || def->scope == scope)
return def;
}
return 0;
@ -166,11 +167,12 @@ vector_field_component (def_t *vec, int comp, scope_t *scope)
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, int allocate)
get_def (type_t *type, const char *name, scope_t *scope,
storage_class_t storage)
{
def_t *def = check_for_name (type, name, scope, allocate);
def_t *def = check_for_name (type, name, scope, storage);
if (def || !allocate)
if (def || storage == st_none)
return def;
// allocate a new def

View file

@ -141,7 +141,7 @@ convert_name (expr_t *e)
e->e.def = class_def (class);
return;
}
d = get_def (NULL, name, current_scope, 0);
d = get_def (NULL, name, current_scope, st_none);
if (d) {
if (d->global) {
new = class_ivar_expr (current_class, name);
@ -520,7 +520,7 @@ new_def_expr (def_t *def)
expr_t *
new_self_expr (void)
{
def_t *def = get_def (&type_entity, ".self", pr.scope, 1);
def_t *def = get_def (&type_entity, ".self", pr.scope, st_global);
def_initialized (def);
return new_def_expr (def);
@ -530,7 +530,7 @@ expr_t *
new_this_expr (void)
{
type_t *type = field_type (&type_id);
def_t *def = get_def (type, ".this", pr.scope, 1);
def_t *def = get_def (type, ".this", pr.scope, st_global);
def_initialized (def);
return new_def_expr (def);

View file

@ -132,10 +132,10 @@ build_scope (function_t *f, def_t *func, param_t *params)
f->scope = new_scope (sc_params, new_defspace (), pr.scope);
if (func->type->num_parms < 0) {
def = get_def (&type_integer, ".argc", f->scope, 1);
def = get_def (&type_integer, ".argc", f->scope, st_local);
def->used = 1;
def_initialized (def);
argv = get_def (&type_pointer, ".argv", f->scope, 1);
argv = get_def (&type_pointer, ".argv", f->scope, st_local);
argv->used = 1;
def_initialized (argv);
}
@ -145,7 +145,7 @@ build_scope (function_t *f, def_t *func, param_t *params)
continue; // ellipsis marker
if (!p->type)
continue; // non-param selector
def = get_def (p->type, p->name, f->scope, 1);
def = get_def (p->type, p->name, f->scope, st_local);
parm_ofs[i] = def->ofs;
if (i > 0 && parm_ofs[i] < parm_ofs[i - 1]) {
error (0, "bad parm order");
@ -159,7 +159,7 @@ build_scope (function_t *f, def_t *func, param_t *params)
if (argv) {
while (i < MAX_PARMS) {
def = get_def (&type_vector, 0, f->scope, 1);
def = get_def (&type_vector, 0, f->scope, st_local);
def->used = 1;
if (argv->type == &type_pointer)
argv->type = array_type (&type_vector, MAX_PARMS - i);

View file

@ -121,8 +121,7 @@ method_def (class_t *class, method_t *method)
if (*s == ':')
*s = '_';
//printf ("%s %s %s %ld\n", method->name, method->types, str->str, str->size);
// FIXME need a file scope
def = get_def (method->type, str->str, pr.scope, 1);
def = get_def (method->type, str->str, pr.scope, st_static);
dstring_delete (str);
return def;
}
@ -175,7 +174,7 @@ make_message_def (const char *name, def_t **def)
expr_t *zero = new_expr ();
zero->type = ex_integer;
*def = get_def (&type_IMP, name, pr.scope, 1);
*def = get_def (&type_IMP, name, pr.scope, st_static);
build_builtin_function (*def, zero);
}
@ -298,7 +297,7 @@ emit_methods (methodlist_t *_methods, const char *name, int instance)
for (i = 0; i < count; i++)
new_struct_field (method_list, type_Method.aux_type, 0, vis_public);
methods_def = get_def (method_list, va ("_OBJ_%s_METHODS_%s", type, name),
pr.scope, 1);
pr.scope, st_static);
methods_def->initialized = methods_def->constant = 1;
methods = &G_STRUCT (pr_method_list_t, methods_def->ofs);
methods->method_next = 0;

View file

@ -119,10 +119,12 @@ flags (def_t *d)
flags |= QFOD_INITIALIZED;
if (d->constant)
flags |= QFOD_CONSTANT;
if (d->global)
flags |= QFOD_GLOBAL;
if (d->absolute)
flags |= QFOD_ABSOLUTE;
if (d->global)
flags |= QFOD_GLOBAL;
if (d->external)
flags |= QFOD_EXTERNAL;
return flags;
}

View file

@ -299,6 +299,8 @@ static keyword_t keywords[] = {
{"@this", THIS, 0, 0, PROG_VERSION},
{"@argc", ARGC, 0, 0, PROG_VERSION},
{"@argv", ARGV, 0, 0, PROG_VERSION},
{"@extern", EXTERN, 0, 0, PROG_VERSION},
{"@static", STATIC, 0, 0, PROG_VERSION},
};
static const char *

View file

@ -128,7 +128,7 @@ void free_local_inits (hashtab_t *def_list);
%token LOCAL RETURN WHILE DO IF ELSE FOR BREAK CONTINUE ELLIPSIS NIL
%token IFBE IFB IFAE IFA
%token SWITCH CASE DEFAULT STRUCT UNION ENUM TYPEDEF SUPER SELF THIS
%token ARGC ARGV
%token ARGC ARGV EXTERN STATIC
%token ELE_START
%token <type> TYPE
@ -179,6 +179,7 @@ type_t *struct_type;
visibility_t current_visibility;
type_t *current_ivars;
scope_t *current_scope;
storage_class_t current_storage;
string_t s_file; // filename for function definition
@ -195,7 +196,7 @@ defs
;
def
: type { current_type = $1; } def_list
: storage_class type { current_type = $2; } def_list
| STRUCT NAME
{ struct_type = new_struct ($2); } '=' '{' struct_defs '}'
| UNION NAME
@ -211,6 +212,12 @@ def
}
;
storage_class
: /* empty */ { current_storage = st_global; }
| EXTERN { current_storage = st_extern; }
| STATIC { current_storage = st_static; }
;
struct_defs
: /* empty */
| struct_defs struct_def ';'
@ -356,13 +363,13 @@ def_name
{
if (current_scope->type == sc_local
&& current_scope->parent->type == sc_params) {
def_t *def = get_def (0, $1, current_scope, 0);
def_t *def = get_def (0, $1, current_scope, st_none);
if (def) {
if (def->scope->type == sc_params)
warning (0, "local %s shadows param %s", $1, def->name);
}
}
$$ = get_def (current_type, $1, current_scope, 1);
$$ = get_def (current_type, $1, current_scope, current_storage);
current_def = $$;
}
;
@ -628,6 +635,7 @@ statement
}
| LOCAL type
{
current_storage = st_local;
current_type = $2;
local_expr = new_block_expr ();
}

View file

@ -373,7 +373,8 @@ finish_compilation (void)
if (options.code.debug) {
e.type = ex_string;
e.e.string_val = debugfile;
ReuseConstant (&e, get_def (&type_string, ".debug_file", pr.scope, 1));
ReuseConstant (&e, get_def (&type_string, ".debug_file", pr.scope,
st_static));
}
for (def = pr.scope->head; def; def = def->def_next) {

View file

@ -223,10 +223,10 @@ emit_struct(type_t *strct, const char *name)
for (i = 0; i < count; i++)
new_struct_field (ivar_list, type_ivar, 0, vis_public);
dsprintf (ivars_name, "_OBJ_INSTANCE_VARIABLES_%s", name);
ivars_def = get_def (ivar_list, ivars_name->str, pr.scope, 0);
ivars_def = get_def (ivar_list, ivars_name->str, pr.scope, st_none);
if (ivars_def)
goto done;
ivars_def = get_def (ivar_list, ivars_name->str, pr.scope, 1);
ivars_def = get_def (ivar_list, ivars_name->str, pr.scope, st_static);
ivars_def->initialized = ivars_def->constant = 1;
ivars = &G_STRUCT (pr_ivar_list_t, ivars_def->ofs);
ivars->ivar_count = count;
@ -280,7 +280,7 @@ process_enum (expr_t *enm)
}
if ((structs && find_struct (name->e.string_val))
|| get_enum (name->e.string_val)
|| get_def (NULL, name->e.string_val, pr.scope, 0)) {
|| get_def (NULL, name->e.string_val, pr.scope, st_none)) {
error (name, "%s redeclared", name->e.string_val);
continue;
}

View file

@ -298,7 +298,8 @@ build_switch (expr_t *sw, case_node_t *tree, int op, expr_t *sw_val,
range->type = ex_uinteger;
def = get_def (array_type (&type_uinteger, high - low + 1), name, pr.scope, 1);
def = get_def (array_type (&type_uinteger, high - low + 1), name,
pr.scope, st_static);
table = new_def_expr (def);
if (tree->left) {