mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-21 01:41:10 +00:00
Implement direct ivar access in methods.
A warning needs to be generated for access to ivars in a class method, but it seems to work (unable to check due to other errors).
This commit is contained in:
parent
3025e04ac5
commit
76034861c9
3 changed files with 47 additions and 17 deletions
|
@ -123,7 +123,11 @@ void class_begin (class_type_t *class_type);
|
|||
void class_finish (class_type_t *class_type);
|
||||
int class_access (class_type_t *current_class, class_t *class);
|
||||
struct symbol_s *class_find_ivar (class_t *class, int vis, const char *name);
|
||||
struct expr_s *class_ivar_expr (class_type_t *class_type, const char *name);
|
||||
struct symtab_s *class_ivar_scope (class_type_t *class_type,
|
||||
struct symtab_s *parent);
|
||||
void class_finish_ivar_scope (class_type_t *class_type,
|
||||
struct symtab_s *ivar_scope,
|
||||
struct symtab_s *param_scope);
|
||||
struct method_s *class_find_method (class_type_t *class_type,
|
||||
struct method_s *method);
|
||||
struct method_s *class_message_response (class_t *class, int class_msg,
|
||||
|
|
|
@ -731,21 +731,6 @@ access_error:
|
|||
return 0;
|
||||
}
|
||||
|
||||
expr_t *
|
||||
class_ivar_expr (class_type_t *class_type, const char *name)
|
||||
{
|
||||
symbol_t *ivar;
|
||||
class_t *class;
|
||||
|
||||
if (!class_type || !(class = extract_class (class_type)))
|
||||
return 0;
|
||||
|
||||
ivar = symtab_lookup (class->ivars, name);
|
||||
if (!ivar)
|
||||
return 0;
|
||||
return binary_expr ('.', new_name_expr ("self"), new_name_expr (name));
|
||||
}
|
||||
|
||||
method_t *
|
||||
class_find_method (class_type_t *class_type, method_t *method)
|
||||
{
|
||||
|
@ -1314,3 +1299,38 @@ class_to_struct (class_t *class, symtab_t *symtab)
|
|||
symtab->parent = parent;
|
||||
return symtab;
|
||||
}
|
||||
|
||||
symtab_t *
|
||||
class_ivar_scope (class_type_t *class_type, symtab_t *parent)
|
||||
{
|
||||
class_t *class = extract_class (class_type);
|
||||
return symtab_flat_copy (class->ivars, parent);
|
||||
}
|
||||
|
||||
void
|
||||
class_finish_ivar_scope (class_type_t *class_type, symtab_t *ivar_scope,
|
||||
symtab_t *param_scope)
|
||||
{
|
||||
class_t *class = extract_class (class_type);
|
||||
type_t *class_ptr = pointer_type (class->type);
|
||||
symbol_t *sym;
|
||||
symbol_t *self;
|
||||
expr_t *self_expr;
|
||||
|
||||
self = symtab_lookup (param_scope, "self");
|
||||
if (!self)
|
||||
internal_error (0, "I've lost my self!");
|
||||
self_expr = new_symbol_expr (self);
|
||||
if (self->type != class_ptr) {
|
||||
debug (0, "class method scope");
|
||||
//FIXME should generate a warning on access
|
||||
self_expr = cast_expr (class_ptr, self_expr);
|
||||
}
|
||||
for (sym = ivar_scope->symbols; sym; sym = sym->next) {
|
||||
if (sym->sy_type != sy_var)
|
||||
continue;
|
||||
sym->sy_type = sy_expr;
|
||||
sym->s.expr = binary_expr ('.', copy_expr (self_expr),
|
||||
new_symbol_expr (new_symbol (sym->name)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1433,8 +1433,14 @@ methoddef
|
|||
method_t *method = $2;
|
||||
const char *nicename = method_name (method);
|
||||
symbol_t *sym = $<symbol>4;
|
||||
symtab_t *ivar_scope;
|
||||
|
||||
$<symtab>$ = current_symtab;
|
||||
current_func = begin_function (sym, nicename, current_symtab);
|
||||
|
||||
ivar_scope = class_ivar_scope (current_class, current_symtab);
|
||||
current_func = begin_function (sym, nicename, ivar_scope);
|
||||
class_finish_ivar_scope (current_class, ivar_scope,
|
||||
current_func->symtab);
|
||||
method->def = sym->s.func->def;
|
||||
current_symtab = current_func->symtab;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue