Handle union access now that they're detected properly.

This commit is contained in:
Bill Currie 2011-02-08 14:45:48 +09:00
parent 204a267b6a
commit 3c849b970b
5 changed files with 31 additions and 1 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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 ("??");
}

View file

@ -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;
}

View file

@ -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;
}