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
*/
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 =
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;
case ARRAY:
array2pointer(expp);
break;
+ case POINTER:
+ if ((*expp)->ex_class == String)
+ string2pointer(expp);
+ break;
#ifndef NOBITFIELD
case FIELD:
field2arith(expp);
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)
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 */
}
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) {
}
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,
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))
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
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!",
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();
}
*/
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:
}
}
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);
}
}
/* 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
#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) */
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;
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,
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:
{
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();
C_loi(expr->ex_type->tp_size);
}
break;
-
case Oper: /* compound expression */
{
register int oper = expr->OP_OPER;
if (tp->tp_fund == ERRONEOUS) /* stop immediately */
break;
-
switch (oper) {
case '+':
/* We have the following possibilities :
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:
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 '(':
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))(); }
*/
}
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;
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 ':' */
- 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);
+ }
}
}
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;
- }
}
}
#include "declar.h"
#include "storage.h"
#include "sizes.h"
+#include "level.h"
extern char *symbol2str();
extern char options[];
) ? 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;
}
crash("(intexpr) bad fund %s\n", symbol2str(fund));
}
expr->ex_class = Value;
+ expr->VL_CLASS = Const;
expr->VL_VALUE = ivalue;
cut_size(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
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 {
};
/* 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
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/
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 */
}
}
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);
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
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 {
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
C_loc(shift);
C_sri(asize);
}
-
conversion(atype, tp);
}
}
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().
{
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
/* 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)
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)
}
/* "int i = 12;" */
check_ival(expr, tp);
- return 0;
+ break;
}
- /* NOTREACHED */
+ return 0;
}
/* do_array() initialises the members of an array described
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:
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);
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:
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 */
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;
}
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)
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;
/* 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;