revised the administration of Value expressions
authorerikb <none@none>
Wed, 2 Apr 1986 08:37:17 +0000 (08:37 +0000)
committererikb <none@none>
Wed, 2 Apr 1986 08:37:17 +0000 (08:37 +0000)
14 files changed:
lang/cem/cemcom/Makefile.erik
lang/cem/cemcom/arith.c
lang/cem/cemcom/ch7.c
lang/cem/cemcom/ch7mon.c
lang/cem/cemcom/code.c
lang/cem/cemcom/code.str
lang/cem/cemcom/cstoper.c
lang/cem/cemcom/dumpidf.c
lang/cem/cemcom/eval.c
lang/cem/cemcom/expr.c
lang/cem/cemcom/expr.str
lang/cem/cemcom/field.c
lang/cem/cemcom/ival.c
lang/cem/cemcom/switch.c

index 8acb5b6..dff19db 100644 (file)
@@ -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
index 629fbac..61bdb6e 100644 (file)
@@ -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);
index 0f39bcf..ab17373 100644 (file)
@@ -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 */
index f18969f..b99925a 100644 (file)
@@ -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!",
index 689daaa..098924f 100644 (file)
@@ -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);
        }
 }
 
index 11a00cb..2f2399c 100644 (file)
@@ -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
index 9b4e09e..1d31a1b 100644 (file)
@@ -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,
index 1c20e88..cd7e469 100644 (file)
@@ -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:
        {
index 636e428..b0f5f40 100644 (file)
@@ -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 (vl->vl_class == Const)      {       /* absolute addressing */
+               load_cst(val, pointer_size);
+               store_block(size, tpalign);
+               return;
+       }
 
-       if (id) {
+       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 {
+               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_dlb((label)df->df_address, exval);
-                               load_block(size, tpalign);
+                               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;
-               }
        }
 }
 
index ba07d30..0a8629e 100644 (file)
@@ -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
index 2531672..1d62758 100644 (file)
@@ -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
index bc0b76d..6245ac8 100644 (file)
@@ -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);
        }
 }
index 8e921e9..ff52c49 100644 (file)
@@ -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 (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 (expr->VL_CLASS == Name) {
+                               register struct idf *id = expr->VL_IDF;
+
+                               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)
index 28db313..3999206 100644 (file)
@@ -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;