[qfcc] Move ruamoko attribute parsing out of the parser

Makes for better separation of variable and function attributes.
This commit is contained in:
Bill Currie 2024-11-22 14:15:08 +09:00
parent 11f8992710
commit 0dfe81bce8
6 changed files with 38 additions and 34 deletions

View file

@ -81,9 +81,6 @@ typedef struct specifier_s {
bool is_generic:1;
bool is_generic_block:1;
bool is_function:1;//FIXME do proper void(*)() -> ev_func
bool nosave:1;
bool no_va_list:1;
bool void_return:1;
};
unsigned spec_bits;
};

View file

@ -161,7 +161,6 @@ void chain_type (type_t *type);
level.
*/
const type_t *append_type (const type_t *type, const type_t *new);
void set_func_type_attrs (const type_t *func, specifier_t spec);
specifier_t default_type (specifier_t spec, const struct symbol_s *sym);
const type_t *find_type (const type_t *new);
void new_typedef (const char *name, type_t *type);

View file

@ -46,6 +46,7 @@
#include "QF/va.h"
#include "tools/qfcc/include/qfcc.h"
#include "tools/qfcc/include/attribute.h"
#include "tools/qfcc/include/class.h"
#include "tools/qfcc/include/def.h"
#include "tools/qfcc/include/defspace.h"
@ -681,6 +682,18 @@ initialize_def (symbol_t *sym, const expr_t *init, defspace_t *space,
sym->def->initializer = init;
}
static void
set_def_attributes (def_t *def, attribute_t *attr_list)
{
for (attribute_t *attr = attr_list; attr; attr = attr->next) {
if (!strcmp (attr->name, "nosave")) {
def->nosave = true;
} else {
warning (0, "skipping unknown attribute '%s'", attr->name);
}
}
}
void
declare_def (specifier_t spec, const expr_t *init, symtab_t *symtab,
expr_t *block)
@ -693,9 +706,7 @@ declare_def (specifier_t spec, const expr_t *init, symtab_t *symtab,
}
initialize_def (sym, init, space, spec.storage, symtab, block);
if (sym->def) {
sym->def->nosave |= spec.nosave;
}
set_def_attributes (sym->def, spec.attributes);
}
static int

View file

@ -46,6 +46,7 @@
#include "tools/qfcc/include/qfcc.h"
#include "tools/qfcc/include/attribute.h"
#include "tools/qfcc/include/class.h"
#include "tools/qfcc/include/codespace.h"
#include "tools/qfcc/include/debug.h"
@ -581,6 +582,21 @@ get_function (const char *name, const type_t *type, specifier_t spec)
return func;
}
static void
set_func_type_attrs (const type_t *func_type, attribute_t *attr_list)
{
auto func = &((type_t *) func_type)->func;//FIXME
for (auto attr = attr_list; attr; attr = attr->next) {
if (!strcmp (attr->name, "no_va_list")) {
func->no_va_list = true;
} else if (!strcmp (attr->name, "void_return")) {
func->void_return = true;
} else {
warning (0, "skipping unknown function attribute '%s'", attr->name);
}
}
}
symbol_t *
function_symbol (specifier_t spec)
{
@ -611,7 +627,7 @@ function_symbol (specifier_t spec)
if (!spec.sym->type || !spec.sym->type->encoding) {
spec = default_type (spec, spec.sym);
spec.sym->type = append_type (spec.sym->type, spec.type);
set_func_type_attrs (spec.sym->type, spec);
set_func_type_attrs (spec.sym->type, spec.attributes);
spec.sym->type = find_type (spec.sym->type);
}
func = get_function (name, unalias_type (sym->type), spec);

View file

@ -319,24 +319,6 @@ generic_spec (void)
return spec;
}
static specifier_t
parse_attributes (attribute_t *attr_list)
{
specifier_t spec = {};
for (attribute_t *attr = attr_list; attr; attr = attr->next) {
if (!strcmp (attr->name, "no_va_list")) {
spec.no_va_list = true;
} else if (!strcmp (attr->name, "nosave")) {
spec.nosave = true;
} else if (!strcmp (attr->name, "void_return")) {
spec.void_return = true;
} else {
warning (0, "skipping unknown attribute '%s'", attr->name);
}
}
return spec;
}
static int
storage_auto (specifier_t spec)
{
@ -392,6 +374,12 @@ spec_merge (specifier_t spec, specifier_t new)
spec.multi_store = true;
}
}
for (auto attr = &spec.attributes; *attr; attr = &(*attr)->next) {
if (!(*attr)->next) {
(*attr)->next = new.attributes;
break;
}
}
spec.sym = new.sym;
spec.spec_bits |= new.spec_bits;
return spec;
@ -1205,7 +1193,7 @@ storage_class
}
| ATTRIBUTE '(' attribute_list ')'
{
$$ = parse_attributes ($3);
$$ = (specifier_t) { .attributes = $3 };
}
;

View file

@ -496,13 +496,6 @@ append_type (const type_t *type, const type_t *new)
return type;
}
void
set_func_type_attrs (const type_t *func, specifier_t spec)
{
((type_t *) func)->func.no_va_list = spec.no_va_list;//FIXME
((type_t *) func)->func.void_return = spec.void_return;
}
specifier_t
default_type (specifier_t spec, const symbol_t *sym)
{