fixed int to unsigned conversions, declarations, pp-list initialization
This commit is contained in:
parent
63fe4e0a18
commit
7f5abdd670
8 changed files with 132 additions and 113 deletions
|
@ -342,10 +342,11 @@ garbage:
|
|||
}
|
||||
#endif NOPP
|
||||
ptok->tk_symb = (
|
||||
idef->id_reserved ? idef->id_reserved
|
||||
: idef->id_def && idef->id_def->df_sc == TYPEDEF ?
|
||||
TYPE_IDENTIFIER
|
||||
: IDENTIFIER
|
||||
idef->id_reserved
|
||||
? idef->id_reserved
|
||||
: idef->id_def && idef->id_def->df_sc == TYPEDEF
|
||||
? TYPE_IDENTIFIER
|
||||
: IDENTIFIER
|
||||
);
|
||||
return IDENTIFIER;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,14 @@ conversion(from_type, to_type)
|
|||
C_cii();
|
||||
from_size = word_size;
|
||||
}
|
||||
/* 3.2.1.2 */
|
||||
if (to_cnvtype == T_UNSIGNED
|
||||
&& (int)from_size < (int)to_size) {
|
||||
C_loc(from_size);
|
||||
C_loc(to_size);
|
||||
C_cii();
|
||||
from_size = to_size;
|
||||
}
|
||||
C_loc(from_size);
|
||||
C_loc(to_size);
|
||||
if (to_cnvtype == T_UNSIGNED) C_ciu();
|
||||
|
|
|
@ -67,28 +67,43 @@ declaration
|
|||
short typedef yepp;
|
||||
makes all hope of writing a specific grammar for typedefs illusory.
|
||||
*/
|
||||
/* We do not accept the whole of the grammar, since when we see
|
||||
something like 'unsigned plain' (where plain is a typedef) is
|
||||
illegal if 'plain' is a typedef. Therefore, we assume that
|
||||
'plain' is the identifier of a declarator. Unfortunately, this
|
||||
causes declarations like 'unsigned plain x;' to be rejected on the
|
||||
grounds of syntax, even though it is syntactically right. This may
|
||||
cause a lot of extra messages.
|
||||
To do this, decl_specifiers is divided into:
|
||||
1: normal specifiers == storage class specifiers + type_qualifiers
|
||||
2: special specifiers == short + long + signed + unsigned
|
||||
3: basic types == void + char + int + float + double
|
||||
4: single type specifiers == struct or union specifiers
|
||||
+ enum specifiers + typedef names
|
||||
|
||||
*/
|
||||
decl_specifiers /* non-empty */ (register struct decspecs *ds;)
|
||||
/* Reads a non-empty decl_specifiers and fills the struct
|
||||
decspecs *ds.
|
||||
*/
|
||||
:
|
||||
[
|
||||
other_specifier(ds)+
|
||||
[%if (DOT != IDENTIFIER || AHEAD == IDENTIFIER)
|
||||
/* the thin ice in R.M. 11.1 */
|
||||
single_type_specifier(ds) other_specifier(ds)*
|
||||
|
|
||||
empty
|
||||
]
|
||||
[ %if (AHEAD == IDENTIFIER) /* like: register i; */
|
||||
normal_specifier(ds)
|
||||
|
|
||||
single_type_specifier(ds) other_specifier(ds)*
|
||||
normal_specifier(ds)*
|
||||
[ special_specifier(ds)
|
||||
| basic_type(ds)
|
||||
| single_type_specifier(ds)
|
||||
]
|
||||
[ normal_specifier(ds)
|
||||
| special_specifier(ds)
|
||||
| basic_type(ds)
|
||||
]*
|
||||
]
|
||||
{do_decspecs(ds);}
|
||||
;
|
||||
|
||||
/* 3.5.1 & 3.5.2 (partially) & 3.5.3 (partially) */
|
||||
other_specifier(register struct decspecs *ds;)
|
||||
normal_specifier(register struct decspecs *ds;)
|
||||
:
|
||||
[ AUTO | STATIC | EXTERN | TYPEDEF | REGISTER ]
|
||||
{ if (ds->ds_sc_given)
|
||||
|
@ -96,18 +111,6 @@ other_specifier(register struct decspecs *ds;)
|
|||
ds->ds_sc_given = 1;
|
||||
ds->ds_sc = DOT;
|
||||
}
|
||||
|
|
||||
[ SHORT | LONG ]
|
||||
{ if (ds->ds_size)
|
||||
error("repeated size specifier");
|
||||
ds->ds_size = DOT;
|
||||
}
|
||||
|
|
||||
[ SIGNED | UNSIGNED ]
|
||||
{ if (ds->ds_unsigned != 0)
|
||||
error("repeated sign specifier");
|
||||
ds->ds_unsigned = DOT;
|
||||
}
|
||||
|
|
||||
/* This qualifier applies to the top type.
|
||||
E.g. volatile float * is a pointer to volatile float.
|
||||
|
@ -129,6 +132,21 @@ other_specifier(register struct decspecs *ds;)
|
|||
}
|
||||
;
|
||||
|
||||
special_specifier(register struct decspecs *ds;)
|
||||
:
|
||||
[ SHORT | LONG ]
|
||||
{ if (ds->ds_size)
|
||||
error("repeated size specifier");
|
||||
ds->ds_size = DOT;
|
||||
}
|
||||
|
|
||||
[ SIGNED | UNSIGNED ]
|
||||
{ if (ds->ds_unsigned != 0)
|
||||
error("repeated sign specifier");
|
||||
ds->ds_unsigned = DOT;
|
||||
}
|
||||
;
|
||||
|
||||
/* 3.5.2 */
|
||||
type_specifier(struct type **tpp;)
|
||||
/* Used in struct/union declarations and in casts; only the
|
||||
|
@ -146,9 +164,20 @@ type_specifier(struct type **tpp;)
|
|||
{*tpp = Ds.ds_type;}
|
||||
;
|
||||
|
||||
basic_type(register struct decspecs *ds;):
|
||||
[ VOID | CHAR | INT | FLOAT | DOUBLE ]
|
||||
{
|
||||
idf2type(dot.tk_idf, &ds->ds_type);
|
||||
ds->ds_typedef = 0;
|
||||
}
|
||||
;
|
||||
|
||||
single_type_specifier(register struct decspecs *ds;):
|
||||
%default TYPE_IDENTIFIER /* this includes INT, CHAR, etc. */
|
||||
{idf2type(dot.tk_idf, &ds->ds_type);}
|
||||
{
|
||||
idf2type(dot.tk_idf, &ds->ds_type);
|
||||
ds->ds_typedef = 1;
|
||||
}
|
||||
|
|
||||
IDENTIFIER
|
||||
{
|
||||
|
@ -283,7 +312,7 @@ declarator(register struct declarator *dc;)
|
|||
|
|
||||
formal_list(&fm)
|
||||
|
|
||||
empty
|
||||
/* empty */
|
||||
]
|
||||
')'
|
||||
{ add_decl_unary(dc, FUNCTION, 0, (arith)0, fm, pl);
|
||||
|
@ -308,6 +337,7 @@ arrayer(arith *sizep;)
|
|||
{ struct expr *expr; }
|
||||
:
|
||||
'['
|
||||
{ *sizep = (arith)-1; }
|
||||
[
|
||||
constant_expression(&expr)
|
||||
{
|
||||
|
@ -315,10 +345,7 @@ arrayer(arith *sizep;)
|
|||
*sizep = expr->VL_VALUE;
|
||||
free_expression(expr);
|
||||
}
|
||||
|
|
||||
empty
|
||||
{ *sizep = (arith)-1; }
|
||||
]
|
||||
]?
|
||||
']'
|
||||
;
|
||||
|
||||
|
@ -358,7 +385,7 @@ enum_specifier(register struct type **tpp;)
|
|||
enumerator_pack(*tpp, &l)
|
||||
|
|
||||
{apply_struct(ENUM, idf, tpp);}
|
||||
empty
|
||||
/* empty */
|
||||
]
|
||||
]
|
||||
;
|
||||
|
@ -433,7 +460,7 @@ struct_or_union_specifier(register struct type **tpp;)
|
|||
if (DOT == ';') declare_struct(fund, idf, tpp);
|
||||
else apply_struct(fund, idf, tpp);
|
||||
}
|
||||
empty
|
||||
/* empty */
|
||||
]
|
||||
]
|
||||
;
|
||||
|
@ -533,7 +560,7 @@ abstract_declarator(register struct declarator *dc;)
|
|||
[
|
||||
parameter_type_list(&pl)
|
||||
|
|
||||
empty
|
||||
/* empty */
|
||||
]
|
||||
')'
|
||||
{add_decl_unary(dc, FUNCTION, 0, (arith)0, NO_PARAMS, pl);}
|
||||
|
@ -551,7 +578,7 @@ abstract_declarator(register struct declarator *dc;)
|
|||
primary_abstract_declarator(struct declarator *dc;)
|
||||
:
|
||||
[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD))
|
||||
empty
|
||||
/* empty */
|
||||
|
|
||||
'(' abstract_declarator(dc) ')'
|
||||
]
|
||||
|
@ -663,7 +690,7 @@ primary_parameter_declarator(register struct declarator *dc;)
|
|||
:
|
||||
[%if (AHEAD == ')' || first_of_parameter_type_list(AHEAD)
|
||||
&& (AHEAD != IDENTIFIER))
|
||||
empty
|
||||
/* empty */
|
||||
|
|
||||
identifier(&dc->dc_idf)
|
||||
|
|
||||
|
|
|
@ -71,62 +71,42 @@ do_decspecs(ds)
|
|||
ds->ds_notypegiven = 1;
|
||||
tp = int_type;
|
||||
}
|
||||
switch (ds->ds_size) {
|
||||
case SHORT:
|
||||
if (tp == int_type)
|
||||
tp = short_type;
|
||||
else
|
||||
error("short with illegal type");
|
||||
break;
|
||||
case LONG:
|
||||
if (tp == int_type)
|
||||
tp = long_type;
|
||||
else
|
||||
if (tp == double_type)
|
||||
tp = lngdbl_type;
|
||||
else
|
||||
error("long with illegal type");
|
||||
break;
|
||||
}
|
||||
if (ds->ds_unsigned == UNSIGNED) {
|
||||
switch (tp->tp_fund) {
|
||||
case CHAR:
|
||||
tp = uchar_type;
|
||||
break;
|
||||
case SHORT:
|
||||
tp = ushort_type;
|
||||
break;
|
||||
case INT:
|
||||
tp = uint_type;
|
||||
break;
|
||||
case LONG:
|
||||
tp = ulong_type;
|
||||
break;
|
||||
default:
|
||||
error("unsigned with illegal type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ds->ds_unsigned == SIGNED) {
|
||||
switch (tp->tp_fund) {
|
||||
case CHAR:
|
||||
tp = schar_type;
|
||||
break;
|
||||
case SHORT:
|
||||
tp = short_type;
|
||||
break;
|
||||
case INT:
|
||||
tp = int_type;
|
||||
break;
|
||||
case LONG:
|
||||
tp = long_type;
|
||||
break;
|
||||
default:
|
||||
error("signed with illegal type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ds->ds_size) {
|
||||
register int ds_isshort = (ds->ds_size == SHORT);
|
||||
|
||||
if (ds->ds_typedef) goto SIZE_ERROR; /* yes */
|
||||
if (tp == int_type) {
|
||||
if (ds_isshort) tp = short_type;
|
||||
else tp = long_type;
|
||||
} else if (tp == double_type && !ds_isshort ) {
|
||||
tp = lngdbl_type;
|
||||
} else {
|
||||
SIZE_ERROR:
|
||||
error("%s with illegal type",symbol2str(ds->ds_size));
|
||||
}
|
||||
}
|
||||
if (ds->ds_unsigned) {
|
||||
register int ds_isunsigned = (ds->ds_unsigned == UNSIGNED);
|
||||
|
||||
if (ds->ds_typedef) goto SIGN_ERROR; /* yes */
|
||||
/*
|
||||
* All integral types are signed by default (char too),
|
||||
* so the case that ds->ds_unsigned == SIGNED can be ignored.
|
||||
*/
|
||||
if (tp == schar_type) {
|
||||
if (ds_isunsigned) tp = uchar_type;
|
||||
} else if (tp == short_type) {
|
||||
if (ds_isunsigned) tp = ushort_type;
|
||||
} else if (tp == int_type) {
|
||||
if (ds_isunsigned) tp = uint_type;
|
||||
} else if (tp == long_type) {
|
||||
if (ds_isunsigned) tp = ulong_type;
|
||||
} else {
|
||||
SIGN_ERROR:
|
||||
error("%s with illegal type"
|
||||
, symbol2str(ds->ds_unsigned));
|
||||
}
|
||||
}
|
||||
ds->ds_type = qualifier_type(tp, ds->ds_typequal);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ struct decspecs {
|
|||
struct decspecs *next;
|
||||
struct type *ds_type; /* single type */
|
||||
int ds_notypegiven; /* set if type not given explicitly */
|
||||
int ds_typedef; /* 1 if type was a user typedef */
|
||||
int ds_sc_given; /* 1 if the st. class is explicitly given */
|
||||
int ds_sc; /* storage class, given or implied */
|
||||
int ds_size; /* LONG, SHORT or 0 */
|
||||
|
|
|
@ -175,21 +175,14 @@ deleted, is now a debug-flag
|
|||
register char *new = text;
|
||||
|
||||
if (++inc_total > inc_max) {
|
||||
char **n = (char **)
|
||||
Malloc((10+inc_max)*sizeof(char *));
|
||||
for (i = 0; i < inc_max; i++) {
|
||||
n[i] = inctable[i];
|
||||
}
|
||||
free((char *) inctable);
|
||||
inctable = n;
|
||||
inc_max += 10;
|
||||
inctable = (char **)
|
||||
Realloc(inctable,(inc_max+=10)*sizeof(char *));
|
||||
}
|
||||
|
||||
i = inc_pos++;
|
||||
while (new) {
|
||||
for (i = inc_pos++; i<= inc_total ; i++) {
|
||||
char *tmp = inctable[i];
|
||||
|
||||
inctable[i++] = new;
|
||||
inctable[i] = new;
|
||||
new = tmp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,18 +91,26 @@ struct tokenname tkidf[] = { /* names of the identifier tokens */
|
|||
{UNSIGNED, "unsigned"},
|
||||
{VOLATILE, "volatile"},
|
||||
{WHILE, "while"},
|
||||
|
||||
{VOID, "void"},
|
||||
{CHAR, "char"},
|
||||
{INT, "int"},
|
||||
{FLOAT, "float"},
|
||||
{DOUBLE, "double"},
|
||||
{0, ""}
|
||||
};
|
||||
|
||||
#ifdef ____
|
||||
struct tokenname tkfunny[] = { /* internal keywords */
|
||||
{CHAR, "char"},
|
||||
{INT, "int"},
|
||||
{FLOAT, "float"},
|
||||
{DOUBLE, "double"},
|
||||
/* The following may be removed after testing:
|
||||
{Q_VOID, "void"},
|
||||
{Q_CHAR, "char"},
|
||||
{Q_INT, "int"},
|
||||
{Q_FLOAT, "float"},
|
||||
{Q_DOUBLE, "double"},
|
||||
*/
|
||||
{LNGDBL, "long double"},
|
||||
{ULONG, "unsigned long"},
|
||||
{VOID, "void"},
|
||||
|
||||
{ARRAY, "array"},
|
||||
{FUNCTION, "function"},
|
||||
|
|
|
@ -249,13 +249,14 @@ idf2type(idf, tpp)
|
|||
struct idf *idf;
|
||||
struct type **tpp;
|
||||
{
|
||||
/* Decoding a typedef-ed identifier: if the size is yet
|
||||
unknown we have to make copy of the type descriptor to
|
||||
prevent garbage at the initialisation of arrays with
|
||||
unknown size.
|
||||
/* Decoding a typedef-ed identifier or basic type: if the
|
||||
size is yet unknown we have to make copy of the type
|
||||
descriptor to prevent garbage at the initialisation of
|
||||
arrays with unknown size.
|
||||
*/
|
||||
register struct type *tp = idf->id_def->df_type;
|
||||
|
||||
if (*tpp) error("multiple types in declaration");
|
||||
if ( tp->tp_size < (arith)0 && tp->tp_fund == ARRAY) {
|
||||
*tpp = new_type();
|
||||
**tpp = *tp;
|
||||
|
|
Loading…
Reference in a new issue