mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-19 07:20:50 +00:00
Handle union access now that they're detected properly.
This commit is contained in:
parent
204a267b6a
commit
3c849b970b
5 changed files with 31 additions and 1 deletions
|
@ -94,7 +94,7 @@ typedef struct {
|
|||
|
||||
Represent a pointer to an absolute address in data space.
|
||||
*/
|
||||
typedef struct {
|
||||
typedef struct ex_pointer_s {
|
||||
int val;
|
||||
struct type_s *type;
|
||||
struct def_s *def;
|
||||
|
|
|
@ -36,6 +36,7 @@ typedef enum {
|
|||
op_value,
|
||||
op_label,
|
||||
op_temp,
|
||||
op_pointer,
|
||||
} op_type_e;
|
||||
|
||||
typedef struct operand_s {
|
||||
|
@ -46,6 +47,7 @@ typedef struct operand_s {
|
|||
struct symbol_s *symbol;
|
||||
struct ex_value_s *value;
|
||||
struct ex_label_s *label;
|
||||
struct ex_pointer_s *pointer;
|
||||
struct def_s *def;
|
||||
} o;
|
||||
} operand_t;
|
||||
|
|
|
@ -47,6 +47,7 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$";
|
|||
#include "expr.h"
|
||||
#include "statements.h"
|
||||
#include "symtab.h"
|
||||
#include "type.h"
|
||||
|
||||
static const char *
|
||||
quote_string (const char *str)
|
||||
|
@ -85,6 +86,8 @@ quote_string (const char *str)
|
|||
static const char *
|
||||
get_operand (operand_t *op)
|
||||
{
|
||||
type_t *type;
|
||||
|
||||
if (!op)
|
||||
return "";
|
||||
switch (op->op_type) {
|
||||
|
@ -131,6 +134,16 @@ get_operand (operand_t *op)
|
|||
return op->o.label->name;
|
||||
case op_temp:
|
||||
return va ("tmp %p", op);
|
||||
case op_pointer:
|
||||
type = op->o.pointer->type;
|
||||
if (op->o.pointer->def)
|
||||
return va ("(%s)[%d]<%s>",
|
||||
type ? pr_type_name[type->type] : "???",
|
||||
op->o.pointer->val, op->o.pointer->def->name);
|
||||
else
|
||||
return va ("(%s)[%d]",
|
||||
type ? pr_type_name[type->type] : "???",
|
||||
op->o.pointer->val);
|
||||
}
|
||||
return ("??");
|
||||
}
|
||||
|
|
|
@ -81,6 +81,8 @@ get_value_def (ex_value_t *value, etype_t type)
|
|||
static def_t *
|
||||
get_operand_def (operand_t *op)
|
||||
{
|
||||
def_t *def;
|
||||
|
||||
if (!op)
|
||||
return 0;
|
||||
switch (op->op_type) {
|
||||
|
@ -110,6 +112,13 @@ get_operand_def (operand_t *op)
|
|||
op->o.def = new_def (".tmp", ev_types[op->type],
|
||||
current_func->symtab->space, st_local);
|
||||
return op->o.def;
|
||||
case op_pointer:
|
||||
def = op->o.pointer->def;
|
||||
if (op->o.pointer->val || op->type != def->type->type) {
|
||||
def = alias_def (def, ev_types[op->type]);
|
||||
def->offset = op->o.pointer->val;
|
||||
}
|
||||
return def;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -113,6 +113,8 @@ print_operand (operand_t *op)
|
|||
case op_temp:
|
||||
printf ("tmp %p", op);
|
||||
break;
|
||||
case op_pointer:
|
||||
printf ("ptr %p", op->o.pointer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,6 +437,10 @@ expr_deref (sblock_t *sblock, expr_t *e, operand_t **op)
|
|||
(*op)->type = low_level_type (e->e.expr.type);
|
||||
}
|
||||
s->opc = *op;
|
||||
} else if (e->type == ex_value && e->e.value.type == ev_pointer) {
|
||||
*op = new_operand (op_pointer);
|
||||
(*op)->type = low_level_type (e->e.value.v.pointer.type);
|
||||
(*op)->o.pointer = &e->e.value.v.pointer;
|
||||
}
|
||||
return sblock;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue