mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-08 10:21:40 +00:00
[qfcc] Handle type expressions when merging specifiers
The type expressions no longer get lost along the way to the function return type and parameter types.
This commit is contained in:
parent
aff70aa243
commit
1567f29668
3 changed files with 48 additions and 19 deletions
|
@ -136,16 +136,18 @@ extern function_t *current_func;
|
|||
typedef struct param_s {
|
||||
struct param_s *next;
|
||||
const char *selector;
|
||||
const struct type_s *type;
|
||||
const type_t *type;
|
||||
const expr_t *type_expr;
|
||||
const char *name;
|
||||
} param_t;
|
||||
|
||||
struct expr_s;
|
||||
struct symbol_s;
|
||||
struct symtab_s;
|
||||
typedef struct expr_s expr_t;
|
||||
typedef struct symbol_s symbol_t;
|
||||
typedef struct symtab_s symtab_t;
|
||||
|
||||
param_t *new_param (const char *selector, const struct type_s *type,
|
||||
const char *name);
|
||||
param_t *new_generic_param (const expr_t *type_expr, const char *name);
|
||||
param_t *param_append_identifiers (param_t *params, struct symbol_s *idents,
|
||||
const struct type_s *type);
|
||||
param_t *reverse_params (param_t *params);
|
||||
|
|
|
@ -98,11 +98,24 @@ new_param (const char *selector, const type_t *type, const char *name)
|
|||
param_t *param;
|
||||
|
||||
ALLOC (4096, param_t, params, param);
|
||||
param->next = 0;
|
||||
param->selector = selector;
|
||||
param->type = find_type (type);
|
||||
param->name = name;
|
||||
*param = (param_t) {
|
||||
.selector = selector,
|
||||
.type = find_type (type),
|
||||
.name = name,
|
||||
};
|
||||
return param;
|
||||
}
|
||||
|
||||
param_t *
|
||||
new_generic_param (const expr_t *type_expr, const char *name)
|
||||
{
|
||||
param_t *param;
|
||||
|
||||
ALLOC (4096, param_t, params, param);
|
||||
*param = (param_t) {
|
||||
.type_expr = type_expr,
|
||||
.name = name,
|
||||
};
|
||||
return param;
|
||||
}
|
||||
|
||||
|
|
|
@ -285,15 +285,22 @@ storage_auto (specifier_t spec)
|
|||
return spec.storage == sc_global || spec.storage == sc_local;
|
||||
}
|
||||
|
||||
static bool
|
||||
spec_type (specifier_t spec)
|
||||
{
|
||||
return spec.type || spec.type_expr;
|
||||
}
|
||||
|
||||
static specifier_t
|
||||
spec_merge (specifier_t spec, specifier_t new)
|
||||
{
|
||||
if (new.type) {
|
||||
if (spec_type (new)) {
|
||||
// deal with "type <type_name>"
|
||||
if (!spec.type || new.sym) {
|
||||
if (!spec_type (spec) || new.sym) {
|
||||
spec.sym = new.sym;
|
||||
if (!spec.type) {
|
||||
if (!spec_type (spec)) {
|
||||
spec.type = new.type;
|
||||
spec.type_expr = new.type_expr;
|
||||
}
|
||||
} else if (!spec.multi_type) {
|
||||
error (0, "two or more data types in declaration specifiers");
|
||||
|
@ -419,13 +426,14 @@ static param_t *
|
|||
make_param (specifier_t spec)
|
||||
{
|
||||
if (spec.type_expr) {
|
||||
if (!(spec.type = resolve_type (spec.type_expr))) {
|
||||
}
|
||||
auto param = new_generic_param (spec.type_expr, spec.sym->name);
|
||||
return param;
|
||||
} else {
|
||||
spec = default_type (spec, spec.sym);
|
||||
spec.type = find_type (append_type (spec.sym->type, spec.type));
|
||||
auto param = new_param (0, spec.type, spec.sym->name);
|
||||
return param;
|
||||
}
|
||||
spec = default_type (spec, spec.sym);
|
||||
spec.type = find_type (append_type (spec.sym->type, spec.type));
|
||||
param_t *param = new_param (0, spec.type, spec.sym->name);
|
||||
return param;
|
||||
}
|
||||
|
||||
static param_t *
|
||||
|
@ -922,8 +930,14 @@ typespec_reserved
|
|||
: TYPE_SPEC
|
||||
| type_function
|
||||
{
|
||||
auto type = resolve_type ($1);
|
||||
$$ = make_spec (type, 0, 0, 0);
|
||||
if (generic_scope) {
|
||||
$$ = (specifier_t) {
|
||||
.type_expr = $1,
|
||||
};
|
||||
} else {
|
||||
auto type = resolve_type ($1);
|
||||
$$ = make_spec (type, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
| algebra_specifier %prec LOW
|
||||
| algebra_specifier '.' attribute
|
||||
|
|
Loading…
Reference in a new issue