mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
[qfcc] Implement type aliasing again
When a type is aliased, the alias has two type chains: the simple type chain with all other aliases stripped, and the full type chain. There are still plenty of bugs in it, but having the clean type chain takes care of the major issue that was in the previous attempt as only the head of the type-chain needs to be skipped for type comparison. Most of the bugs are in finding the locations where the head needs to be skipped.
This commit is contained in:
parent
734f10d43e
commit
1eef2a8b5e
12 changed files with 180 additions and 64 deletions
|
@ -52,8 +52,9 @@ typedef enum {
|
||||||
|
|
||||||
typedef struct qfot_alias_s {
|
typedef struct qfot_alias_s {
|
||||||
pr_int_t type; ///< type at end of alias chain
|
pr_int_t type; ///< type at end of alias chain
|
||||||
pointer_t aux_type; ///< referenced type
|
pointer_t aux_type; ///< referenced type: stripped of aliases
|
||||||
string_t name; ///< alias name
|
pointer_t full_type; ///< includes full alias info
|
||||||
|
string_t name; ///< alias name, may be null
|
||||||
} qfot_alias_t;
|
} qfot_alias_t;
|
||||||
|
|
||||||
typedef struct qfot_fldptr_s {
|
typedef struct qfot_fldptr_s {
|
||||||
|
@ -101,7 +102,7 @@ typedef struct qfot_array_s {
|
||||||
*/
|
*/
|
||||||
typedef struct qfot_type_s {
|
typedef struct qfot_type_s {
|
||||||
ty_meta_e meta:32; ///< meta type
|
ty_meta_e meta:32; ///< meta type
|
||||||
pr_int_t size; ///< total word size of this encoding
|
pr_uint_t size; ///< total word size of this encoding
|
||||||
string_t encoding; ///< Objective-QC encoding
|
string_t encoding; ///< Objective-QC encoding
|
||||||
union {
|
union {
|
||||||
etype_t type:32; ///< ty_basic: etype_t
|
etype_t type:32; ///< ty_basic: etype_t
|
||||||
|
|
|
@ -33,6 +33,7 @@ typedef enum {
|
||||||
typedef struct qfot_alias_s {
|
typedef struct qfot_alias_s {
|
||||||
etype_t type;
|
etype_t type;
|
||||||
struct qfot_type_s *aux_type;
|
struct qfot_type_s *aux_type;
|
||||||
|
struct qfot_type_s *full_type;
|
||||||
string name;
|
string name;
|
||||||
} qfot_alias_t;
|
} qfot_alias_t;
|
||||||
|
|
||||||
|
|
|
@ -380,10 +380,11 @@ expr_t *build_block_expr (expr_t *expr_list);
|
||||||
element_t *new_element (expr_t *expr, struct symbol_s *symbol);
|
element_t *new_element (expr_t *expr, struct symbol_s *symbol);
|
||||||
expr_t *new_compound_init (void);
|
expr_t *new_compound_init (void);
|
||||||
expr_t *append_element (expr_t *compound, element_t *element);
|
expr_t *append_element (expr_t *compound, element_t *element);
|
||||||
expr_t *initialized_temp_expr (struct type_s *type, expr_t *compound);
|
expr_t *initialized_temp_expr (const struct type_s *type, expr_t *compound);
|
||||||
void assign_elements (expr_t *local_expr, expr_t *ptr,
|
void assign_elements (expr_t *local_expr, expr_t *ptr,
|
||||||
element_chain_t *element_chain);
|
element_chain_t *element_chain);
|
||||||
void build_element_chain (element_chain_t *element_chain, struct type_s *type,
|
void build_element_chain (element_chain_t *element_chain,
|
||||||
|
const struct type_s *type,
|
||||||
expr_t *eles, int base_offset);
|
expr_t *eles, int base_offset);
|
||||||
void free_element_chain (element_chain_t *element_chain);
|
void free_element_chain (element_chain_t *element_chain);
|
||||||
|
|
||||||
|
@ -433,7 +434,7 @@ expr_t *new_symbol_expr (struct symbol_s *symbol);
|
||||||
\param type The type of the temporary variable.
|
\param type The type of the temporary variable.
|
||||||
\return The new temporary variable expression node (ex_temp_t).
|
\return The new temporary variable expression node (ex_temp_t).
|
||||||
*/
|
*/
|
||||||
expr_t *new_temp_def_expr (struct type_s *type);
|
expr_t *new_temp_def_expr (const struct type_s *type);
|
||||||
|
|
||||||
/** Create a new nil expression node.
|
/** Create a new nil expression node.
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,8 @@ typedef struct ty_array_s {
|
||||||
} ty_array_t;
|
} ty_array_t;
|
||||||
|
|
||||||
typedef struct ty_alias_s {
|
typedef struct ty_alias_s {
|
||||||
struct type_s *type;
|
struct type_s *aux_type; ///< other aliases stripped
|
||||||
|
struct type_s *full_type; ///< full alias chain
|
||||||
} ty_alias_t;
|
} ty_alias_t;
|
||||||
|
|
||||||
typedef struct type_s {
|
typedef struct type_s {
|
||||||
|
@ -148,6 +149,8 @@ type_t *field_type (type_t *aux);
|
||||||
type_t *pointer_type (type_t *aux);
|
type_t *pointer_type (type_t *aux);
|
||||||
type_t *array_type (type_t *aux, int size);
|
type_t *array_type (type_t *aux, int size);
|
||||||
type_t *based_array_type (type_t *aux, int base, int top);
|
type_t *based_array_type (type_t *aux, int base, int top);
|
||||||
|
type_t *alias_type (type_t *type, type_t *alias_chain, const char *name);
|
||||||
|
const type_t *unalias_type (const type_t *type) __attribute__((pure));
|
||||||
void print_type_str (struct dstring_s *str, const type_t *type);
|
void print_type_str (struct dstring_s *str, const type_t *type);
|
||||||
void print_type (const type_t *type);
|
void print_type (const type_t *type);
|
||||||
const char *encode_params (const type_t *type);
|
const char *encode_params (const type_t *type);
|
||||||
|
|
|
@ -580,8 +580,10 @@ dump_qfo_types (qfo_t *qfo, int base_address)
|
||||||
printf (" %-5x\n", type->t.class);
|
printf (" %-5x\n", type->t.class);
|
||||||
break;
|
break;
|
||||||
case ty_alias:
|
case ty_alias:
|
||||||
printf (" %s %d %-5x\n", QFO_GETSTR (qfo, type->t.alias.name),
|
printf (" %s %d %5x %5x\n",
|
||||||
type->t.alias.type, type->t.alias.aux_type);
|
QFO_GETSTR (qfo, type->t.alias.name),
|
||||||
|
type->t.alias.type, type->t.alias.aux_type,
|
||||||
|
type->t.alias.full_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,6 +211,7 @@ convert_vector (expr_t *e)
|
||||||
type_t *
|
type_t *
|
||||||
get_type (expr_t *e)
|
get_type (expr_t *e)
|
||||||
{
|
{
|
||||||
|
const type_t *type = 0;
|
||||||
convert_name (e);
|
convert_name (e);
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
case ex_labelref:
|
case ex_labelref:
|
||||||
|
@ -238,19 +239,23 @@ get_type (expr_t *e)
|
||||||
return &type_void;
|
return &type_void;
|
||||||
case ex_expr:
|
case ex_expr:
|
||||||
case ex_uexpr:
|
case ex_uexpr:
|
||||||
return e->e.expr.type;
|
type = e->e.expr.type;
|
||||||
|
break;
|
||||||
case ex_def:
|
case ex_def:
|
||||||
return e->e.def->type;
|
type = e->e.def->type;
|
||||||
|
break;
|
||||||
case ex_symbol:
|
case ex_symbol:
|
||||||
return e->e.symbol->type;
|
type = e->e.symbol->type;
|
||||||
|
break;
|
||||||
case ex_temp:
|
case ex_temp:
|
||||||
return e->e.temp.type;
|
return e->e.temp.type;
|
||||||
case ex_value:
|
case ex_value:
|
||||||
return e->e.value->type;
|
type = e->e.value->type;
|
||||||
|
break;
|
||||||
case ex_vector:
|
case ex_vector:
|
||||||
return e->e.vector.type;
|
return e->e.vector.type;
|
||||||
}
|
}
|
||||||
return 0;
|
return (type_t *) unalias_type (type);//FIXME cast
|
||||||
}
|
}
|
||||||
|
|
||||||
etype_t
|
etype_t
|
||||||
|
@ -632,12 +637,12 @@ new_symbol_expr (symbol_t *symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_t *
|
expr_t *
|
||||||
new_temp_def_expr (type_t *type)
|
new_temp_def_expr (const type_t *type)
|
||||||
{
|
{
|
||||||
expr_t *e = new_expr ();
|
expr_t *e = new_expr ();
|
||||||
|
|
||||||
e->type = ex_temp;
|
e->type = ex_temp;
|
||||||
e->e.temp.type = type;
|
e->e.temp.type = (type_t *) unalias_type (type); // FIXME cast
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2026,8 +2031,9 @@ goto_expr (expr_t *label)
|
||||||
expr_t *
|
expr_t *
|
||||||
return_expr (function_t *f, expr_t *e)
|
return_expr (function_t *f, expr_t *e)
|
||||||
{
|
{
|
||||||
type_t *t;
|
const type_t *t;
|
||||||
type_t *ret_type = f->sym->type->t.func.type;
|
const type_t *func_type = unalias_type (f->sym->type);
|
||||||
|
const type_t *ret_type = unalias_type (func_type->t.func.type);
|
||||||
|
|
||||||
if (!e) {
|
if (!e) {
|
||||||
if (!is_void(ret_type)) {
|
if (!is_void(ret_type)) {
|
||||||
|
@ -2064,7 +2070,7 @@ return_expr (function_t *f, expr_t *e)
|
||||||
warning (e, "returning a value for a void function");
|
warning (e, "returning a value for a void function");
|
||||||
}
|
}
|
||||||
if (e->type == ex_bool) {
|
if (e->type == ex_bool) {
|
||||||
e = convert_from_bool (e, ret_type);
|
e = convert_from_bool (e, (type_t *) ret_type); //FIXME cast
|
||||||
}
|
}
|
||||||
if (is_float(ret_type) && is_integer_val (e)) {
|
if (is_float(ret_type) && is_integer_val (e)) {
|
||||||
convert_int (e);
|
convert_int (e);
|
||||||
|
@ -2073,7 +2079,7 @@ return_expr (function_t *f, expr_t *e)
|
||||||
if (is_void(t)) {
|
if (is_void(t)) {
|
||||||
if (e->type == ex_nil) {
|
if (e->type == ex_nil) {
|
||||||
t = ret_type;
|
t = ret_type;
|
||||||
convert_nil (e, t);
|
convert_nil (e, (type_t *) t);//FIXME cast
|
||||||
} else {
|
} else {
|
||||||
if (!options.traditional)
|
if (!options.traditional)
|
||||||
return error (e, "void value not ignored as it ought to be");
|
return error (e, "void value not ignored as it ought to be");
|
||||||
|
@ -2091,7 +2097,7 @@ return_expr (function_t *f, expr_t *e)
|
||||||
f->sym->name);
|
f->sym->name);
|
||||||
} else {
|
} else {
|
||||||
if (ret_type != t) {
|
if (ret_type != t) {
|
||||||
e = cast_expr (ret_type, e);
|
e = cast_expr ((type_t *) ret_type, e);//FIXME cast
|
||||||
t = f->sym->type->t.func.type;
|
t = f->sym->type->t.func.type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2621,6 +2627,7 @@ cast_expr (type_t *dstType, expr_t *e)
|
||||||
if (e->type == ex_error)
|
if (e->type == ex_error)
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
|
dstType = (type_t *) unalias_type (dstType); //FIXME cast
|
||||||
srcType = get_type (e);
|
srcType = get_type (e);
|
||||||
|
|
||||||
if (dstType == srcType)
|
if (dstType == srcType)
|
||||||
|
|
|
@ -83,11 +83,13 @@ new_compound_init (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
build_element_chain (element_chain_t *element_chain, type_t *type,
|
build_element_chain (element_chain_t *element_chain, const type_t *type,
|
||||||
expr_t *eles, int base_offset)
|
expr_t *eles, int base_offset)
|
||||||
{
|
{
|
||||||
element_t *ele = eles->e.compound.head;
|
element_t *ele = eles->e.compound.head;
|
||||||
|
|
||||||
|
type = unalias_type (type);
|
||||||
|
|
||||||
if (is_array (type)) {
|
if (is_array (type)) {
|
||||||
type_t *array_type = type->t.array.type;
|
type_t *array_type = type->t.array.type;
|
||||||
int array_size = type->t.array.size;
|
int array_size = type->t.array.size;
|
||||||
|
@ -193,8 +195,9 @@ assign_elements (expr_t *local_expr, expr_t *init,
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_t *
|
expr_t *
|
||||||
initialized_temp_expr (type_t *type, expr_t *compound)
|
initialized_temp_expr (const type_t *type, expr_t *compound)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
element_chain_t element_chain;
|
element_chain_t element_chain;
|
||||||
expr_t *temp = new_temp_def_expr (type);
|
expr_t *temp = new_temp_def_expr (type);
|
||||||
expr_t *block = new_block_expr ();
|
expr_t *block = new_block_expr ();
|
||||||
|
|
|
@ -235,7 +235,7 @@ check_params (param_t *params)
|
||||||
}
|
}
|
||||||
|
|
||||||
static overloaded_function_t *
|
static overloaded_function_t *
|
||||||
get_function (const char *name, type_t *type, int overload, int create)
|
get_function (const char *name, const type_t *type, int overload, int create)
|
||||||
{
|
{
|
||||||
const char *full_name;
|
const char *full_name;
|
||||||
overloaded_function_t *func;
|
overloaded_function_t *func;
|
||||||
|
@ -251,7 +251,7 @@ get_function (const char *name, type_t *type, int overload, int create)
|
||||||
|
|
||||||
func = Hash_Find (overloaded_functions, full_name);
|
func = Hash_Find (overloaded_functions, full_name);
|
||||||
if (func) {
|
if (func) {
|
||||||
if (func->type != type) {
|
if (unalias_type (func->type) != type) {
|
||||||
error (0, "can't overload on return types");
|
error (0, "can't overload on return types");
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
@ -277,7 +277,7 @@ get_function (const char *name, type_t *type, int overload, int create)
|
||||||
func = calloc (1, sizeof (overloaded_function_t));
|
func = calloc (1, sizeof (overloaded_function_t));
|
||||||
func->name = name;
|
func->name = name;
|
||||||
func->full_name = full_name;
|
func->full_name = full_name;
|
||||||
func->type = type;
|
func->type = (type_t *) type; //FIXME cast
|
||||||
func->overloaded = overload;
|
func->overloaded = overload;
|
||||||
func->file = pr.source_file;
|
func->file = pr.source_file;
|
||||||
func->line = pr.source_line;
|
func->line = pr.source_line;
|
||||||
|
@ -294,7 +294,7 @@ function_symbol (symbol_t *sym, int overload, int create)
|
||||||
overloaded_function_t *func;
|
overloaded_function_t *func;
|
||||||
symbol_t *s;
|
symbol_t *s;
|
||||||
|
|
||||||
func = get_function (name, sym->type, overload, create);
|
func = get_function (name, unalias_type (sym->type), overload, create);
|
||||||
|
|
||||||
if (func && func->overloaded)
|
if (func && func->overloaded)
|
||||||
name = func->full_name;
|
name = func->full_name;
|
||||||
|
@ -615,7 +615,8 @@ begin_function (symbol_t *sym, const char *nicename, symtab_t *parent,
|
||||||
static void
|
static void
|
||||||
build_function (symbol_t *fsym)
|
build_function (symbol_t *fsym)
|
||||||
{
|
{
|
||||||
if (fsym->type->t.func.num_params > MAX_PARMS) {
|
const type_t *func_type = unalias_type (fsym->type);
|
||||||
|
if (func_type->t.func.num_params > MAX_PARMS) {
|
||||||
error (0, "too many params");
|
error (0, "too many params");
|
||||||
}
|
}
|
||||||
// FIXME
|
// FIXME
|
||||||
|
|
|
@ -774,7 +774,11 @@ function_params (qfo_t *qfo, qfo_func_t *func, dfunction_t *df)
|
||||||
if (func->type >= qfo->spaces[qfo_type_space].data_size)
|
if (func->type >= qfo->spaces[qfo_type_space].data_size)
|
||||||
return;
|
return;
|
||||||
type = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, func->type);
|
type = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, func->type);
|
||||||
if (type->meta != ty_basic && type->t.type != ev_func)
|
if (type->meta == ty_alias) {
|
||||||
|
type = QFO_POINTER (qfo, qfo_type_space, qfot_type_t,
|
||||||
|
type->t.alias.aux_type);
|
||||||
|
}
|
||||||
|
if (type->meta != ty_basic || type->t.type != ev_func)
|
||||||
return;
|
return;
|
||||||
df->numparms = num_params = type->t.func.num_params;
|
df->numparms = num_params = type->t.func.num_params;
|
||||||
if (num_params < 0)
|
if (num_params < 0)
|
||||||
|
@ -1228,6 +1232,10 @@ qfo_to_sym (qfo_t *qfo, int *size)
|
||||||
aux->num_locals = num_locals;
|
aux->num_locals = num_locals;
|
||||||
//FIXME check type
|
//FIXME check type
|
||||||
type = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, func->type);
|
type = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, func->type);
|
||||||
|
if (type->meta == ty_alias) {
|
||||||
|
type = QFO_POINTER (qfo, qfo_type_space, qfot_type_t,
|
||||||
|
type->t.alias.aux_type);
|
||||||
|
}
|
||||||
aux->return_type = type->t.func.return_type;
|
aux->return_type = type->t.func.return_type;
|
||||||
aux++;
|
aux++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,6 +254,28 @@ qfo_encode_class (type_t *type)
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static def_t *
|
||||||
|
qfo_encode_alias (type_t *type)
|
||||||
|
{
|
||||||
|
qfot_type_t *enc;
|
||||||
|
def_t *def;
|
||||||
|
def_t *type_def;
|
||||||
|
def_t *full_def;
|
||||||
|
|
||||||
|
type_def = qfo_encode_type (type->t.alias.aux_type);
|
||||||
|
full_def = qfo_encode_type (type->t.alias.full_type);
|
||||||
|
|
||||||
|
def = qfo_new_encoding (type, sizeof (enc->t.alias));
|
||||||
|
enc = D_POINTER (qfot_type_t, def);
|
||||||
|
enc->t.alias.type = type->type;
|
||||||
|
ENC_DEF (enc->t.alias.aux_type, type_def);
|
||||||
|
ENC_DEF (enc->t.alias.full_type, full_def);
|
||||||
|
if (type->name) {
|
||||||
|
ENC_STR (enc->t.alias.name, type->name);
|
||||||
|
}
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
def_t *
|
def_t *
|
||||||
qfo_encode_type (type_t *type)
|
qfo_encode_type (type_t *type)
|
||||||
{
|
{
|
||||||
|
@ -266,6 +288,7 @@ qfo_encode_type (type_t *type)
|
||||||
qfo_encode_struct, // ty_enum
|
qfo_encode_struct, // ty_enum
|
||||||
qfo_encode_array, // ty_array
|
qfo_encode_array, // ty_array
|
||||||
qfo_encode_class, // ty_class
|
qfo_encode_class, // ty_class
|
||||||
|
qfo_encode_alias, // ty_alias
|
||||||
};
|
};
|
||||||
|
|
||||||
if (type->type_def && type->type_def->external) {
|
if (type->type_def && type->type_def->external) {
|
||||||
|
|
|
@ -456,6 +456,7 @@ external_decl
|
||||||
$1->type = find_type (append_type ($1->type, spec.type));
|
$1->type = find_type (append_type ($1->type, spec.type));
|
||||||
if (spec.is_typedef) {
|
if (spec.is_typedef) {
|
||||||
$1->sy_type = sy_type;
|
$1->sy_type = sy_type;
|
||||||
|
$1->type=find_type (alias_type ($1->type, $1->type, $1->name));
|
||||||
symtab_addsymbol (current_symtab, $1);
|
symtab_addsymbol (current_symtab, $1);
|
||||||
} else {
|
} else {
|
||||||
initialize_def ($1, 0, current_symtab->space, spec.storage);
|
initialize_def ($1, 0, current_symtab->space, spec.storage);
|
||||||
|
@ -471,6 +472,7 @@ external_decl
|
||||||
if (spec.is_typedef) {
|
if (spec.is_typedef) {
|
||||||
error (0, "typedef %s is initialized", $1->name);
|
error (0, "typedef %s is initialized", $1->name);
|
||||||
$1->sy_type = sy_type;
|
$1->sy_type = sy_type;
|
||||||
|
$1->type=find_type (alias_type ($1->type, $1->type, $1->name));
|
||||||
symtab_addsymbol (current_symtab, $1);
|
symtab_addsymbol (current_symtab, $1);
|
||||||
} else {
|
} else {
|
||||||
initialize_def ($1, $2, current_symtab->space, spec.storage);
|
initialize_def ($1, $2, current_symtab->space, spec.storage);
|
||||||
|
@ -484,6 +486,7 @@ external_decl
|
||||||
$1->type = find_type (append_type ($1->type, spec.type));
|
$1->type = find_type (append_type ($1->type, spec.type));
|
||||||
if (spec.is_typedef) {
|
if (spec.is_typedef) {
|
||||||
$1->sy_type = sy_type;
|
$1->sy_type = sy_type;
|
||||||
|
$1->type=find_type (alias_type ($1->type, $1->type, $1->name));
|
||||||
symtab_addsymbol (current_symtab, $1);
|
symtab_addsymbol (current_symtab, $1);
|
||||||
} else {
|
} else {
|
||||||
$1 = function_symbol ($1, spec.is_overload, 1);
|
$1 = function_symbol ($1, spec.is_overload, 1);
|
||||||
|
|
|
@ -213,39 +213,53 @@ append_type (type_t *type, type_t *new)
|
||||||
type_t **t = &type;
|
type_t **t = &type;
|
||||||
|
|
||||||
while (*t) {
|
while (*t) {
|
||||||
switch ((*t)->type) {
|
switch ((*t)->meta) {
|
||||||
case ev_void:
|
case ty_basic:
|
||||||
case ev_string:
|
switch ((*t)->type) {
|
||||||
case ev_float:
|
case ev_void:
|
||||||
case ev_vector:
|
case ev_string:
|
||||||
case ev_entity:
|
case ev_float:
|
||||||
case ev_type_count:
|
case ev_vector:
|
||||||
case ev_quat:
|
case ev_entity:
|
||||||
case ev_integer:
|
case ev_type_count:
|
||||||
case ev_uinteger:
|
case ev_quat:
|
||||||
case ev_short:
|
case ev_integer:
|
||||||
case ev_double:
|
case ev_uinteger:
|
||||||
internal_error (0, "append to basic type");
|
case ev_short:
|
||||||
case ev_field:
|
case ev_double:
|
||||||
case ev_pointer:
|
internal_error (0, "append to basic type");
|
||||||
t = &(*t)->t.fldptr.type;
|
case ev_field:
|
||||||
type->alignment = 1;
|
case ev_pointer:
|
||||||
break;
|
t = &(*t)->t.fldptr.type;
|
||||||
case ev_func:
|
type->alignment = 1;
|
||||||
t = &(*t)->t.func.type;
|
break;
|
||||||
type->alignment = 1;
|
case ev_func:
|
||||||
break;
|
t = &(*t)->t.func.type;
|
||||||
case ev_invalid:
|
type->alignment = 1;
|
||||||
if ((*t)->meta == ty_array) {
|
break;
|
||||||
t = &(*t)->t.array.type;
|
case ev_invalid:
|
||||||
type->alignment = new->alignment;
|
internal_error (0, "invalid basic type");
|
||||||
} else {
|
break;
|
||||||
internal_error (0, "append to object type");
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ty_array:
|
||||||
|
t = &(*t)->t.array.type;
|
||||||
|
type->alignment = new->alignment;
|
||||||
|
break;
|
||||||
|
case ty_struct:
|
||||||
|
case ty_union:
|
||||||
|
case ty_enum:
|
||||||
|
case ty_class:
|
||||||
|
case ty_alias: //XXX is this correct?
|
||||||
|
internal_error (0, "append to object type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*t = new;
|
if (new->meta == ty_alias) {
|
||||||
|
*t = new->t.alias.aux_type;
|
||||||
|
type = alias_type (type, new, 0);
|
||||||
|
} else {
|
||||||
|
*t = new;
|
||||||
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +312,10 @@ types_same (type_t *a, type_t *b)
|
||||||
return 0;
|
return 0;
|
||||||
return compare_protocols (a->protos, b->protos);
|
return compare_protocols (a->protos, b->protos);
|
||||||
case ty_alias:
|
case ty_alias:
|
||||||
return !strcmp (a->name, b->name);
|
// names have gone through save_string
|
||||||
|
return (a->name == b->name
|
||||||
|
&& a->t.alias.aux_type == b->t.alias.aux_type
|
||||||
|
&& a->t.alias.full_type == b->t.alias.full_type);
|
||||||
}
|
}
|
||||||
internal_error (0, "we be broke");
|
internal_error (0, "we be broke");
|
||||||
}
|
}
|
||||||
|
@ -349,7 +366,7 @@ find_type (type_t *type)
|
||||||
case ty_class:
|
case ty_class:
|
||||||
break;
|
break;
|
||||||
case ty_alias:
|
case ty_alias:
|
||||||
type->t.alias.type = find_type (type->t.alias.type);
|
type->t.alias.aux_type = find_type (type->t.alias.aux_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -450,6 +467,30 @@ based_array_type (type_t *aux, int base, int top)
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type_t *
|
||||||
|
alias_type (type_t *type, type_t *alias_chain, const char *name)
|
||||||
|
{
|
||||||
|
type_t *alias = new_type ();
|
||||||
|
alias->meta = ty_alias;
|
||||||
|
alias->type = type->type;
|
||||||
|
alias->alignment = type->alignment;
|
||||||
|
alias->t.alias.aux_type = type;
|
||||||
|
alias->t.alias.full_type = alias_chain;
|
||||||
|
if (name) {
|
||||||
|
alias->name = save_string (name);
|
||||||
|
}
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
const type_t *
|
||||||
|
unalias_type (const type_t *type)
|
||||||
|
{
|
||||||
|
if (type->meta == ty_alias) {
|
||||||
|
return type->t.alias.aux_type;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_type_str (dstring_t *str, const type_t *type)
|
print_type_str (dstring_t *str, const type_t *type)
|
||||||
{
|
{
|
||||||
|
@ -460,7 +501,7 @@ print_type_str (dstring_t *str, const type_t *type)
|
||||||
switch (type->meta) {
|
switch (type->meta) {
|
||||||
case ty_alias:
|
case ty_alias:
|
||||||
dasprintf (str, "({%s=", type->name);
|
dasprintf (str, "({%s=", type->name);
|
||||||
print_type_str (str, type->t.alias.type);
|
print_type_str (str, type->t.alias.aux_type);
|
||||||
dstring_appendstr (str, "})");
|
dstring_appendstr (str, "})");
|
||||||
return;
|
return;
|
||||||
case ty_class:
|
case ty_class:
|
||||||
|
@ -569,7 +610,7 @@ encode_params (const type_t *type)
|
||||||
else
|
else
|
||||||
count = type->t.func.num_params;
|
count = type->t.func.num_params;
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
encode_type (encoding, type->t.func.param_types[i]);
|
encode_type (encoding, unalias_type (type->t.func.param_types[i]));
|
||||||
if (type->t.func.num_params < 0)
|
if (type->t.func.num_params < 0)
|
||||||
dasprintf (encoding, ".");
|
dasprintf (encoding, ".");
|
||||||
|
|
||||||
|
@ -622,7 +663,7 @@ encode_type (dstring_t *encoding, const type_t *type)
|
||||||
switch (type->meta) {
|
switch (type->meta) {
|
||||||
case ty_alias: // XXX do I want this, or just the unaliased type?
|
case ty_alias: // XXX do I want this, or just the unaliased type?
|
||||||
dasprintf (encoding, "{%s>", type->name);
|
dasprintf (encoding, "{%s>", type->name);
|
||||||
encode_type (encoding, type->t.alias.type);
|
encode_type (encoding, type->t.alias.aux_type);
|
||||||
dasprintf (encoding, "}");
|
dasprintf (encoding, "}");
|
||||||
return;
|
return;
|
||||||
case ty_class:
|
case ty_class:
|
||||||
|
@ -714,12 +755,14 @@ encode_type (dstring_t *encoding, const type_t *type)
|
||||||
int
|
int
|
||||||
is_void (const type_t *type)
|
is_void (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
return type->type == ev_void;
|
return type->type == ev_void;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
is_enum (const type_t *type)
|
is_enum (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
if (type->type == ev_invalid && type->meta == ty_enum)
|
if (type->type == ev_invalid && type->meta == ty_enum)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -728,6 +771,7 @@ is_enum (const type_t *type)
|
||||||
int
|
int
|
||||||
is_integer (const type_t *type)
|
is_integer (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
etype_t t = type->type;
|
etype_t t = type->type;
|
||||||
|
|
||||||
if (t == ev_integer)
|
if (t == ev_integer)
|
||||||
|
@ -738,6 +782,7 @@ is_integer (const type_t *type)
|
||||||
int
|
int
|
||||||
is_uinteger (const type_t *type)
|
is_uinteger (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
etype_t t = type->type;
|
etype_t t = type->type;
|
||||||
|
|
||||||
if (t == ev_uinteger)
|
if (t == ev_uinteger)
|
||||||
|
@ -748,6 +793,7 @@ is_uinteger (const type_t *type)
|
||||||
int
|
int
|
||||||
is_short (const type_t *type)
|
is_short (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
etype_t t = type->type;
|
etype_t t = type->type;
|
||||||
|
|
||||||
if (t == ev_short)
|
if (t == ev_short)
|
||||||
|
@ -758,6 +804,7 @@ is_short (const type_t *type)
|
||||||
int
|
int
|
||||||
is_integral (const type_t *type)
|
is_integral (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
if (is_integer (type) || is_uinteger (type) || is_short (type))
|
if (is_integer (type) || is_uinteger (type) || is_short (type))
|
||||||
return 1;
|
return 1;
|
||||||
return is_enum (type);
|
return is_enum (type);
|
||||||
|
@ -766,36 +813,42 @@ is_integral (const type_t *type)
|
||||||
int
|
int
|
||||||
is_double (const type_t *type)
|
is_double (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
return type->type == ev_double;
|
return type->type == ev_double;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
is_float (const type_t *type)
|
is_float (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
return type->type == ev_float;
|
return type->type == ev_float;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
is_scalar (const type_t *type)
|
is_scalar (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
return is_float (type) || is_integral (type) || is_double (type);
|
return is_float (type) || is_integral (type) || is_double (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
is_vector (const type_t *type)
|
is_vector (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
return type->type == ev_vector;
|
return type->type == ev_vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
is_quaternion (const type_t *type)
|
is_quaternion (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
return type->type == ev_quat;
|
return type->type == ev_quat;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
is_math (const type_t *type)
|
is_math (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
etype_t t = type->type;
|
etype_t t = type->type;
|
||||||
|
|
||||||
return t == ev_vector || t == ev_quat || is_scalar (type);
|
return t == ev_vector || t == ev_quat || is_scalar (type);
|
||||||
|
@ -804,6 +857,7 @@ is_math (const type_t *type)
|
||||||
int
|
int
|
||||||
is_struct (const type_t *type)
|
is_struct (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
if (type->type == ev_invalid
|
if (type->type == ev_invalid
|
||||||
&& (type->meta == ty_struct || type->meta == ty_union))
|
&& (type->meta == ty_struct || type->meta == ty_union))
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -813,6 +867,7 @@ is_struct (const type_t *type)
|
||||||
int
|
int
|
||||||
is_pointer (const type_t *type)
|
is_pointer (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
if (type->type == ev_pointer)
|
if (type->type == ev_pointer)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -821,6 +876,7 @@ is_pointer (const type_t *type)
|
||||||
int
|
int
|
||||||
is_field (const type_t *type)
|
is_field (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
if (type->type == ev_field)
|
if (type->type == ev_field)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -829,6 +885,7 @@ is_field (const type_t *type)
|
||||||
int
|
int
|
||||||
is_entity (const type_t *type)
|
is_entity (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
if (type->type == ev_entity)
|
if (type->type == ev_entity)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -837,6 +894,7 @@ is_entity (const type_t *type)
|
||||||
int
|
int
|
||||||
is_array (const type_t *type)
|
is_array (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
if (type->type == ev_invalid && type->meta == ty_array)
|
if (type->type == ev_invalid && type->meta == ty_array)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -845,6 +903,7 @@ is_array (const type_t *type)
|
||||||
int
|
int
|
||||||
is_func (const type_t *type)
|
is_func (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
if (type->type == ev_func)
|
if (type->type == ev_func)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -853,12 +912,14 @@ is_func (const type_t *type)
|
||||||
int
|
int
|
||||||
is_structural (const type_t *type)
|
is_structural (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
return is_struct (type) || is_array (type);
|
return is_struct (type) || is_array (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
is_string (const type_t *type)
|
is_string (const type_t *type)
|
||||||
{
|
{
|
||||||
|
type = unalias_type (type);
|
||||||
if (type->type == ev_string)
|
if (type->type == ev_string)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -888,6 +949,8 @@ type_assignable (const type_t *dst, const type_t *src)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
dst = unalias_type (dst);
|
||||||
|
src = unalias_type (src);
|
||||||
// same type
|
// same type
|
||||||
if (dst == src)
|
if (dst == src)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -952,7 +1015,7 @@ type_size (const type_t *type)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
case ty_alias:
|
case ty_alias:
|
||||||
return type_size (type->t.alias.type);
|
return type_size (type->t.alias.aux_type);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue