[qfcc] Create a nil operand

This is for struct assignments so they can pass the source operand back
up the assignment chain.
This commit is contained in:
Bill Currie 2020-03-14 17:47:23 +09:00
parent eca976e5ae
commit 97e0c23529
4 changed files with 25 additions and 1 deletions

View File

@ -38,6 +38,7 @@ typedef enum {
op_label, op_label,
op_temp, op_temp,
op_alias, op_alias,
op_nil,
} op_type_e; } op_type_e;
typedef struct { typedef struct {
@ -55,7 +56,7 @@ typedef struct {
typedef struct operand_s { typedef struct operand_s {
struct operand_s *next; struct operand_s *next;
op_type_e op_type; op_type_e op_type;
struct type_s *type; ///< possibly override def's type struct type_s *type; ///< possibly override def's/nil's type
int size; ///< for structures int size; ///< for structures
struct expr_s *expr; ///< expression generating this operand struct expr_s *expr; ///< expression generating this operand
void *return_addr; ///< who created this operand void *return_addr; ///< who created this operand
@ -117,6 +118,7 @@ struct dstring_s;
const char *optype_str (op_type_e type) __attribute__((const)); const char *optype_str (op_type_e type) __attribute__((const));
operand_t *nil_operand (struct type_s *type, struct expr_s *expr);
operand_t *def_operand (struct def_s *def, struct type_s *type, operand_t *def_operand (struct def_s *def, struct type_s *type,
struct expr_s *expr); struct expr_s *expr);
operand_t *return_operand (struct type_s *type, struct expr_s *expr); operand_t *return_operand (struct type_s *type, struct expr_s *expr);

View File

@ -106,6 +106,8 @@ get_operand_def (expr_t *expr, operand_t *op)
return op->o.tempop.def; return op->o.tempop.def;
case op_alias: case op_alias:
return get_operand_def (expr, op->o.alias); return get_operand_def (expr, op->o.alias);
case op_nil:
internal_error (expr, "unexpected nil operand");
} }
return 0; return 0;
} }

View File

@ -281,6 +281,8 @@ flowvar_get_def (flowvar_t *var)
return op->o.tempop.def; return op->o.tempop.def;
case op_alias: case op_alias:
internal_error (op->expr, "unexpected alias operand"); internal_error (op->expr, "unexpected alias operand");
case op_nil:
internal_error (op->expr, "unexpected nil operand");
} }
internal_error (op->expr, "oops, blue pill"); internal_error (op->expr, "oops, blue pill");
return 0; return 0;

View File

@ -65,6 +65,8 @@ static const char *op_type_names[] = {
"op_value", "op_value",
"op_label", "op_label",
"op_temp", "op_temp",
"op_alias",
"op_nil",
}; };
const char * const char *
@ -150,6 +152,8 @@ operand_string (operand_t *op)
strcpy (buf, alias); strcpy (buf, alias);
return va ("alias(%s,%s)", pr_type_name[op->type->type], buf); return va ("alias(%s,%s)", pr_type_name[op->type->type], buf);
} }
case op_nil:
return va ("nil");
} }
return ("??"); return ("??");
} }
@ -222,6 +226,10 @@ print_operand (operand_t *op)
printf ("alias(%s,", pr_type_name[op->type->type]); printf ("alias(%s,", pr_type_name[op->type->type]);
print_operand (op->o.alias); print_operand (op->o.alias);
printf (")"); printf (")");
break;
case op_nil:
printf ("nil");
break;
} }
} }
@ -313,6 +321,16 @@ free_sblock (sblock_t *sblock)
FREE (sblocks, sblock); FREE (sblocks, sblock);
} }
operand_t *
nil_operand (type_t *type, expr_t *expr)
{
operand_t *op;
op = new_operand (op_nil, expr, __builtin_return_address (0));
op->type = type;
op->size = type_size (type);
return op;
}
operand_t * operand_t *
def_operand (def_t *def, type_t *type, expr_t *expr) def_operand (def_t *def, type_t *type, expr_t *expr)
{ {