mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-07 01:42:04 +00:00
[qfcc] Move ruamoko attribute parsing out of the parser
Makes for better separation of variable and function attributes.
This commit is contained in:
parent
11f8992710
commit
0dfe81bce8
6 changed files with 38 additions and 34 deletions
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue