revised the administration of Value expressions
This commit is contained in:
parent
fac31cce07
commit
66c571d217
|
@ -190,10 +190,10 @@ idf.o: LLlex.h Lpars.h align.h alloc.h arith.h assert.h botch_free.h debug.h dec
|
|||
declarator.o: Lpars.h alloc.h arith.h botch_free.h declar.h expr.h idf.h label.h nobitfield.h nopp.h sizes.h spec_arith.h storage.h type.h
|
||||
decspecs.o: Lpars.h arith.h decspecs.h def.h level.h nobitfield.h spec_arith.h type.h
|
||||
struct.o: LLlex.h Lpars.h align.h arith.h assert.h botch_free.h debug.h def.h field.h idf.h level.h nobitfield.h nopp.h sizes.h spec_arith.h stack.h storage.h struct.h type.h
|
||||
expr.o: LLlex.h Lpars.h alloc.h arith.h botch_free.h declar.h decspecs.h def.h expr.h idf.h label.h nobitfield.h nopp.h sizes.h spec_arith.h storage.h type.h
|
||||
expr.o: LLlex.h Lpars.h alloc.h arith.h botch_free.h declar.h decspecs.h def.h expr.h idf.h label.h nobitfield.h nopp.h sizes.h spec_arith.h storage.h type.h level.h
|
||||
ch7.o: Lpars.h arith.h assert.h debug.h def.h expr.h idf.h label.h nobitfield.h nopp.h spec_arith.h struct.h type.h
|
||||
ch7bin.o: Lpars.h arith.h botch_free.h expr.h idf.h label.h nobitfield.h nopp.h spec_arith.h storage.h struct.h type.h
|
||||
cstoper.o: Lpars.h arith.h expr.h idf.h label.h nobitfield.h nopp.h sizes.h spec_arith.h target_sizes.h type.h
|
||||
cstoper.o: Lpars.h arith.h expr.h idf.h label.h nobitfield.h nopp.h sizes.h spec_arith.h target_sizes.h type.h assert.h
|
||||
arith.o: Lpars.h alloc.h arith.h botch_free.h expr.h field.h idf.h label.h mes.h nobitfield.h nopp.h spec_arith.h storage.h type.h
|
||||
alloc.o: alloc.h assert.h debug.h myalloc.h
|
||||
code.o: LLlex.h Lpars.h alloc.h arith.h assert.h atw.h botch_free.h code.h dataflow.h debug.h declar.h decspecs.h def.h expr.h idf.h label.h level.h mes.h nobitfield.h nopp.h sizes.h spec_arith.h specials.h stack.h storage.h type.h use_tmp.h
|
||||
|
|
|
@ -257,18 +257,16 @@ float2float(expp, tp)
|
|||
*/
|
||||
|
||||
fp_used = 1;
|
||||
if (is_fp_cst(*expp)) {
|
||||
if (is_fp_cst(*expp))
|
||||
(*expp)->ex_type = tp;
|
||||
}
|
||||
else {
|
||||
else
|
||||
*expp = arith2arith(tp, FLOAT2FLOAT, *expp);
|
||||
}
|
||||
}
|
||||
|
||||
array2pointer(expp)
|
||||
struct expr **expp;
|
||||
{
|
||||
/* The expression, which must be an array, it is converted
|
||||
/* The expression, which must be an array, is converted
|
||||
to a pointer.
|
||||
*/
|
||||
(*expp)->ex_type =
|
||||
|
@ -278,13 +276,29 @@ array2pointer(expp)
|
|||
function2pointer(expp)
|
||||
struct expr **expp;
|
||||
{
|
||||
/* The expression, which must be a function, it is converted
|
||||
/* The expression, which must be a function, is converted
|
||||
to a pointer to the function.
|
||||
*/
|
||||
(*expp)->ex_type =
|
||||
construct_type(POINTER, (*expp)->ex_type, (arith)0);
|
||||
}
|
||||
|
||||
string2pointer(expp)
|
||||
struct expr **expp;
|
||||
{
|
||||
/* The expression, which must be a string constant, is converted
|
||||
to a pointer to the string-containing area.
|
||||
*/
|
||||
struct expr *ex = *expp;
|
||||
label lbl = data_label();
|
||||
|
||||
code_string(ex->SG_VALUE, ex->SG_LEN, lbl);
|
||||
ex->ex_class = Value;
|
||||
ex->VL_CLASS = Label;
|
||||
ex->VL_LBL = lbl;
|
||||
ex->VL_VALUE = (arith)0;
|
||||
}
|
||||
|
||||
opnd2integral(expp, oper)
|
||||
struct expr **expp;
|
||||
int oper;
|
||||
|
@ -421,6 +435,10 @@ any2opnd(expp, oper)
|
|||
case ARRAY:
|
||||
array2pointer(expp);
|
||||
break;
|
||||
case POINTER:
|
||||
if ((*expp)->ex_class == String)
|
||||
string2pointer(expp);
|
||||
break;
|
||||
#ifndef NOBITFIELD
|
||||
case FIELD:
|
||||
field2arith(expp);
|
||||
|
|
|
@ -109,6 +109,7 @@ ch7sel(expp, oper, idf)
|
|||
struct oper *op = &((*expp)->ex_object.ex_oper);
|
||||
|
||||
if (op->op_oper == '.' || op->op_oper == ARROW) {
|
||||
ASSERT(is_cp_cst(op->op_right));
|
||||
op->op_right->VL_VALUE += sd->sd_offset;
|
||||
(*expp)->ex_type = sd->sd_type;
|
||||
if ((*expp)->ex_type == error_type)
|
||||
|
@ -188,6 +189,8 @@ ch7cast(expp, oper, tp)
|
|||
function2pointer(expp);
|
||||
if ((*expp)->ex_type->tp_fund == ARRAY)
|
||||
array2pointer(expp);
|
||||
if ((*expp)->ex_class == String)
|
||||
string2pointer(expp);
|
||||
oldtp = (*expp)->ex_type;
|
||||
if (oldtp == tp)
|
||||
{} /* life is easy */
|
||||
|
|
|
@ -46,13 +46,11 @@ ch7mon(oper, expp)
|
|||
}
|
||||
break;
|
||||
case '&':
|
||||
if ((*expp)->ex_type->tp_fund == ARRAY) {
|
||||
if ((*expp)->ex_type->tp_fund == ARRAY)
|
||||
array2pointer(expp);
|
||||
}
|
||||
else
|
||||
if ((*expp)->ex_type->tp_fund == FUNCTION) {
|
||||
if ((*expp)->ex_type->tp_fund == FUNCTION)
|
||||
function2pointer(expp);
|
||||
}
|
||||
else
|
||||
#ifndef NOBITFIELD
|
||||
if ((*expp)->ex_type->tp_fund == FIELD) {
|
||||
|
@ -65,12 +63,15 @@ ch7mon(oper, expp)
|
|||
}
|
||||
else {
|
||||
/* assume that enums are already filtered out */
|
||||
if ((*expp)->ex_class == Value && (*expp)->VL_IDF) {
|
||||
if ( (*expp)->ex_class == Value
|
||||
&& (*expp)->VL_CLASS == Name
|
||||
) {
|
||||
register struct def *def =
|
||||
(*expp)->VL_IDF->id_def;
|
||||
|
||||
/* &<var> indicates that <var> cannot
|
||||
be used as register anymore
|
||||
/* &<var> indicates that <var>
|
||||
cannot be used as register
|
||||
anymore
|
||||
*/
|
||||
if (def->df_sc == REGISTER) {
|
||||
expr_error(*expp,
|
||||
|
@ -98,11 +99,7 @@ ch7mon(oper, expp)
|
|||
any2arith(expp, oper);
|
||||
if (is_cp_cst(*expp)) {
|
||||
arith o1 = (*expp)->VL_VALUE;
|
||||
if (oper == '-')
|
||||
o1 = -o1;
|
||||
else
|
||||
o1 = ~o1;
|
||||
(*expp)->VL_VALUE = o1;
|
||||
(*expp)->VL_VALUE = (oper == '-') ? -o1 : ~o1;
|
||||
}
|
||||
else
|
||||
if (is_fp_cst(*expp))
|
||||
|
@ -118,9 +115,7 @@ ch7mon(oper, expp)
|
|||
any2arith(expp, oper);
|
||||
opnd2test(expp, '!');
|
||||
if (is_cp_cst(*expp)) {
|
||||
arith o1 = (*expp)->VL_VALUE;
|
||||
o1 = !o1;
|
||||
(*expp)->VL_VALUE = o1;
|
||||
(*expp)->VL_VALUE = !((*expp)->VL_VALUE);
|
||||
(*expp)->ex_type = int_type;
|
||||
}
|
||||
else
|
||||
|
@ -133,7 +128,7 @@ ch7mon(oper, expp)
|
|||
break;
|
||||
case SIZEOF:
|
||||
if ( (*expp)->ex_class == Value
|
||||
&& (*expp)->VL_IDF
|
||||
&& (*expp)->VL_CLASS == Name
|
||||
&& (*expp)->VL_IDF->id_def->df_formal_array
|
||||
)
|
||||
warning("sizeof formal array %s is sizeof pointer!",
|
||||
|
|
|
@ -59,11 +59,41 @@ famous_first_words()
|
|||
C_ms_emx(word_size, pointer_size);
|
||||
}
|
||||
|
||||
static struct string_cst *str_list = 0;
|
||||
|
||||
code_string(val, len, dlb)
|
||||
char *val;
|
||||
int len;
|
||||
label dlb;
|
||||
{
|
||||
struct string_cst *sc = new_string_cst();
|
||||
|
||||
C_ina_dlb(dlb);
|
||||
sc->next = str_list;
|
||||
str_list = sc;
|
||||
sc->sc_value = val;
|
||||
sc->sc_len = len;
|
||||
sc->sc_dlb = dlb;
|
||||
}
|
||||
|
||||
def_strings(sc)
|
||||
register struct string_cst *sc;
|
||||
{
|
||||
if (sc) {
|
||||
def_strings(sc->next);
|
||||
C_df_dlb(sc->sc_dlb);
|
||||
C_con_scon(sc->sc_value, sc->sc_len);
|
||||
free_string_cst(sc);
|
||||
}
|
||||
}
|
||||
|
||||
end_code()
|
||||
{
|
||||
/* end_code() performs the actions to be taken when closing
|
||||
the output stream.
|
||||
*/
|
||||
def_strings(str_list);
|
||||
str_list = 0;
|
||||
C_ms_src((arith)(LineNumber - 2), FileName);
|
||||
C_close();
|
||||
}
|
||||
|
@ -351,6 +381,7 @@ loc_init(expr, id)
|
|||
*/
|
||||
register struct type *tp = id->id_def->df_type;
|
||||
|
||||
ASSERT(id->id_def->df_sc != STATIC);
|
||||
/* automatic aggregates cannot be initialised. */
|
||||
switch (tp->tp_fund) {
|
||||
case ARRAY:
|
||||
|
@ -374,9 +405,14 @@ loc_init(expr, id)
|
|||
}
|
||||
}
|
||||
else { /* not embraced */
|
||||
struct value vl;
|
||||
|
||||
ch7cast(&expr, '=', tp);
|
||||
EVAL(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
|
||||
store_val(id, tp, (arith) 0);
|
||||
vl.vl_class = Name;
|
||||
vl.vl_data.vl_idf = id;
|
||||
vl.vl_value = (arith)0;
|
||||
store_val(&vl, tp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,15 @@ struct stat_block {
|
|||
|
||||
/* ALLOCDEF "stat_block" */
|
||||
|
||||
struct string_cst { /* storing string constants */
|
||||
struct string_cst *next;
|
||||
char *sc_value;
|
||||
int sc_len;
|
||||
label sc_dlb;
|
||||
};
|
||||
|
||||
/* ALLOCDEF "string_cst" */
|
||||
|
||||
#define LVAL 0
|
||||
#define RVAL 1
|
||||
#define FALSE 0
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "expr.h"
|
||||
#include "sizes.h"
|
||||
#include "Lpars.h"
|
||||
#include "assert.h"
|
||||
|
||||
long mach_long_sign; /* sign bit of the machine long */
|
||||
int mach_long_size; /* size of long on this machine == sizeof(long) */
|
||||
|
@ -21,13 +22,14 @@ cstbin(expp, oper, expr)
|
|||
struct expr **expp, *expr;
|
||||
{
|
||||
/* The operation oper is performed on the constant
|
||||
expressions *expp and expr, and the result restored in
|
||||
expressions *expp(ld) and expr(ct), and the result restored in
|
||||
*expp.
|
||||
*/
|
||||
arith o1 = (*expp)->VL_VALUE;
|
||||
arith o2 = expr->VL_VALUE;
|
||||
int uns = (*expp)->ex_type->tp_unsigned;
|
||||
|
||||
ASSERT(is_ld_cst(*expp) && is_cp_cst(expr));
|
||||
switch (oper) {
|
||||
case '*':
|
||||
o1 *= o2;
|
||||
|
@ -190,6 +192,7 @@ cut_size(expr)
|
|||
int uns = expr->ex_type->tp_unsigned;
|
||||
int size = (int) expr->ex_type->tp_size;
|
||||
|
||||
ASSERT(expr->ex_class == Value);
|
||||
if (uns) {
|
||||
if (o1 & ~full_mask[size])
|
||||
expr_warning(expr,
|
||||
|
|
|
@ -331,14 +331,24 @@ p1_expr(lvl, expr)
|
|||
expr->ex_class == Type ? "Type" : "UNKNOWN CLASS"
|
||||
);
|
||||
switch (expr->ex_class) {
|
||||
struct value *v;
|
||||
struct oper *o;
|
||||
case Value:
|
||||
v = &expr->ex_object.ex_value;
|
||||
if (v->vl_idf)
|
||||
printf("%s + ", v->vl_idf->id_text);
|
||||
switch (expr->VL_CLASS) {
|
||||
case Const:
|
||||
printf("(Const) ");
|
||||
break;
|
||||
case Name:
|
||||
printf("(Name) %s + ", expr->VL_IDF->id_text);
|
||||
break;
|
||||
case Label:
|
||||
printf("(Label) .%lu + ", expr->VL_LBL);
|
||||
break;
|
||||
default:
|
||||
printf("(Unknown) ");
|
||||
break;
|
||||
}
|
||||
printf(expr->ex_type->tp_unsigned ? "%lu\n" : "%ld\n",
|
||||
v->vl_value);
|
||||
expr->VL_VALUE);
|
||||
break;
|
||||
case String:
|
||||
{
|
||||
|
|
|
@ -80,22 +80,17 @@ EVAL(expr, val, code, true_label, false_label)
|
|||
register gencode = (code == TRUE);
|
||||
|
||||
switch (expr->ex_class) {
|
||||
|
||||
case Value: /* just a simple value */
|
||||
if (gencode)
|
||||
load_val(expr, val);
|
||||
break;
|
||||
|
||||
case String: /* a string constant */
|
||||
expr_warning(expr, "(DEBUG) value-class 'String' seen");
|
||||
if (gencode) {
|
||||
label datlab = data_label();
|
||||
|
||||
C_df_dlb(datlab);
|
||||
C_con_scon(expr->SG_VALUE, (arith)expr->SG_LEN);
|
||||
C_lae_dlb(datlab, (arith)0);
|
||||
string2pointer(&expr);
|
||||
C_lae_dlb(expr->VL_LBL, expr->VL_VALUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case Float: /* a floating constant */
|
||||
if (gencode) {
|
||||
label datlab = data_label();
|
||||
|
@ -106,7 +101,6 @@ EVAL(expr, val, code, true_label, false_label)
|
|||
C_loi(expr->ex_type->tp_size);
|
||||
}
|
||||
break;
|
||||
|
||||
case Oper: /* compound expression */
|
||||
{
|
||||
register int oper = expr->OP_OPER;
|
||||
|
@ -116,7 +110,6 @@ EVAL(expr, val, code, true_label, false_label)
|
|||
|
||||
if (tp->tp_fund == ERRONEOUS) /* stop immediately */
|
||||
break;
|
||||
|
||||
switch (oper) {
|
||||
case '+':
|
||||
/* We have the following possibilities :
|
||||
|
@ -366,8 +359,10 @@ EVAL(expr, val, code, true_label, false_label)
|
|||
store_block(tp->tp_size, tp->tp_align);
|
||||
}
|
||||
else
|
||||
store_val(leftop->VL_IDF, leftop->ex_type,
|
||||
leftop->VL_VALUE);
|
||||
store_val(
|
||||
&(leftop->ex_object.ex_value),
|
||||
leftop->ex_type
|
||||
);
|
||||
break;
|
||||
case PLUSAB:
|
||||
case MINAB:
|
||||
|
@ -410,8 +405,10 @@ EVAL(expr, val, code, true_label, false_label)
|
|||
assop(tp, oper);
|
||||
if (gencode)
|
||||
C_dup(roundup(tp->tp_size));
|
||||
store_val(leftop->VL_IDF, leftop->ex_type,
|
||||
leftop->VL_VALUE);
|
||||
store_val(
|
||||
&(leftop->ex_object.ex_value),
|
||||
leftop->ex_type
|
||||
);
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
|
@ -433,7 +430,9 @@ EVAL(expr, val, code, true_label, false_label)
|
|||
EVAL(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
|
||||
ParSize += ATW(expr->ex_type->tp_size);
|
||||
}
|
||||
if (leftop->ex_class == Value && leftop->VL_IDF != 0) {
|
||||
if ( leftop->ex_class == Value
|
||||
&& leftop->VL_CLASS == Name
|
||||
) {
|
||||
/* just an example:
|
||||
main() { (*((int (*)())0))(); }
|
||||
*/
|
||||
|
@ -466,11 +465,13 @@ EVAL(expr, val, code, true_label, false_label)
|
|||
}
|
||||
case '.':
|
||||
EVAL(leftop, LVAL, code, NO_LABEL, NO_LABEL);
|
||||
ASSERT(is_cp_cst(rightop));
|
||||
if (gencode)
|
||||
C_adp(rightop->VL_VALUE);
|
||||
break;
|
||||
case ARROW:
|
||||
EVAL(leftop, RVAL, code, NO_LABEL, NO_LABEL);
|
||||
ASSERT(is_cp_cst(rightop));
|
||||
if (gencode)
|
||||
C_adp(rightop->VL_VALUE);
|
||||
break;
|
||||
|
@ -532,8 +533,10 @@ EVAL(expr, val, code, true_label, false_label)
|
|||
free_tmp_var(old_offset);
|
||||
}
|
||||
else
|
||||
store_val(leftop->VL_IDF, leftop->ex_type,
|
||||
leftop->VL_VALUE);
|
||||
store_val(
|
||||
&(leftop->ex_object.ex_value),
|
||||
leftop->ex_type
|
||||
);
|
||||
break;
|
||||
}
|
||||
case '?': /* must be followed by ':' */
|
||||
|
@ -841,62 +844,70 @@ free_tmp_var(oldoffset)
|
|||
- into an automatic local variable
|
||||
- into a local static variable
|
||||
- absolute addressing
|
||||
When the destination is described by an (lvalue) expression, the call
|
||||
is "store_val(ex->VL_IDF, ex->ex_type, ex->VL_VALUE)"
|
||||
*/
|
||||
store_val(id, tp, offs)
|
||||
register struct idf *id;
|
||||
store_val(vl, tp)
|
||||
register struct value *vl;
|
||||
struct type *tp;
|
||||
arith offs;
|
||||
{
|
||||
arith size = tp->tp_size;
|
||||
int tpalign = tp->tp_align;
|
||||
int al_on_word;
|
||||
register int inword;
|
||||
register int indword;
|
||||
arith val = vl->vl_value;
|
||||
|
||||
if (id) {
|
||||
if (vl->vl_class == Const) { /* absolute addressing */
|
||||
load_cst(val, pointer_size);
|
||||
store_block(size, tpalign);
|
||||
return;
|
||||
}
|
||||
|
||||
al_on_word = (tpalign % word_align == 0);
|
||||
if (!(inword = (size == word_size && al_on_word)))
|
||||
indword = (size == dword_size && al_on_word);
|
||||
|
||||
if (vl->vl_class == Name) {
|
||||
register struct idf *id = vl->vl_data.vl_idf;
|
||||
register struct def *df = id->id_def;
|
||||
int al_on_word = (tpalign % word_align == 0);
|
||||
register inword = (size == word_size && al_on_word);
|
||||
register indword = (size == dword_size && al_on_word);
|
||||
|
||||
if (df->df_level == L_GLOBAL) {
|
||||
if (inword)
|
||||
C_ste_dnam(id->id_text, offs);
|
||||
C_ste_dnam(id->id_text, val);
|
||||
else
|
||||
if (indword)
|
||||
C_sde_dnam(id->id_text, offs);
|
||||
C_sde_dnam(id->id_text, val);
|
||||
else {
|
||||
C_lae_dnam(id->id_text, offs);
|
||||
store_block(size, tpalign);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (df->df_sc == STATIC) {
|
||||
if (inword)
|
||||
C_ste_dlb((label)df->df_address, offs);
|
||||
else
|
||||
if (indword)
|
||||
C_sde_dlb((label)df->df_address, offs);
|
||||
else {
|
||||
C_lae_dlb((label)df->df_address, offs);
|
||||
C_lae_dnam(id->id_text, val);
|
||||
store_block(size, tpalign);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ASSERT(df->df_sc != STATIC);
|
||||
if (inword)
|
||||
C_stl(df->df_address + offs);
|
||||
C_stl(df->df_address + val);
|
||||
else
|
||||
if (indword)
|
||||
C_sdl(df->df_address + offs);
|
||||
C_sdl(df->df_address + val);
|
||||
else {
|
||||
C_lal(df->df_address + offs);
|
||||
C_lal(df->df_address + val);
|
||||
store_block(size, tpalign);
|
||||
df->df_register = REG_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* absolute addressing */
|
||||
load_cst(offs, pointer_size);
|
||||
store_block(size, tpalign);
|
||||
else {
|
||||
label dlb = vl->vl_data.vl_lbl;
|
||||
|
||||
ASSERT(vl->vl_class == Label);
|
||||
if (inword)
|
||||
C_ste_dlb(dlb, val);
|
||||
else
|
||||
if (indword)
|
||||
C_sde_dlb(dlb, val);
|
||||
else {
|
||||
C_lae_dlb(dlb, val);
|
||||
store_block(size, tpalign);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -914,101 +925,96 @@ load_val(expr, val)
|
|||
struct expr *expr; /* expression containing the value */
|
||||
int val; /* generate either LVAL or RVAL */
|
||||
{
|
||||
register struct idf *id;
|
||||
register struct type *tp = expr->ex_type;
|
||||
register struct def *df;
|
||||
register rvalue = (val == RVAL && expr->ex_lvalue != 0);
|
||||
register arith exval = expr->VL_VALUE;
|
||||
register int rvalue = (val == RVAL && expr->ex_lvalue != 0);
|
||||
register arith size = tp->tp_size;
|
||||
register tpalign = tp->tp_align;
|
||||
register al_on_word = (tpalign % word_align == 0);
|
||||
register int tpalign = tp->tp_align;
|
||||
register int al_on_word;
|
||||
register int inword, indword;
|
||||
register arith val = expr->VL_VALUE;
|
||||
|
||||
if ((id = expr->VL_IDF) == 0) {
|
||||
/* Note: enum constants are also dealt with here */
|
||||
if (rvalue) {
|
||||
/* absolute addressing
|
||||
*/
|
||||
load_cst(exval, pointer_size);
|
||||
if (expr->VL_CLASS == Const) {
|
||||
if (rvalue) { /* absolute addressing */
|
||||
load_cst(val, pointer_size);
|
||||
load_block(size, tpalign);
|
||||
}
|
||||
else /* integer, unsigned, long, enum etc */
|
||||
load_cst(exval, size);
|
||||
load_cst(val, size);
|
||||
return;
|
||||
}
|
||||
else
|
||||
if ((df = id->id_def)->df_type->tp_fund == FUNCTION)
|
||||
/* the previous statement tried to catch a function
|
||||
identifier, which may be cast to a pointer to a
|
||||
function.
|
||||
ASSERT(!(rvalue)); ???
|
||||
*/
|
||||
C_lpi(id->id_text);
|
||||
else
|
||||
if (df->df_level == L_GLOBAL) {
|
||||
if (rvalue) {
|
||||
al_on_word = (tpalign % word_align == 0);
|
||||
if (!(inword = (size == word_size && al_on_word)))
|
||||
indword = (size == dword_size && al_on_word);
|
||||
}
|
||||
if (expr->VL_CLASS == Label) {
|
||||
if (rvalue) {
|
||||
if (size == word_size && al_on_word)
|
||||
C_loe_dnam(id->id_text, exval);
|
||||
if (inword)
|
||||
C_loe_dlb(expr->VL_LBL, val);
|
||||
else
|
||||
if (size == dword_size && al_on_word)
|
||||
C_lde_dnam(id->id_text, exval);
|
||||
if (indword)
|
||||
C_lde_dlb(expr->VL_LBL, val);
|
||||
else {
|
||||
C_lae_dnam(id->id_text, exval);
|
||||
C_lae_dlb(expr->VL_LBL, val);
|
||||
load_block(size, tpalign);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
C_lae_dnam(id->id_text, (arith)0);
|
||||
C_adp(exval);
|
||||
C_lae_dlb(expr->VL_LBL, (arith)0);
|
||||
C_adp(val);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (df->df_sc == STATIC) {
|
||||
if (rvalue) {
|
||||
if (size == word_size && al_on_word)
|
||||
C_loe_dlb((label)df->df_address, exval);
|
||||
else
|
||||
if (size == dword_size && al_on_word)
|
||||
C_lde_dlb((label)df->df_address, exval);
|
||||
else {
|
||||
C_lae_dlb((label)df->df_address, exval);
|
||||
load_block(size, tpalign);
|
||||
}
|
||||
else {
|
||||
register struct idf *id = expr->VL_IDF;
|
||||
register struct def *df;
|
||||
|
||||
ASSERT(expr->VL_CLASS == Name);
|
||||
if ((df = id->id_def)->df_type->tp_fund == FUNCTION)
|
||||
/* the previous statement tried to catch a function
|
||||
identifier, which may be cast to a pointer to a
|
||||
function.
|
||||
ASSERT(!(rvalue)); ???
|
||||
*/
|
||||
C_lpi(id->id_text);
|
||||
else
|
||||
if (df->df_level == L_GLOBAL) {
|
||||
if (rvalue) {
|
||||
if (inword)
|
||||
C_loe_dnam(id->id_text, val);
|
||||
else
|
||||
if (indword)
|
||||
C_lde_dnam(id->id_text, val);
|
||||
else {
|
||||
C_lae_dnam(id->id_text, val);
|
||||
load_block(size, tpalign);
|
||||
}
|
||||
}
|
||||
else {
|
||||
C_lae_dnam(id->id_text, (arith)0);
|
||||
C_adp(val);
|
||||
}
|
||||
}
|
||||
else {
|
||||
C_lae_dlb((label)df->df_address, (arith)0);
|
||||
C_adp(exval);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rvalue) {
|
||||
if (size == word_size && al_on_word)
|
||||
C_lol(df->df_address + exval);
|
||||
else
|
||||
if (size == dword_size && al_on_word)
|
||||
C_ldl(df->df_address + exval);
|
||||
ASSERT(df->df_sc != STATIC);
|
||||
if (rvalue) {
|
||||
if (inword)
|
||||
C_lol(df->df_address + val);
|
||||
else
|
||||
if (indword)
|
||||
C_ldl(df->df_address + val);
|
||||
else {
|
||||
C_lal(df->df_address + val);
|
||||
load_block(size, tpalign);
|
||||
df->df_register = REG_NONE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
C_lal(df->df_address + exval);
|
||||
load_block(size, tpalign);
|
||||
C_lal(df->df_address);
|
||||
C_adp(val);
|
||||
df->df_register = REG_NONE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* following code may be used when
|
||||
comparing addresses as in the following
|
||||
example:
|
||||
f() {
|
||||
int a[10], *i;
|
||||
for (i = &a[0]; i < &a[10]; i++) ...;
|
||||
}
|
||||
We don't accept the contents of a[10] to
|
||||
be legitimate, so the RVAL of it may
|
||||
contain a big mess.
|
||||
*/
|
||||
C_lal(df->df_address);
|
||||
C_adp(exval);
|
||||
df->df_register = REG_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "declar.h"
|
||||
#include "storage.h"
|
||||
#include "sizes.h"
|
||||
#include "level.h"
|
||||
|
||||
extern char *symbol2str();
|
||||
extern char options[];
|
||||
|
@ -184,10 +185,17 @@ idf2expr(expr)
|
|||
) ? 0 : 1;
|
||||
expr->ex_class = Value;
|
||||
if (def->df_sc == ENUM) {
|
||||
expr->VL_IDF = 0;
|
||||
expr->VL_CLASS = Const;
|
||||
expr->VL_VALUE = def->df_address;
|
||||
}
|
||||
else {
|
||||
else
|
||||
if (def->df_sc == STATIC && def->df_level >= L_LOCAL) {
|
||||
expr->VL_CLASS = Label;
|
||||
expr->VL_LBL = def->df_address;
|
||||
expr->VL_VALUE = (arith)0;
|
||||
}
|
||||
else {
|
||||
expr->VL_CLASS = Name;
|
||||
expr->VL_IDF = idf;
|
||||
expr->VL_VALUE = (arith)0;
|
||||
}
|
||||
|
@ -246,6 +254,7 @@ intexpr(ivalue, fund)
|
|||
crash("(intexpr) bad fund %s\n", symbol2str(fund));
|
||||
}
|
||||
expr->ex_class = Value;
|
||||
expr->VL_CLASS = Const;
|
||||
expr->VL_VALUE = ivalue;
|
||||
|
||||
cut_size(expr);
|
||||
|
@ -421,7 +430,7 @@ is_cp_cst(expr)
|
|||
/* An expression is a `compile-time constant' if it is a
|
||||
load-time constant, and the idf is not there.
|
||||
*/
|
||||
return is_ld_cst(expr) && expr->VL_IDF == 0;
|
||||
return is_ld_cst(expr) && expr->VL_CLASS == Const;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -5,9 +5,18 @@
|
|||
a union of various goodies, we define them first; so be patient.
|
||||
*/
|
||||
|
||||
/* classes of value */
|
||||
#define Const 1
|
||||
#define Name 2
|
||||
#define Label 3
|
||||
|
||||
struct value {
|
||||
struct idf *vl_idf; /* idf of an external name or 0 */
|
||||
arith vl_value; /* constant, or offset if idf != 0 */
|
||||
int vl_class; /* Const, Name or Label */
|
||||
arith vl_value; /* constant value or offset */
|
||||
union {
|
||||
struct idf *vl_idf; /* external name */
|
||||
label vl_lbl; /* compiler-generated label */
|
||||
} vl_data;
|
||||
};
|
||||
|
||||
struct string {
|
||||
|
@ -53,8 +62,10 @@ struct expr {
|
|||
};
|
||||
|
||||
/* some abbreviated selections */
|
||||
#define VL_CLASS ex_object.ex_value.vl_class
|
||||
#define VL_VALUE ex_object.ex_value.vl_value
|
||||
#define VL_IDF ex_object.ex_value.vl_idf
|
||||
#define VL_IDF ex_object.ex_value.vl_data.vl_idf
|
||||
#define VL_LBL ex_object.ex_value.vl_data.vl_lbl
|
||||
#define SG_VALUE ex_object.ex_string.sg_value
|
||||
#define SG_LEN ex_object.ex_string.sg_len
|
||||
#define SG_DATLAB ex_object.ex_string.sg_datlab
|
||||
|
|
|
@ -47,7 +47,6 @@ eval_field(expr, code)
|
|||
|
||||
ASSERT(leftop->ex_type->tp_fund == FIELD);
|
||||
ASSERT(asize == word_size); /* make sure that C_loc() is legal */
|
||||
|
||||
leftop->ex_type = atype; /* this is cheating but it works... */
|
||||
|
||||
/* Note that op is either an assignment operator or an increment/
|
||||
|
@ -60,26 +59,21 @@ eval_field(expr, code)
|
|||
conversion(tp, atype);
|
||||
C_loc(fd->fd_mask);
|
||||
C_and(asize);
|
||||
if (code == TRUE) {
|
||||
if (code == TRUE)
|
||||
C_dup(asize);
|
||||
}
|
||||
C_loc((arith)fd->fd_shift);
|
||||
|
||||
if (atype->tp_unsigned)
|
||||
C_slu(asize);
|
||||
else
|
||||
C_sli(asize);
|
||||
|
||||
C_loc(~((fd->fd_mask << fd->fd_shift) | (~0 << (8 * asize))));
|
||||
|
||||
if (leftop->ex_depth == 0) { /* simple case */
|
||||
load_val(leftop, RVAL);
|
||||
C_and(asize);
|
||||
C_ior(asize);
|
||||
store_val(
|
||||
leftop->VL_IDF,
|
||||
leftop->ex_type,
|
||||
leftop->VL_VALUE
|
||||
&(leftop->ex_object.ex_value),
|
||||
leftop->ex_type
|
||||
);
|
||||
}
|
||||
else { /* complex case */
|
||||
|
@ -98,13 +92,11 @@ eval_field(expr, code)
|
|||
}
|
||||
}
|
||||
else { /* treat ++F as F += 1 and --F as F -= 1 */
|
||||
|
||||
/* F op= e: f = (((((f>>shift)&mask) op e)&mask)<<shift)|
|
||||
(f&~(mask<<shift))
|
||||
*/
|
||||
if (leftop->ex_depth == 0) { /* simple case */
|
||||
if (leftop->ex_depth == 0) /* simple case */
|
||||
load_val(leftop, RVAL);
|
||||
}
|
||||
else { /* complex case */
|
||||
tmpvar = tmp_pointer_var(&old_offset);
|
||||
EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
|
||||
|
@ -113,26 +105,18 @@ eval_field(expr, code)
|
|||
C_sti(pointer_size);
|
||||
C_loi(asize);
|
||||
}
|
||||
|
||||
C_loc((arith)fd->fd_shift);
|
||||
|
||||
if (atype->tp_unsigned)
|
||||
C_sru(asize);
|
||||
else
|
||||
C_sri(asize);
|
||||
|
||||
C_loc(fd->fd_mask);
|
||||
C_and(asize);
|
||||
|
||||
if (code == TRUE && (op == POSTINCR || op == POSTDECR)) {
|
||||
if (code == TRUE && (op == POSTINCR || op == POSTDECR))
|
||||
C_dup(asize);
|
||||
}
|
||||
|
||||
EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL);
|
||||
conversion(tp, atype);
|
||||
|
||||
/* generate the code for the operator
|
||||
*/
|
||||
/* generate code for the operator */
|
||||
if (op == PLUSPLUS || op == POSTINCR)
|
||||
assop(atype, PLUSAB);
|
||||
else
|
||||
|
@ -140,31 +124,23 @@ eval_field(expr, code)
|
|||
assop(atype, MINAB);
|
||||
else
|
||||
assop(atype, op);
|
||||
|
||||
C_loc(fd->fd_mask);
|
||||
C_and(asize);
|
||||
|
||||
if (code == TRUE && op != POSTINCR && op != POSTDECR) {
|
||||
if (code == TRUE && op != POSTINCR && op != POSTDECR)
|
||||
C_dup(asize);
|
||||
}
|
||||
|
||||
C_loc((arith)fd->fd_shift);
|
||||
|
||||
if (atype->tp_unsigned)
|
||||
C_slu(asize);
|
||||
else
|
||||
C_sli(asize);
|
||||
|
||||
C_loc(~((fd->fd_mask << fd->fd_shift) | (~0 << (8 * asize))));
|
||||
|
||||
if (leftop->ex_depth == 0) {
|
||||
load_val(leftop, RVAL);
|
||||
C_and(asize);
|
||||
C_ior(asize);
|
||||
store_val(
|
||||
leftop->VL_IDF,
|
||||
leftop->ex_type,
|
||||
leftop->VL_VALUE
|
||||
&(leftop->ex_object.ex_value),
|
||||
leftop->ex_type
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -179,7 +155,6 @@ eval_field(expr, code)
|
|||
free_tmp_var(old_offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (code == TRUE) {
|
||||
/* Take care that the effective value stored in
|
||||
the bit field (i.e. the value that is got on
|
||||
|
@ -193,7 +168,6 @@ eval_field(expr, code)
|
|||
C_loc(shift);
|
||||
C_sri(asize);
|
||||
}
|
||||
|
||||
conversion(atype, tp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ char *symbol2str();
|
|||
char *long2str();
|
||||
|
||||
struct expr *do_array(), *do_struct(), *IVAL();
|
||||
struct expr *strings = 0; /* list of string constants within initialiser */
|
||||
|
||||
/* do_ival() performs the initialisation of a global variable
|
||||
of type tp with the initialisation expression expr by calling IVAL().
|
||||
|
@ -39,33 +38,8 @@ do_ival(tpp, expr)
|
|||
{
|
||||
if (IVAL(tpp, expr) != 0)
|
||||
too_many_initialisers(expr);
|
||||
|
||||
/* The following loop declares the string constants
|
||||
used in the initialisation.
|
||||
The code for these string constants may not appear in
|
||||
the code of the initialisation because a data label
|
||||
in EM causes the current initialisation to be completed.
|
||||
E.g. char *s[] = {"hello", "world"};
|
||||
*/
|
||||
while (strings != 0) {
|
||||
C_df_dlb(strings->SG_DATLAB);
|
||||
C_con_scon(strings->SG_VALUE, (arith)strings->SG_LEN);
|
||||
strings = strings->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* store_string() collects the string constants appearing in an
|
||||
initialisation.
|
||||
*/
|
||||
store_string(expr)
|
||||
struct expr *expr;
|
||||
{
|
||||
expr->next = strings;
|
||||
strings = expr;
|
||||
}
|
||||
|
||||
|
||||
/* IVAL() recursively guides the initialisation expression through the
|
||||
different routines for the different types of initialisation:
|
||||
- array initialisation
|
||||
|
@ -89,18 +63,14 @@ IVAL(tpp, expr)
|
|||
/* array initialisation */
|
||||
if (valid_type(tp->tp_up, "array element") == 0)
|
||||
return 0;
|
||||
if (ISCOMMA(expr)) {
|
||||
/* list of initialisation expressions */
|
||||
if (ISCOMMA(expr)) /* list of initialisation expressions */
|
||||
return do_array(expr, tpp);
|
||||
}
|
||||
/* There might be an initialisation of a string
|
||||
like char s[] = "I am a string"
|
||||
*/
|
||||
/* catch initialisations like char s[] = "I am a string" */
|
||||
if (tp->tp_up->tp_fund == CHAR && expr->ex_class == String)
|
||||
init_string(tpp, expr);
|
||||
else /* " int i[24] = 12;" */
|
||||
check_and_pad(expr, tpp);
|
||||
return 0; /* nothing left */
|
||||
break;
|
||||
case STRUCT:
|
||||
/* struct initialisation */
|
||||
if (valid_type(tp, "struct") == 0)
|
||||
|
@ -109,12 +79,12 @@ IVAL(tpp, expr)
|
|||
return do_struct(expr, tp);
|
||||
/* "struct foo f = 12;" */
|
||||
check_and_pad(expr, tpp);
|
||||
return 0;
|
||||
break;
|
||||
case UNION:
|
||||
error("union initialisation not allowed");
|
||||
return 0;
|
||||
break;
|
||||
case ERRONEOUS:
|
||||
return 0;
|
||||
break;
|
||||
default: /* fundamental type */
|
||||
if (ISCOMMA(expr)) { /* " int i = {12};" */
|
||||
if (IVAL(tpp, expr->OP_LEFT) != 0)
|
||||
|
@ -127,9 +97,9 @@ IVAL(tpp, expr)
|
|||
}
|
||||
/* "int i = 12;" */
|
||||
check_ival(expr, tp);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* do_array() initialises the members of an array described
|
||||
|
@ -451,20 +421,18 @@ check_ival(expr, type)
|
|||
case LONG:
|
||||
case ENUM:
|
||||
ch7cast(&expr, '=', type);
|
||||
if (!is_cp_cst(expr)) {
|
||||
if (is_cp_cst(expr))
|
||||
con_int(expr);
|
||||
else
|
||||
illegal_init_cst(expr);
|
||||
break;
|
||||
}
|
||||
con_int(expr);
|
||||
break;
|
||||
#ifndef NOBITFIELD
|
||||
case FIELD:
|
||||
ch7cast(&expr, '=', type->tp_up);
|
||||
if (!is_cp_cst(expr)) {
|
||||
if (is_cp_cst(expr))
|
||||
put_bf(type, expr->VL_VALUE);
|
||||
else
|
||||
illegal_init_cst(expr);
|
||||
break;
|
||||
}
|
||||
put_bf(type, expr->VL_VALUE);
|
||||
break;
|
||||
#endif NOBITFIELD
|
||||
case FLOAT:
|
||||
|
@ -475,14 +443,13 @@ check_ival(expr, type)
|
|||
else
|
||||
if (expr->ex_class == Oper && expr->OP_OPER == INT2FLOAT) {
|
||||
expr = expr->OP_RIGHT;
|
||||
if (!is_cp_cst(expr)) {
|
||||
if (is_cp_cst(expr))
|
||||
C_con_fcon(
|
||||
long2str((long)expr->VL_VALUE, 10),
|
||||
type->tp_size
|
||||
);
|
||||
else
|
||||
illegal_init_cst(expr);
|
||||
break;
|
||||
}
|
||||
C_con_fcon(
|
||||
long2str((long)expr->VL_VALUE, 10),
|
||||
type->tp_size
|
||||
);
|
||||
}
|
||||
else
|
||||
illegal_init_cst(expr);
|
||||
|
@ -493,55 +460,35 @@ check_ival(expr, type)
|
|||
case Oper:
|
||||
illegal_init_cst(expr);
|
||||
break;
|
||||
case String: /* char *s = "...." */
|
||||
{
|
||||
label datlab = data_label();
|
||||
|
||||
C_ina_dlb(datlab);
|
||||
C_con_dlb(datlab, (arith)0);
|
||||
expr->SG_DATLAB = datlab;
|
||||
store_string(expr);
|
||||
break;
|
||||
}
|
||||
case Value:
|
||||
{
|
||||
struct value *vl = &(expr->ex_object.ex_value);
|
||||
struct idf *idf = vl->vl_idf;
|
||||
|
||||
ASSERT(expr->ex_type->tp_fund == POINTER);
|
||||
if (expr->ex_type->tp_up->tp_fund == FUNCTION) {
|
||||
if (idf)
|
||||
C_con_pnam(idf->id_text);
|
||||
if (expr->VL_CLASS == Name)
|
||||
C_con_pnam(expr->VL_IDF->id_text);
|
||||
else /* int (*func)() = 0 */
|
||||
con_int(expr);
|
||||
}
|
||||
else
|
||||
if (idf) {
|
||||
register struct def *def = idf->id_def;
|
||||
if (expr->VL_CLASS == Name) {
|
||||
register struct idf *id = expr->VL_IDF;
|
||||
|
||||
if (def->df_level >= L_LOCAL) {
|
||||
if (def->df_sc != STATIC)
|
||||
/* Eg. int a;
|
||||
static int *p = &a;
|
||||
*/
|
||||
expr_error(expr,
|
||||
"illegal initialisation"
|
||||
);
|
||||
else
|
||||
C_con_dlb(
|
||||
(label)def->df_address,
|
||||
vl->vl_value
|
||||
);
|
||||
}
|
||||
if (id ->id_def->df_level >= L_LOCAL)
|
||||
expr_error(expr,
|
||||
"illegal initialisation");
|
||||
else
|
||||
C_con_dnam(idf->id_text, vl->vl_value);
|
||||
C_con_dnam(id->id_text, expr->VL_VALUE);
|
||||
}
|
||||
else
|
||||
if (expr->VL_CLASS == Label)
|
||||
C_con_dlb(expr->VL_LBL, expr->VL_VALUE);
|
||||
else
|
||||
con_int(expr);
|
||||
break;
|
||||
}
|
||||
case String:
|
||||
default:
|
||||
crash("(check_ival) illegal initialisation expression");
|
||||
crash("(check_ival) illegal value class");
|
||||
}
|
||||
break;
|
||||
case ERRONEOUS:
|
||||
|
@ -565,6 +512,7 @@ init_string(tpp, expr)
|
|||
char *s = expr->SG_VALUE;
|
||||
arith ntopad;
|
||||
|
||||
ASSERT(expr->ex_class == String);
|
||||
length = expr->SG_LEN;
|
||||
if (tp->tp_size == (arith)-1) {
|
||||
/* set the dimension */
|
||||
|
@ -604,21 +552,22 @@ put_bf(tp, val)
|
|||
static arith offset = (arith)-1;
|
||||
register struct field *fd = tp->tp_field;
|
||||
register struct sdef *sd = fd->fd_sdef;
|
||||
static struct expr expr;
|
||||
static struct expr exp;
|
||||
|
||||
ASSERT(sd);
|
||||
if (offset == (arith)-1) {
|
||||
/* first bitfield in this field */
|
||||
offset = sd->sd_offset;
|
||||
expr.ex_type = tp->tp_up;
|
||||
expr.ex_class = Value;
|
||||
exp.ex_type = tp->tp_up;
|
||||
exp.ex_class = Value;
|
||||
exp.VL_CLASS = Const;
|
||||
}
|
||||
if (val != 0) /* insert the value into "field" */
|
||||
field |= (val & fd->fd_mask) << fd->fd_shift;
|
||||
if (sd->sd_sdef == 0 || sd->sd_sdef->sd_offset != offset) {
|
||||
/* the selector was the last stored at this address */
|
||||
expr.VL_VALUE = field;
|
||||
con_int(&expr);
|
||||
exp.VL_VALUE = field;
|
||||
con_int(&exp);
|
||||
field = (arith)0;
|
||||
offset = (arith)-1;
|
||||
}
|
||||
|
@ -654,27 +603,28 @@ valid_type(tp, str)
|
|||
return 1;
|
||||
}
|
||||
|
||||
con_int(expr)
|
||||
register struct expr *expr;
|
||||
con_int(ex)
|
||||
register struct expr *ex;
|
||||
{
|
||||
register struct type *tp = expr->ex_type;
|
||||
register struct type *tp = ex->ex_type;
|
||||
|
||||
ASSERT(is_cp_cst(ex));
|
||||
if (tp->tp_unsigned)
|
||||
C_con_ucon(long2str((long)expr->VL_VALUE, -10), tp->tp_size);
|
||||
C_con_ucon(long2str((long)ex->VL_VALUE, -10), tp->tp_size);
|
||||
else
|
||||
C_con_icon(long2str((long)expr->VL_VALUE, 10), tp->tp_size);
|
||||
C_con_icon(long2str((long)ex->VL_VALUE, 10), tp->tp_size);
|
||||
}
|
||||
|
||||
illegal_init_cst(expr)
|
||||
struct expr *expr;
|
||||
illegal_init_cst(ex)
|
||||
struct expr *ex;
|
||||
{
|
||||
expr_error(expr, "illegal initialisation constant");
|
||||
expr_error(ex, "illegal initialisation constant");
|
||||
}
|
||||
|
||||
too_many_initialisers(expr)
|
||||
struct expr *expr;
|
||||
too_many_initialisers(ex)
|
||||
struct expr *ex;
|
||||
{
|
||||
expr_error(expr, "too many initialisers");
|
||||
expr_error(ex, "too many initialisers");
|
||||
}
|
||||
|
||||
aggregate_type(tp)
|
||||
|
|
|
@ -124,6 +124,7 @@ code_case(expr)
|
|||
register struct case_entry *ce;
|
||||
register struct switch_hdr *sh = switch_stack;
|
||||
|
||||
ASSERT(is_cp_cst(expr));
|
||||
if (sh == 0) {
|
||||
error("case statement not in switch");
|
||||
return;
|
||||
|
@ -133,14 +134,11 @@ code_case(expr)
|
|||
/* is probably 0 anyway */
|
||||
return;
|
||||
}
|
||||
|
||||
expr->ex_type = sh->sh_type;
|
||||
cut_size(expr);
|
||||
|
||||
ce = new_case_entry();
|
||||
C_df_ilb(ce->ce_label = text_label());
|
||||
ce->ce_value = val = expr->VL_VALUE;
|
||||
|
||||
if (sh->sh_entries == 0) {
|
||||
/* first case entry */
|
||||
ce->next = (struct case_entry *) 0;
|
||||
|
|
Loading…
Reference in a new issue