revised check_ival() (among some other small changes)
This commit is contained in:
parent
52d743f223
commit
725d3fa6ea
4 changed files with 152 additions and 148 deletions
|
@ -9,10 +9,12 @@ EM_INCLUDES =$(EM)/h# # directory containing EM interface definition
|
||||||
|
|
||||||
# Libraries
|
# Libraries
|
||||||
SYSLIB = /user1/erikb/em/lib/libsystem.a
|
SYSLIB = /user1/erikb/em/lib/libsystem.a
|
||||||
EMLIB = /user1/erikb/em/lib/libemk.a
|
EMKLIB = /user1/erikb/em/lib/libemk.a
|
||||||
|
EMELIB = /user1/erikb/em/lib/libeme.a
|
||||||
STRLIB = /user1/erikb/em/lib/libstr.a
|
STRLIB = /user1/erikb/em/lib/libstr.a
|
||||||
EMMESLIB = /user1/erikb/em/lib/libem_mes.a
|
EMMESLIB = /user1/erikb/em/lib/libem_mes.a
|
||||||
LIBS = $(EMMESLIB) $(EMLIB) $(STRLIB) $(SYSLIB)
|
LIBS = $(EMMESLIB) $(EMKLIB) $(STRLIB) $(SYSLIB)
|
||||||
|
ELIBS = $(EMMESLIB) $(EMELIB) $(STRLIB) $(SYSLIB)
|
||||||
LIB_INCLUDES = /user1/erikb/em/h
|
LIB_INCLUDES = /user1/erikb/em/h
|
||||||
|
|
||||||
# Where to install the compiler and its driver
|
# Where to install the compiler and its driver
|
||||||
|
@ -128,6 +130,10 @@ main: $(OBJ) Makefile
|
||||||
$(CC) $(COPTIONS) $(LFLAGS) $(OBJ) $(LIBS) -o main
|
$(CC) $(COPTIONS) $(LFLAGS) $(OBJ) $(LIBS) -o main
|
||||||
size main
|
size main
|
||||||
|
|
||||||
|
emain: $(OBJ) Makefile
|
||||||
|
$(CC) $(COPTIONS) $(LFLAGS) $(OBJ) $(ELIBS) -o emain
|
||||||
|
size emain
|
||||||
|
|
||||||
cfiles: hfiles LLfiles $(GSRC)
|
cfiles: hfiles LLfiles $(GSRC)
|
||||||
@touch cfiles
|
@touch cfiles
|
||||||
|
|
||||||
|
|
|
@ -46,21 +46,23 @@ ch7mon(oper, expp)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '&':
|
case '&':
|
||||||
if ((*expp)->ex_type->tp_fund == ARRAY)
|
if ((*expp)->ex_type->tp_fund == ARRAY) {
|
||||||
|
warning("& before array: ignored");
|
||||||
array2pointer(expp);
|
array2pointer(expp);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
if ((*expp)->ex_type->tp_fund == FUNCTION)
|
if ((*expp)->ex_type->tp_fund == FUNCTION) {
|
||||||
|
warning("& before function: ignored");
|
||||||
function2pointer(expp);
|
function2pointer(expp);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#ifndef NOBITFIELD
|
#ifndef NOBITFIELD
|
||||||
if ((*expp)->ex_type->tp_fund == FIELD) {
|
if ((*expp)->ex_type->tp_fund == FIELD)
|
||||||
expr_error(*expp, "& applied to field variable");
|
expr_error(*expp, "& applied to field variable");
|
||||||
}
|
|
||||||
else
|
else
|
||||||
#endif NOBITFIELD
|
#endif NOBITFIELD
|
||||||
if (!(*expp)->ex_lvalue) {
|
if (!(*expp)->ex_lvalue)
|
||||||
expr_error(*expp, "& applied to non-lvalue");
|
expr_error(*expp, "& applied to non-lvalue");
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
/* assume that enums are already filtered out */
|
/* assume that enums are already filtered out */
|
||||||
if ( (*expp)->ex_class == Value
|
if ( (*expp)->ex_class == Value
|
||||||
|
@ -89,11 +91,15 @@ ch7mon(oper, expp)
|
||||||
int fund = (*expp)->ex_type->tp_fund;
|
int fund = (*expp)->ex_type->tp_fund;
|
||||||
|
|
||||||
if (fund == FLOAT || fund == DOUBLE) {
|
if (fund == FLOAT || fund == DOUBLE) {
|
||||||
expr_error(*expp, "~ not allowed on %s operands",
|
expr_error(
|
||||||
symbol2str(fund));
|
*expp,
|
||||||
|
"~ not allowed on %s operands",
|
||||||
|
symbol2str(fund)
|
||||||
|
);
|
||||||
erroneous2int(expp);
|
erroneous2int(expp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* FALL THROUGH */
|
||||||
}
|
}
|
||||||
case '-':
|
case '-':
|
||||||
any2arith(expp, oper);
|
any2arith(expp, oper);
|
||||||
|
@ -106,7 +112,7 @@ ch7mon(oper, expp)
|
||||||
switch_sign_fp(*expp);
|
switch_sign_fp(*expp);
|
||||||
else
|
else
|
||||||
*expp = new_oper((*expp)->ex_type,
|
*expp = new_oper((*expp)->ex_type,
|
||||||
NILEXPR, oper, *expp);
|
NILEXPR, oper, *expp);
|
||||||
break;
|
break;
|
||||||
case '!':
|
case '!':
|
||||||
if ((*expp)->ex_type->tp_fund == FUNCTION)
|
if ((*expp)->ex_type->tp_fund == FUNCTION)
|
||||||
|
@ -116,7 +122,7 @@ ch7mon(oper, expp)
|
||||||
opnd2test(expp, '!');
|
opnd2test(expp, '!');
|
||||||
if (is_cp_cst(*expp)) {
|
if (is_cp_cst(*expp)) {
|
||||||
(*expp)->VL_VALUE = !((*expp)->VL_VALUE);
|
(*expp)->VL_VALUE = !((*expp)->VL_VALUE);
|
||||||
(*expp)->ex_type = int_type;
|
(*expp)->ex_type = int_type; /* a cast ???(EB) */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*expp = new_oper(int_type, NILEXPR, oper, *expp);
|
*expp = new_oper(int_type, NILEXPR, oper, *expp);
|
||||||
|
|
|
@ -32,12 +32,12 @@ struct expr *do_array(), *do_struct(), *IVAL();
|
||||||
of type tp with the initialisation expression expr by calling IVAL().
|
of type tp with the initialisation expression expr by calling IVAL().
|
||||||
Guided by type tp, the expression is evaluated.
|
Guided by type tp, the expression is evaluated.
|
||||||
*/
|
*/
|
||||||
do_ival(tpp, expr)
|
do_ival(tpp, ex)
|
||||||
struct type **tpp;
|
struct type **tpp;
|
||||||
struct expr *expr;
|
struct expr *ex;
|
||||||
{
|
{
|
||||||
if (IVAL(tpp, expr) != 0)
|
if (IVAL(tpp, ex) != 0)
|
||||||
too_many_initialisers(expr);
|
too_many_initialisers(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IVAL() recursively guides the initialisation expression through the
|
/* IVAL() recursively guides the initialisation expression through the
|
||||||
|
@ -52,9 +52,9 @@ do_ival(tpp, expr)
|
||||||
IVAL() returns a pointer to the remaining expression tree.
|
IVAL() returns a pointer to the remaining expression tree.
|
||||||
*/
|
*/
|
||||||
struct expr *
|
struct expr *
|
||||||
IVAL(tpp, expr)
|
IVAL(tpp, ex)
|
||||||
struct type **tpp; /* type of global variable */
|
struct type **tpp; /* type of global variable */
|
||||||
struct expr *expr; /* initialiser expression */
|
struct expr *ex; /* initialiser expression */
|
||||||
{
|
{
|
||||||
register struct type *tp = *tpp;
|
register struct type *tp = *tpp;
|
||||||
|
|
||||||
|
@ -63,22 +63,22 @@ IVAL(tpp, expr)
|
||||||
/* array initialisation */
|
/* array initialisation */
|
||||||
if (valid_type(tp->tp_up, "array element") == 0)
|
if (valid_type(tp->tp_up, "array element") == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (ISCOMMA(expr)) /* list of initialisation expressions */
|
if (ISCOMMA(ex)) /* list of initialisation expressions */
|
||||||
return do_array(expr, tpp);
|
return do_array(ex, tpp);
|
||||||
/* catch initialisations 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)
|
if (tp->tp_up->tp_fund == CHAR && ex->ex_class == String)
|
||||||
init_string(tpp, expr);
|
init_string(tpp, ex);
|
||||||
else /* " int i[24] = 12;" */
|
else /* " int i[24] = 12;" */
|
||||||
check_and_pad(expr, tpp);
|
check_and_pad(ex, tpp);
|
||||||
break;
|
break;
|
||||||
case STRUCT:
|
case STRUCT:
|
||||||
/* struct initialisation */
|
/* struct initialisation */
|
||||||
if (valid_type(tp, "struct") == 0)
|
if (valid_type(tp, "struct") == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (ISCOMMA(expr)) /* list of initialisation expressions */
|
if (ISCOMMA(ex)) /* list of initialisation expressions */
|
||||||
return do_struct(expr, tp);
|
return do_struct(ex, tp);
|
||||||
/* "struct foo f = 12;" */
|
/* "struct foo f = 12;" */
|
||||||
check_and_pad(expr, tpp);
|
check_and_pad(ex, tpp);
|
||||||
break;
|
break;
|
||||||
case UNION:
|
case UNION:
|
||||||
error("union initialisation not allowed");
|
error("union initialisation not allowed");
|
||||||
|
@ -86,17 +86,17 @@ IVAL(tpp, expr)
|
||||||
case ERRONEOUS:
|
case ERRONEOUS:
|
||||||
break;
|
break;
|
||||||
default: /* fundamental type */
|
default: /* fundamental type */
|
||||||
if (ISCOMMA(expr)) { /* " int i = {12};" */
|
if (ISCOMMA(ex)) { /* " int i = {12};" */
|
||||||
if (IVAL(tpp, expr->OP_LEFT) != 0)
|
if (IVAL(tpp, ex->OP_LEFT) != 0)
|
||||||
too_many_initialisers(expr);
|
too_many_initialisers(ex);
|
||||||
/* return remainings of the list for the
|
/* return remainings of the list for the
|
||||||
other members of the aggregate, if this
|
other members of the aggregate, if this
|
||||||
item belongs to an aggregate.
|
item belongs to an aggregate.
|
||||||
*/
|
*/
|
||||||
return expr->OP_RIGHT;
|
return ex->OP_RIGHT;
|
||||||
}
|
}
|
||||||
/* "int i = 12;" */
|
/* "int i = 12;" */
|
||||||
check_ival(expr, tp);
|
check_ival(ex, tp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -115,14 +115,14 @@ IVAL(tpp, expr)
|
||||||
members are padded with zeroes
|
members are padded with zeroes
|
||||||
*/
|
*/
|
||||||
struct expr *
|
struct expr *
|
||||||
do_array(expr, tpp)
|
do_array(ex, tpp)
|
||||||
struct expr *expr;
|
struct expr *ex;
|
||||||
struct type **tpp;
|
struct type **tpp;
|
||||||
{
|
{
|
||||||
register struct type *tp = *tpp;
|
register struct type *tp = *tpp;
|
||||||
register arith elem_count;
|
register arith elem_count;
|
||||||
|
|
||||||
ASSERT(tp->tp_fund == ARRAY && ISCOMMA(expr));
|
ASSERT(tp->tp_fund == ARRAY && ISCOMMA(ex));
|
||||||
/* the following test catches initialisations like
|
/* the following test catches initialisations like
|
||||||
char c[] = {"just a string"};
|
char c[] = {"just a string"};
|
||||||
or
|
or
|
||||||
|
@ -132,7 +132,7 @@ do_array(expr, tpp)
|
||||||
is completely foolish, we did it!! (no applause, thank you)
|
is completely foolish, we did it!! (no applause, thank you)
|
||||||
*/
|
*/
|
||||||
if (tp->tp_up->tp_fund == CHAR) {
|
if (tp->tp_up->tp_fund == CHAR) {
|
||||||
register struct expr *f = expr->OP_LEFT;
|
register struct expr *f = ex->OP_LEFT;
|
||||||
register struct expr *g = 0;
|
register struct expr *g = 0;
|
||||||
|
|
||||||
while (ISCOMMA(f)) { /* eat the brackets!!! */
|
while (ISCOMMA(f)) { /* eat the brackets!!! */
|
||||||
|
@ -141,28 +141,28 @@ do_array(expr, tpp)
|
||||||
}
|
}
|
||||||
if (f->ex_class == String) { /* hallelujah, it's a string! */
|
if (f->ex_class == String) { /* hallelujah, it's a string! */
|
||||||
init_string(tpp, f);
|
init_string(tpp, f);
|
||||||
return g ? g->OP_RIGHT : expr->OP_RIGHT;
|
return g ? g->OP_RIGHT : ex->OP_RIGHT;
|
||||||
}
|
}
|
||||||
/* else: just go on with the next part of this function */
|
/* else: just go on with the next part of this function */
|
||||||
if (g != 0)
|
if (g != 0)
|
||||||
expr = g;
|
ex = g;
|
||||||
}
|
}
|
||||||
if (tp->tp_size == (arith)-1) {
|
if (tp->tp_size == (arith)-1) {
|
||||||
/* declared with unknown size: [] */
|
/* declared with unknown size: [] */
|
||||||
for (elem_count = 0; expr; elem_count++) {
|
for (elem_count = 0; ex; elem_count++) {
|
||||||
/* eat whole initialisation expression */
|
/* eat whole initialisation expression */
|
||||||
if (ISCOMMA(expr->OP_LEFT)) {
|
if (ISCOMMA(ex->OP_LEFT)) {
|
||||||
/* the member expression is embraced */
|
/* the member expression is embraced */
|
||||||
if (IVAL(&(tp->tp_up), expr->OP_LEFT) != 0)
|
if (IVAL(&(tp->tp_up), ex->OP_LEFT) != 0)
|
||||||
too_many_initialisers(expr);
|
too_many_initialisers(ex);
|
||||||
expr = expr->OP_RIGHT;
|
ex = ex->OP_RIGHT;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (aggregate_type(tp->tp_up))
|
if (aggregate_type(tp->tp_up))
|
||||||
expr = IVAL(&(tp->tp_up), expr);
|
ex = IVAL(&(tp->tp_up), ex);
|
||||||
else {
|
else {
|
||||||
check_ival(expr->OP_LEFT, tp->tp_up);
|
check_ival(ex->OP_LEFT, tp->tp_up);
|
||||||
expr = expr->OP_RIGHT;
|
ex = ex->OP_RIGHT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,30 +172,30 @@ do_array(expr, tpp)
|
||||||
else { /* the number of members is already known */
|
else { /* the number of members is already known */
|
||||||
arith dim = tp->tp_size / tp->tp_up->tp_size;
|
arith dim = tp->tp_size / tp->tp_up->tp_size;
|
||||||
|
|
||||||
for (elem_count = 0; elem_count < dim && expr; elem_count++) {
|
for (elem_count = 0; elem_count < dim && ex; elem_count++) {
|
||||||
if (ISCOMMA(expr->OP_LEFT)) {
|
if (ISCOMMA(ex->OP_LEFT)) {
|
||||||
/* embraced member initialisation */
|
/* embraced member initialisation */
|
||||||
if (IVAL(&(tp->tp_up), expr->OP_LEFT) != 0)
|
if (IVAL(&(tp->tp_up), ex->OP_LEFT) != 0)
|
||||||
too_many_initialisers(expr);
|
too_many_initialisers(ex);
|
||||||
expr = expr->OP_RIGHT;
|
ex = ex->OP_RIGHT;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (aggregate_type(tp->tp_up))
|
if (aggregate_type(tp->tp_up))
|
||||||
/* the member is an aggregate */
|
/* the member is an aggregate */
|
||||||
expr = IVAL(&(tp->tp_up), expr);
|
ex = IVAL(&(tp->tp_up), ex);
|
||||||
else {
|
else {
|
||||||
check_ival(expr->OP_LEFT, tp->tp_up);
|
check_ival(ex->OP_LEFT, tp->tp_up);
|
||||||
expr = expr->OP_RIGHT;
|
ex = ex->OP_RIGHT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (expr && elem_count == dim)
|
if (ex && elem_count == dim)
|
||||||
/* all the members are initialised but there
|
/* all the members are initialised but there
|
||||||
remains a part of the expression tree which
|
remains a part of the expression tree which
|
||||||
is returned
|
is returned
|
||||||
*/
|
*/
|
||||||
return expr;
|
return ex;
|
||||||
if ((expr == 0) && elem_count < dim) {
|
if ((ex == 0) && elem_count < dim) {
|
||||||
/* the expression tree is completely absorbed
|
/* the expression tree is completely absorbed
|
||||||
but there are still members which must be
|
but there are still members which must be
|
||||||
initialised with zeroes
|
initialised with zeroes
|
||||||
|
@ -214,31 +214,31 @@ do_array(expr, tpp)
|
||||||
during which alignment is taken care of.
|
during which alignment is taken care of.
|
||||||
*/
|
*/
|
||||||
struct expr *
|
struct expr *
|
||||||
do_struct(expr, tp)
|
do_struct(ex, tp)
|
||||||
struct expr *expr;
|
struct expr *ex;
|
||||||
struct type *tp;
|
struct type *tp;
|
||||||
{
|
{
|
||||||
struct sdef *sd = tp->tp_sdef;
|
struct sdef *sd = tp->tp_sdef;
|
||||||
arith bytes_upto_here = (arith)0;
|
arith bytes_upto_here = (arith)0;
|
||||||
arith last_offset = (arith)-1;
|
arith last_offset = (arith)-1;
|
||||||
|
|
||||||
ASSERT(tp->tp_fund == STRUCT && ISCOMMA(expr));
|
ASSERT(tp->tp_fund == STRUCT && ISCOMMA(ex));
|
||||||
/* as long as there are selectors and there is an initialiser.. */
|
/* as long as there are selectors and there is an initialiser.. */
|
||||||
while (sd && expr) {
|
while (sd && ex) {
|
||||||
if (ISCOMMA(expr->OP_LEFT)) { /* embraced expression */
|
if (ISCOMMA(ex->OP_LEFT)) { /* embraced expression */
|
||||||
if (IVAL(&(sd->sd_type), expr->OP_LEFT) != 0)
|
if (IVAL(&(sd->sd_type), ex->OP_LEFT) != 0)
|
||||||
too_many_initialisers(expr);
|
too_many_initialisers(ex);
|
||||||
expr = expr->OP_RIGHT;
|
ex = ex->OP_RIGHT;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (aggregate_type(sd->sd_type))
|
if (aggregate_type(sd->sd_type))
|
||||||
/* selector is an aggregate itself */
|
/* selector is an aggregate itself */
|
||||||
expr = IVAL(&(sd->sd_type), expr);
|
ex = IVAL(&(sd->sd_type), ex);
|
||||||
else {
|
else {
|
||||||
#ifdef NOBITFIELD
|
#ifdef NOBITFIELD
|
||||||
/* fundamental type, not embraced */
|
/* fundamental type, not embraced */
|
||||||
check_ival(expr->OP_LEFT, sd->sd_type);
|
check_ival(ex->OP_LEFT, sd->sd_type);
|
||||||
expr = expr->OP_RIGHT;
|
ex = ex->OP_RIGHT;
|
||||||
#else
|
#else
|
||||||
if (is_anon_idf(sd->sd_idf))
|
if (is_anon_idf(sd->sd_idf))
|
||||||
/* a hole in the struct due to
|
/* a hole in the struct due to
|
||||||
|
@ -248,9 +248,9 @@ do_struct(expr, tp)
|
||||||
put_bf(sd->sd_type, (arith)0);
|
put_bf(sd->sd_type, (arith)0);
|
||||||
else {
|
else {
|
||||||
/* fundamental type, not embraced */
|
/* fundamental type, not embraced */
|
||||||
check_ival(expr->OP_LEFT,
|
check_ival(ex->OP_LEFT,
|
||||||
sd->sd_type);
|
sd->sd_type);
|
||||||
expr = expr->OP_RIGHT;
|
ex = ex->OP_RIGHT;
|
||||||
}
|
}
|
||||||
#endif NOBITFIELD
|
#endif NOBITFIELD
|
||||||
}
|
}
|
||||||
|
@ -266,8 +266,8 @@ do_struct(expr, tp)
|
||||||
}
|
}
|
||||||
sd = sd->sd_sdef;
|
sd = sd->sd_sdef;
|
||||||
}
|
}
|
||||||
/* perfect fit if (expr && (sd == 0)) holds */
|
/* perfect fit if (ex && (sd == 0)) holds */
|
||||||
if ((expr == 0) && (sd != 0)) {
|
if ((ex == 0) && (sd != 0)) {
|
||||||
/* there are selectors left which must be padded with
|
/* there are selectors left which must be padded with
|
||||||
zeroes
|
zeroes
|
||||||
*/
|
*/
|
||||||
|
@ -284,7 +284,7 @@ do_struct(expr, tp)
|
||||||
/* keep on aligning... */
|
/* keep on aligning... */
|
||||||
while (bytes_upto_here++ < tp->tp_size)
|
while (bytes_upto_here++ < tp->tp_size)
|
||||||
con_nullbyte();
|
con_nullbyte();
|
||||||
return expr;
|
return ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check_and_pad() is given a simple initialisation expression
|
/* check_and_pad() is given a simple initialisation expression
|
||||||
|
@ -292,17 +292,17 @@ do_struct(expr, tp)
|
||||||
In the latter case, only the first member is initialised and
|
In the latter case, only the first member is initialised and
|
||||||
the rest is zeroed.
|
the rest is zeroed.
|
||||||
*/
|
*/
|
||||||
check_and_pad(expr, tpp)
|
check_and_pad(ex, tpp)
|
||||||
struct expr *expr;
|
struct expr *ex;
|
||||||
struct type **tpp;
|
struct type **tpp;
|
||||||
{
|
{
|
||||||
/* expr is of a fundamental type */
|
/* ex is of a fundamental type */
|
||||||
struct type *tp = *tpp;
|
struct type *tp = *tpp;
|
||||||
|
|
||||||
if (tp->tp_fund == ARRAY) {
|
if (tp->tp_fund == ARRAY) {
|
||||||
if (valid_type(tp->tp_up, "array element") == 0)
|
if (valid_type(tp->tp_up, "array element") == 0)
|
||||||
return;
|
return;
|
||||||
check_and_pad(expr, &(tp->tp_up)); /* first member */
|
check_and_pad(ex, &(tp->tp_up)); /* first member */
|
||||||
if (tp->tp_size == (arith)-1)
|
if (tp->tp_size == (arith)-1)
|
||||||
/* no size specified upto here: just
|
/* no size specified upto here: just
|
||||||
set it to the size of one member.
|
set it to the size of one member.
|
||||||
|
@ -321,7 +321,7 @@ check_and_pad(expr, tpp)
|
||||||
|
|
||||||
if (valid_type(tp, "struct") == 0)
|
if (valid_type(tp, "struct") == 0)
|
||||||
return;
|
return;
|
||||||
check_and_pad(expr, &(sd->sd_type));
|
check_and_pad(ex, &(sd->sd_type));
|
||||||
/* Next selector is aligned by adding extra zeroes */
|
/* Next selector is aligned by adding extra zeroes */
|
||||||
if (sd->sd_sdef)
|
if (sd->sd_sdef)
|
||||||
zero_bytes(sd);
|
zero_bytes(sd);
|
||||||
|
@ -332,7 +332,7 @@ check_and_pad(expr, tpp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* simple type */
|
else /* simple type */
|
||||||
check_ival(expr, tp);
|
check_ival(ex, tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pad() fills an element of type tp with zeroes.
|
/* pad() fills an element of type tp with zeroes.
|
||||||
|
@ -404,9 +404,9 @@ pad(tp)
|
||||||
No further comment is needed to explain the internal structure
|
No further comment is needed to explain the internal structure
|
||||||
of this straightforward function.
|
of this straightforward function.
|
||||||
*/
|
*/
|
||||||
check_ival(expr, type)
|
check_ival(ex, tp)
|
||||||
struct expr *expr;
|
struct expr *ex;
|
||||||
struct type *type;
|
struct type *tp;
|
||||||
{
|
{
|
||||||
/* The philosophy here is that ch7cast puts an explicit
|
/* The philosophy here is that ch7cast puts an explicit
|
||||||
conversion node in front of the expression if the types
|
conversion node in front of the expression if the types
|
||||||
|
@ -414,88 +414,81 @@ check_ival(expr, type)
|
||||||
expression is no longer a constant.
|
expression is no longer a constant.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch (type->tp_fund) {
|
switch (tp->tp_fund) {
|
||||||
case CHAR:
|
case CHAR:
|
||||||
case SHORT:
|
case SHORT:
|
||||||
case INT:
|
case INT:
|
||||||
case LONG:
|
case LONG:
|
||||||
case ENUM:
|
case ENUM:
|
||||||
ch7cast(&expr, '=', type);
|
case POINTER:
|
||||||
if (is_cp_cst(expr))
|
ch7cast(&ex, '=', tp);
|
||||||
con_int(expr);
|
#ifdef DEBUG
|
||||||
|
print_expr("init-expr after cast", ex);
|
||||||
|
#endif DEBUG
|
||||||
|
if (!is_ld_cst(ex))
|
||||||
|
illegal_init_cst(ex);
|
||||||
else
|
else
|
||||||
illegal_init_cst(expr);
|
if (ex->VL_CLASS == Const)
|
||||||
break;
|
con_int(ex);
|
||||||
#ifndef NOBITFIELD
|
|
||||||
case FIELD:
|
|
||||||
ch7cast(&expr, '=', type->tp_up);
|
|
||||||
if (is_cp_cst(expr))
|
|
||||||
put_bf(type, expr->VL_VALUE);
|
|
||||||
else
|
else
|
||||||
illegal_init_cst(expr);
|
if (ex->VL_CLASS == Name) {
|
||||||
|
register struct idf *id = ex->VL_IDF;
|
||||||
|
register struct def *df = id->id_def;
|
||||||
|
|
||||||
|
if (df->df_level >= L_LOCAL)
|
||||||
|
illegal_init_cst(ex);
|
||||||
|
else /* e.g., int f(); int p = f; */
|
||||||
|
if (df->df_type->tp_fund == FUNCTION)
|
||||||
|
C_con_pnam(id->id_text);
|
||||||
|
else /* e.g., int a; int *p = &a; */
|
||||||
|
C_con_dnam(id->id_text, ex->VL_VALUE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ASSERT(ex->VL_CLASS == Label);
|
||||||
|
C_con_dlb(ex->VL_LBL, ex->VL_VALUE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
#endif NOBITFIELD
|
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
case DOUBLE:
|
case DOUBLE:
|
||||||
ch7cast(&expr, '=', type);
|
ch7cast(&ex, '=', tp);
|
||||||
if (expr->ex_class == Float)
|
#ifdef DEBUG
|
||||||
C_con_fcon(expr->FL_VALUE, expr->ex_type->tp_size);
|
print_expr("init-expr after cast", ex);
|
||||||
|
#endif DEBUG
|
||||||
|
if (ex->ex_class == Float)
|
||||||
|
C_con_fcon(ex->FL_VALUE, ex->ex_type->tp_size);
|
||||||
else
|
else
|
||||||
if (expr->ex_class == Oper && expr->OP_OPER == INT2FLOAT) {
|
if (ex->ex_class == Oper && ex->OP_OPER == INT2FLOAT) {
|
||||||
expr = expr->OP_RIGHT;
|
/* float f = 1; */
|
||||||
if (is_cp_cst(expr))
|
ex = ex->OP_RIGHT;
|
||||||
|
if (is_cp_cst(ex))
|
||||||
C_con_fcon(
|
C_con_fcon(
|
||||||
long2str((long)expr->VL_VALUE, 10),
|
long2str((long)ex->VL_VALUE, 10),
|
||||||
type->tp_size
|
tp->tp_size
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
illegal_init_cst(expr);
|
illegal_init_cst(ex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
illegal_init_cst(expr);
|
illegal_init_cst(ex);
|
||||||
break;
|
break;
|
||||||
case POINTER:
|
|
||||||
ch7cast(&expr, '=', type);
|
|
||||||
switch (expr->ex_class) {
|
|
||||||
case Oper:
|
|
||||||
illegal_init_cst(expr);
|
|
||||||
break;
|
|
||||||
case Value:
|
|
||||||
{
|
|
||||||
ASSERT(expr->ex_type->tp_fund == POINTER);
|
|
||||||
if (expr->ex_type->tp_up->tp_fund == FUNCTION) {
|
|
||||||
if (expr->VL_CLASS == Name)
|
|
||||||
C_con_pnam(expr->VL_IDF->id_text);
|
|
||||||
else /* int (*func)() = 0 */
|
|
||||||
con_int(expr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (expr->VL_CLASS == Name) {
|
|
||||||
register struct idf *id = expr->VL_IDF;
|
|
||||||
|
|
||||||
if (id ->id_def->df_level >= L_LOCAL)
|
#ifndef NOBITFIELD
|
||||||
expr_error(expr,
|
case FIELD:
|
||||||
"illegal initialisation");
|
ch7cast(&ex, '=', tp->tp_up);
|
||||||
else
|
#ifdef DEBUG
|
||||||
C_con_dnam(id->id_text, expr->VL_VALUE);
|
print_expr("init-expr after cast", ex);
|
||||||
}
|
#endif DEBUG
|
||||||
else
|
if (is_cp_cst(ex))
|
||||||
if (expr->VL_CLASS == Label)
|
put_bf(tp, ex->VL_VALUE);
|
||||||
C_con_dlb(expr->VL_LBL, expr->VL_VALUE);
|
else
|
||||||
else
|
illegal_init_cst(ex);
|
||||||
con_int(expr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case String:
|
|
||||||
default:
|
|
||||||
crash("(check_ival) illegal value class");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
#endif NOBITFIELD
|
||||||
|
|
||||||
case ERRONEOUS:
|
case ERRONEOUS:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
crash("(check_ival) bad fundamental type %s",
|
crash("check_ival");
|
||||||
symbol2str(type->tp_fund));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,17 +496,17 @@ check_ival(expr, type)
|
||||||
a string constant.
|
a string constant.
|
||||||
Alignment is taken care of.
|
Alignment is taken care of.
|
||||||
*/
|
*/
|
||||||
init_string(tpp, expr)
|
init_string(tpp, ex)
|
||||||
struct type **tpp; /* type tp = array of characters */
|
struct type **tpp; /* type tp = array of characters */
|
||||||
struct expr *expr;
|
struct expr *ex;
|
||||||
{
|
{
|
||||||
register struct type *tp = *tpp;
|
register struct type *tp = *tpp;
|
||||||
register arith length;
|
register arith length;
|
||||||
char *s = expr->SG_VALUE;
|
char *s = ex->SG_VALUE;
|
||||||
arith ntopad;
|
arith ntopad;
|
||||||
|
|
||||||
ASSERT(expr->ex_class == String);
|
ASSERT(ex->ex_class == String);
|
||||||
length = expr->SG_LEN;
|
length = ex->SG_LEN;
|
||||||
if (tp->tp_size == (arith)-1) {
|
if (tp->tp_size == (arith)-1) {
|
||||||
/* set the dimension */
|
/* set the dimension */
|
||||||
tp = *tpp = construct_type(ARRAY, tp->tp_up, length);
|
tp = *tpp = construct_type(ARRAY, tp->tp_up, length);
|
||||||
|
@ -524,7 +517,7 @@ init_string(tpp, expr)
|
||||||
|
|
||||||
ntopad = align(dim, word_align) - length;
|
ntopad = align(dim, word_align) - length;
|
||||||
if (length > dim)
|
if (length > dim)
|
||||||
expr_error(expr,
|
expr_error(ex,
|
||||||
"too many characters in initialiser string");
|
"too many characters in initialiser string");
|
||||||
}
|
}
|
||||||
/* throw out the characters of the already prepared string */
|
/* throw out the characters of the already prepared string */
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
User options:
|
User options:
|
||||||
|
|
||||||
C while running preprocessor, copy comment
|
C while running preprocessor, copy comment
|
||||||
D see identifier following as a macro
|
D see identifier following as a macro
|
||||||
E run preprocessor only
|
E run preprocessor only
|
||||||
|
|
Loading…
Reference in a new issue