New version with different parameter passing mechanism and some
minor fixes
This commit is contained in:
parent
346bc839a3
commit
f9b6acf1dc
15 changed files with 197 additions and 105 deletions
|
@ -152,9 +152,11 @@ GetString(upto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
str->s_length = p - str->s_str;
|
str->s_length = p - str->s_str;
|
||||||
*p = '\0';
|
len = (str->s_length+(int)word_size) & ~((int)word_size-1);
|
||||||
str->s_str = Realloc(str->s_str,
|
while (p - str->s_str < len) {
|
||||||
(unsigned)((str->s_length+(int)word_size) & ~((int)word_size-1)));
|
*p++ = '\0';
|
||||||
|
}
|
||||||
|
str->s_str = Realloc(str->s_str, (unsigned) len);
|
||||||
if (str->s_length == 0) str->s_length = 1;
|
if (str->s_length == 0) str->s_length = 1;
|
||||||
/* ??? string length at least 1 ??? */
|
/* ??? string length at least 1 ??? */
|
||||||
return str;
|
return str;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
static char Version[] = "ACK Modula-2 compiler Version 0.47";
|
static char Version[] = "ACK Modula-2 compiler Version 0.48";
|
||||||
|
|
|
@ -77,7 +77,8 @@ compact(nr, low, up)
|
||||||
diff / nr <= (DENSITY - 1));
|
diff / nr <= (DENSITY - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
CaseCode(nd, exitlabel)
|
int
|
||||||
|
CaseCode(nd, exitlabel, end_reached)
|
||||||
t_node *nd;
|
t_node *nd;
|
||||||
label exitlabel;
|
label exitlabel;
|
||||||
{
|
{
|
||||||
|
@ -91,6 +92,7 @@ CaseCode(nd, exitlabel)
|
||||||
register struct case_entry *ce;
|
register struct case_entry *ce;
|
||||||
register arith val;
|
register arith val;
|
||||||
label CaseDescrLab;
|
label CaseDescrLab;
|
||||||
|
int rval;
|
||||||
|
|
||||||
assert(pnode->nd_class == Stat && pnode->nd_symb == CASE);
|
assert(pnode->nd_class == Stat && pnode->nd_symb == CASE);
|
||||||
|
|
||||||
|
@ -109,15 +111,12 @@ CaseCode(nd, exitlabel)
|
||||||
/* non-empty case
|
/* non-empty case
|
||||||
*/
|
*/
|
||||||
pnode->nd_lab = ++text_label;
|
pnode->nd_lab = ++text_label;
|
||||||
if (! AddCases(sh, /* to descriptor */
|
AddCases(sh, /* to descriptor */
|
||||||
pnode->nd_left->nd_left,
|
pnode->nd_left->nd_left,
|
||||||
/* of case labels */
|
/* of case labels */
|
||||||
pnode->nd_lab
|
pnode->nd_lab
|
||||||
/* and code label */
|
/* and code label */
|
||||||
)) {
|
);
|
||||||
FreeSh(sh);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -135,8 +134,6 @@ CaseCode(nd, exitlabel)
|
||||||
*/
|
*/
|
||||||
if (! (sh->sh_type->tp_fund & T_DISCRETE)) {
|
if (! (sh->sh_type->tp_fund & T_DISCRETE)) {
|
||||||
node_error(nd, "illegal type in CASE-expression");
|
node_error(nd, "illegal type in CASE-expression");
|
||||||
FreeSh(sh);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,12 +181,13 @@ CaseCode(nd, exitlabel)
|
||||||
/* Now generate code for the cases
|
/* Now generate code for the cases
|
||||||
*/
|
*/
|
||||||
pnode = nd;
|
pnode = nd;
|
||||||
|
rval = 0;
|
||||||
while (pnode = pnode->nd_right) {
|
while (pnode = pnode->nd_right) {
|
||||||
if (pnode->nd_class == Link && pnode->nd_symb == '|') {
|
if (pnode->nd_class == Link && pnode->nd_symb == '|') {
|
||||||
if (pnode->nd_left) {
|
if (pnode->nd_left) {
|
||||||
LblWalkNode(pnode->nd_lab,
|
rval |= LblWalkNode(pnode->nd_lab,
|
||||||
pnode->nd_left->nd_right,
|
pnode->nd_left->nd_right,
|
||||||
exitlabel);
|
exitlabel, end_reached);
|
||||||
C_bra(sh->sh_break);
|
C_bra(sh->sh_break);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,13 +196,15 @@ CaseCode(nd, exitlabel)
|
||||||
*/
|
*/
|
||||||
assert(sh->sh_default != 0);
|
assert(sh->sh_default != 0);
|
||||||
|
|
||||||
LblWalkNode(sh->sh_default, pnode, exitlabel);
|
rval |= LblWalkNode(sh->sh_default,
|
||||||
|
pnode, exitlabel, end_reached);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def_ilb(sh->sh_break);
|
def_ilb(sh->sh_break);
|
||||||
FreeSh(sh);
|
FreeSh(sh);
|
||||||
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeSh(sh)
|
FreeSh(sh)
|
||||||
|
@ -241,22 +241,23 @@ AddCases(sh, node, lbl)
|
||||||
node->nd_type = node->nd_left->nd_type;
|
node->nd_type = node->nd_left->nd_type;
|
||||||
node->nd_INT = node->nd_left->nd_INT;
|
node->nd_INT = node->nd_left->nd_INT;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (! AddOneCase(sh, node, lbl)) return 0;
|
AddOneCase(sh, node, lbl);
|
||||||
if (node->nd_INT == node->nd_right->nd_INT) {
|
if (node->nd_INT == node->nd_right->nd_INT) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
node->nd_INT++;
|
node->nd_INT++;
|
||||||
}
|
}
|
||||||
return 1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(node->nd_symb == ',');
|
assert(node->nd_symb == ',');
|
||||||
return AddCases(sh, node->nd_left, lbl) &&
|
AddCases(sh, node->nd_left, lbl);
|
||||||
AddCases(sh, node->nd_right, lbl);
|
AddCases(sh, node->nd_right, lbl);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(node->nd_class == Value);
|
assert(node->nd_class == Value);
|
||||||
return AddOneCase(sh, node, lbl);
|
AddOneCase(sh, node, lbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddOneCase(sh, node, lbl)
|
AddOneCase(sh, node, lbl)
|
||||||
|
@ -271,8 +272,6 @@ AddOneCase(sh, node, lbl)
|
||||||
ce->ce_label = lbl;
|
ce->ce_label = lbl;
|
||||||
ce->ce_value = node->nd_INT;
|
ce->ce_value = node->nd_INT;
|
||||||
if (! ChkCompat(&node, sh->sh_type, "case")) {
|
if (! ChkCompat(&node, sh->sh_type, "case")) {
|
||||||
free_case_entry(ce);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
if (sh->sh_entries == 0) {
|
if (sh->sh_entries == 0) {
|
||||||
/* first case entry
|
/* first case entry
|
||||||
|
@ -311,7 +310,6 @@ AddOneCase(sh, node, lbl)
|
||||||
if (c1->ce_value == ce->ce_value) {
|
if (c1->ce_value == ce->ce_value) {
|
||||||
node_error(node, "multiple case entry for value %ld", ce->ce_value);
|
node_error(node, "multiple case entry for value %ld", ce->ce_value);
|
||||||
free_case_entry(ce);
|
free_case_entry(ce);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
if (c2) {
|
if (c2) {
|
||||||
ce->ce_next = c2->ce_next;
|
ce->ce_next = c2->ce_next;
|
||||||
|
@ -330,5 +328,4 @@ node_error(node, "multiple case entry for value %ld", ce->ce_value);
|
||||||
}
|
}
|
||||||
(sh->sh_nrofentries)++;
|
(sh->sh_nrofentries)++;
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,23 +207,24 @@ ChkArr(expp, flags)
|
||||||
"index type");
|
"index type");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
/*ARGSUSED*/
|
||||||
STATIC int
|
STATIC int
|
||||||
ChkValue(expp)
|
ChkValue(expp)
|
||||||
t_node *expp;
|
t_node *expp;
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
switch(expp->nd_symb) {
|
switch(expp->nd_symb) {
|
||||||
case REAL:
|
case REAL:
|
||||||
case STRING:
|
case STRING:
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
return 1;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
crash("(ChkValue)");
|
crash("(ChkValue)");
|
||||||
}
|
}
|
||||||
/*NOTREACHED*/
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
STATIC int
|
STATIC int
|
||||||
ChkLinkOrName(expp, flags)
|
ChkLinkOrName(expp, flags)
|
||||||
|
@ -430,7 +431,6 @@ MkSet(size)
|
||||||
{
|
{
|
||||||
register arith *s;
|
register arith *s;
|
||||||
|
|
||||||
size = (size / (int) word_size + 1) * sizeof(arith);
|
|
||||||
s = (arith *) Malloc(size);
|
s = (arith *) Malloc(size);
|
||||||
clear((char *) s , size);
|
clear((char *) s , size);
|
||||||
s++;
|
s++;
|
||||||
|
@ -492,7 +492,7 @@ ChkSet(expp)
|
||||||
First allocate room for the set.
|
First allocate room for the set.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
expp->nd_set = MkSet((unsigned)(tp->tp_size));
|
expp->nd_set = MkSet(tp->set_sz);
|
||||||
|
|
||||||
/* Now check the elements, one by one
|
/* Now check the elements, one by one
|
||||||
*/
|
*/
|
||||||
|
@ -1163,7 +1163,7 @@ ChkStandard(expp)
|
||||||
}
|
}
|
||||||
left = getvariable(&arg,
|
left = getvariable(&arg,
|
||||||
edf,
|
edf,
|
||||||
edf->df_value.df_stdname == S_NEW ? D_DEFINED : D_USED);
|
D_USED|D_DEFINED);
|
||||||
expp->nd_type = 0;
|
expp->nd_type = 0;
|
||||||
if (! left) return 0;
|
if (! left) return 0;
|
||||||
if (! (left->nd_type->tp_fund == T_POINTER)) {
|
if (! (left->nd_type->tp_fund == T_POINTER)) {
|
||||||
|
@ -1395,19 +1395,17 @@ no_desig(expp)
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int
|
STATIC int
|
||||||
done_before()
|
add_flags(expp, flags)
|
||||||
|
t_node *expp;
|
||||||
{
|
{
|
||||||
|
expp->nd_def->df_flags |= flags;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int NodeCrash();
|
extern int NodeCrash();
|
||||||
|
|
||||||
int (*ExprChkTable[])() = {
|
int (*ExprChkTable[])() = {
|
||||||
#ifdef DEBUG
|
|
||||||
ChkValue,
|
ChkValue,
|
||||||
#else
|
|
||||||
done_before,
|
|
||||||
#endif
|
|
||||||
ChkArr,
|
ChkArr,
|
||||||
ChkBinOper,
|
ChkBinOper,
|
||||||
ChkUnOper,
|
ChkUnOper,
|
||||||
|
@ -1416,7 +1414,7 @@ int (*ExprChkTable[])() = {
|
||||||
ChkExLinkOrName,
|
ChkExLinkOrName,
|
||||||
NodeCrash,
|
NodeCrash,
|
||||||
ChkSet,
|
ChkSet,
|
||||||
done_before,
|
add_flags,
|
||||||
NodeCrash,
|
NodeCrash,
|
||||||
ChkExLinkOrName,
|
ChkExLinkOrName,
|
||||||
};
|
};
|
||||||
|
@ -1431,7 +1429,7 @@ int (*DesigChkTable[])() = {
|
||||||
ChkLinkOrName,
|
ChkLinkOrName,
|
||||||
NodeCrash,
|
NodeCrash,
|
||||||
no_desig,
|
no_desig,
|
||||||
done_before,
|
add_flags,
|
||||||
NodeCrash,
|
NodeCrash,
|
||||||
ChkLinkOrName,
|
ChkLinkOrName,
|
||||||
};
|
};
|
||||||
|
|
|
@ -417,6 +417,8 @@ CodeParameters(param, arg)
|
||||||
C_loc(left_type->arr_high - left_type->arr_low);
|
C_loc(left_type->arr_high - left_type->arr_low);
|
||||||
}
|
}
|
||||||
c_loc(0);
|
c_loc(0);
|
||||||
|
}
|
||||||
|
if (IsConformantArray(tp) || IsVarParam(param) || IsBigParamTp(tp)) {
|
||||||
if (left->nd_symb == STRING) {
|
if (left->nd_symb == STRING) {
|
||||||
CodeString(left);
|
CodeString(left);
|
||||||
}
|
}
|
||||||
|
@ -438,10 +440,6 @@ CodeParameters(param, arg)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (IsVarParam(param)) {
|
|
||||||
CodeDAddress(left, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (left_type->tp_fund == T_STRING) {
|
if (left_type->tp_fund == T_STRING) {
|
||||||
CodePString(left, tp);
|
CodePString(left, tp);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -371,6 +371,10 @@ cstset(expp)
|
||||||
setsize = (unsigned) (expp->nd_right->nd_type->tp_size) / (unsigned) word_size;
|
setsize = (unsigned) (expp->nd_right->nd_type->tp_size) / (unsigned) word_size;
|
||||||
|
|
||||||
if (expp->nd_symb == IN) {
|
if (expp->nd_symb == IN) {
|
||||||
|
/* The setsize must fit in an unsigned, as it is
|
||||||
|
allocated with Malloc, so we can do the arithmetic
|
||||||
|
in an unsigned too.
|
||||||
|
*/
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
assert(expp->nd_left->nd_class == Value);
|
assert(expp->nd_left->nd_class == Value);
|
||||||
|
@ -378,6 +382,10 @@ cstset(expp)
|
||||||
expp->nd_left->nd_INT -= expp->nd_right->nd_type->set_low;
|
expp->nd_left->nd_INT -= expp->nd_right->nd_type->set_low;
|
||||||
i = expp->nd_left->nd_INT;
|
i = expp->nd_left->nd_INT;
|
||||||
expp->nd_class = Value;
|
expp->nd_class = Value;
|
||||||
|
/* Careful here; use expp->nd_left->nd_INT to see if
|
||||||
|
it falls in the range of the set. Do not use i
|
||||||
|
for this, as i may be truncated.
|
||||||
|
*/
|
||||||
expp->nd_INT = (expp->nd_left->nd_INT >= 0 &&
|
expp->nd_INT = (expp->nd_left->nd_INT >= 0 &&
|
||||||
expp->nd_left->nd_INT < setsize * wrd_bits &&
|
expp->nd_left->nd_INT < setsize * wrd_bits &&
|
||||||
(set2[i / wrd_bits] & (1 << (i % wrd_bits))));
|
(set2[i / wrd_bits] & (1 << (i % wrd_bits))));
|
||||||
|
@ -393,7 +401,7 @@ cstset(expp)
|
||||||
case '-': /* Set difference */
|
case '-': /* Set difference */
|
||||||
case '*': /* Set intersection */
|
case '*': /* Set intersection */
|
||||||
case '/': /* Symmetric set difference */
|
case '/': /* Symmetric set difference */
|
||||||
expp->nd_set = resultset = MkSet(setsize * (unsigned) word_size);
|
expp->nd_set = resultset = MkSet(expp->nd_type->set_sz);
|
||||||
for (j = 0; j < setsize; j++) {
|
for (j = 0; j < setsize; j++) {
|
||||||
switch(expp->nd_symb) {
|
switch(expp->nd_symb) {
|
||||||
case '+':
|
case '+':
|
||||||
|
|
|
@ -402,7 +402,7 @@ CaseLabels(t_type **ptp; register t_node **pnd;)
|
||||||
{
|
{
|
||||||
if (*ptp != 0) {
|
if (*ptp != 0) {
|
||||||
t_type *tp = intorcard(*ptp,
|
t_type *tp = intorcard(*ptp,
|
||||||
BaseType((*pnd)->nd_type), 0);
|
BaseType((*pnd)->nd_type));
|
||||||
if (tp) *ptp = tp;
|
if (tp) *ptp = tp;
|
||||||
ChkCompat(pnd, *ptp, "case label");
|
ChkCompat(pnd, *ptp, "case label");
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ typedef struct desig t_desig;
|
||||||
|
|
||||||
struct withdesig {
|
struct withdesig {
|
||||||
struct withdesig *w_next;
|
struct withdesig *w_next;
|
||||||
|
int w_flags; /* D_USED|D_DEFINED */
|
||||||
struct scope *w_scope; /* scope in which fields of this record
|
struct scope *w_scope; /* scope in which fields of this record
|
||||||
reside
|
reside
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -514,6 +514,7 @@ CodeFieldDesig(df, ds)
|
||||||
/* Found it. Now, act like it was a selection.
|
/* Found it. Now, act like it was a selection.
|
||||||
*/
|
*/
|
||||||
*ds = wds->w_desig;
|
*ds = wds->w_desig;
|
||||||
|
wds->w_flags |= df->df_flags;
|
||||||
assert(ds->dsg_kind == DSG_PFIXED);
|
assert(ds->dsg_kind == DSG_PFIXED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,10 +584,11 @@ CodeVarDesig(df, ds)
|
||||||
*/
|
*/
|
||||||
C_lxa((arith) difflevel);
|
C_lxa((arith) difflevel);
|
||||||
if ((df->df_flags & D_VARPAR) ||
|
if ((df->df_flags & D_VARPAR) ||
|
||||||
|
IsBigParamTp(df->df_type) ||
|
||||||
IsConformantArray(df->df_type)) {
|
IsConformantArray(df->df_type)) {
|
||||||
/* var parameter or conformant array.
|
/* var parameter, big parameter,
|
||||||
For conformant array's, the address is
|
or conformant array.
|
||||||
passed.
|
The address is passed.
|
||||||
*/
|
*/
|
||||||
C_adp(df->var_off);
|
C_adp(df->var_off);
|
||||||
C_loi(pointer_size);
|
C_loi(pointer_size);
|
||||||
|
@ -603,7 +605,9 @@ CodeVarDesig(df, ds)
|
||||||
|
|
||||||
/* Now, finally, we have a local variable or a local parameter
|
/* Now, finally, we have a local variable or a local parameter
|
||||||
*/
|
*/
|
||||||
if ((df->df_flags & D_VARPAR) || IsConformantArray(df->df_type)) {
|
if ((df->df_flags & D_VARPAR) ||
|
||||||
|
((df->df_flags & D_VALPAR) && IsBigParamTp(df->df_type)) ||
|
||||||
|
IsConformantArray(df->df_type)) {
|
||||||
/* a var parameter; address directly accessible.
|
/* a var parameter; address directly accessible.
|
||||||
*/
|
*/
|
||||||
ds->dsg_kind = DSG_PFIXED;
|
ds->dsg_kind = DSG_PFIXED;
|
||||||
|
|
|
@ -222,7 +222,7 @@ EnterParamList(ppr, Idlist, type, VARp, off)
|
||||||
*/
|
*/
|
||||||
*off += pointer_size + word_size + dword_size;
|
*off += pointer_size + word_size + dword_size;
|
||||||
}
|
}
|
||||||
else if (VARp == D_VARPAR) {
|
else if (VARp == D_VARPAR || IsBigParamTp(type)) {
|
||||||
*off += pointer_size;
|
*off += pointer_size;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -53,7 +53,7 @@ main(argc, argv)
|
||||||
register char **Nargv = &argv[0];
|
register char **Nargv = &argv[0];
|
||||||
|
|
||||||
ProgName = *argv++;
|
ProgName = *argv++;
|
||||||
DEFPATH = (char **) Malloc(mDEF * sizeof(char *));
|
DEFPATH = (char **) Malloc((unsigned)mDEF * sizeof(char *));
|
||||||
|
|
||||||
while (--argc > 0) {
|
while (--argc > 0) {
|
||||||
if (**argv == '-')
|
if (**argv == '-')
|
||||||
|
|
|
@ -64,14 +64,16 @@ struct record {
|
||||||
|
|
||||||
struct proc {
|
struct proc {
|
||||||
struct paramlist *pr_params;
|
struct paramlist *pr_params;
|
||||||
arith pr_nbpar;
|
arith pr_nbpar; /* number of bytes parameters accessed */
|
||||||
#define prc_params tp_value.tp_proc.pr_params
|
#define prc_params tp_value.tp_proc.pr_params
|
||||||
#define prc_nbpar tp_value.tp_proc.pr_nbpar
|
#define prc_nbpar tp_value.tp_proc.pr_nbpar
|
||||||
};
|
};
|
||||||
|
|
||||||
struct set {
|
struct set {
|
||||||
arith st_low;
|
arith st_low; /* lowerbound of subrange type of set */
|
||||||
|
unsigned st_sz; /* size of constant set in compiler */
|
||||||
#define set_low tp_value.tp_set.st_low
|
#define set_low tp_value.tp_set.st_low
|
||||||
|
#define set_sz tp_value.tp_set.st_sz
|
||||||
};
|
};
|
||||||
|
|
||||||
struct type {
|
struct type {
|
||||||
|
@ -224,6 +226,7 @@ extern t_type
|
||||||
(tpx))
|
(tpx))
|
||||||
#define IsConstructed(tpx) ((tpx)->tp_fund & T_CONSTRUCTED)
|
#define IsConstructed(tpx) ((tpx)->tp_fund & T_CONSTRUCTED)
|
||||||
#define TooBigForReturnArea(tpx) ((tpx)->tp_size > ret_area_size)
|
#define TooBigForReturnArea(tpx) ((tpx)->tp_size > ret_area_size)
|
||||||
|
#define IsBigParamTp(tpx) ((tpx)->tp_size > double_size)
|
||||||
|
|
||||||
extern long full_mask[];
|
extern long full_mask[];
|
||||||
extern long max_int[];
|
extern long max_int[];
|
||||||
|
|
|
@ -503,7 +503,7 @@ set_type(tp)
|
||||||
/* Construct a set type with base type "tp", but first
|
/* Construct a set type with base type "tp", but first
|
||||||
perform some checks
|
perform some checks
|
||||||
*/
|
*/
|
||||||
arith lb, ub, diff;
|
arith lb, ub, diff, alloc_size;
|
||||||
|
|
||||||
if (! bounded(tp) || tp->tp_size > word_size) {
|
if (! bounded(tp) || tp->tp_size > word_size) {
|
||||||
error("illegal base type for set");
|
error("illegal base type for set");
|
||||||
|
@ -526,6 +526,12 @@ set_type(tp)
|
||||||
|
|
||||||
tp = construct_type(T_SET, tp);
|
tp = construct_type(T_SET, tp);
|
||||||
tp->tp_size = WA((diff + 7) >> 3);
|
tp->tp_size = WA((diff + 7) >> 3);
|
||||||
|
alloc_size = (tp->tp_size / word_size + 1) * sizeof(arith);
|
||||||
|
tp->set_sz = alloc_size;
|
||||||
|
if (tp->set_sz != alloc_size) {
|
||||||
|
error("set size too large");
|
||||||
|
return error_type;
|
||||||
|
}
|
||||||
tp->set_low = lb;
|
tp->set_low = lb;
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
extern arith NewPtr();
|
extern arith NewPtr();
|
||||||
extern arith NewInt();
|
extern arith NewInt();
|
||||||
|
extern arith TmpSpace();
|
||||||
|
|
||||||
extern int proclevel;
|
extern int proclevel;
|
||||||
|
|
||||||
|
@ -61,7 +62,11 @@ static int UseWarnings();
|
||||||
#define NO_EXIT_LABEL ((label) 0)
|
#define NO_EXIT_LABEL ((label) 0)
|
||||||
#define RETURN_LABEL ((label) 1)
|
#define RETURN_LABEL ((label) 1)
|
||||||
|
|
||||||
LblWalkNode(lbl, nd, exit)
|
#define REACH_FLAG 1
|
||||||
|
#define EXIT_FLAG 2
|
||||||
|
|
||||||
|
int
|
||||||
|
LblWalkNode(lbl, nd, exit, reach)
|
||||||
label lbl, exit;
|
label lbl, exit;
|
||||||
register t_node *nd;
|
register t_node *nd;
|
||||||
{
|
{
|
||||||
|
@ -71,7 +76,7 @@ LblWalkNode(lbl, nd, exit)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
def_ilb(lbl);
|
def_ilb(lbl);
|
||||||
WalkNode(nd, exit);
|
return WalkNode(nd, exit, reach);
|
||||||
}
|
}
|
||||||
|
|
||||||
static arith tmpprio;
|
static arith tmpprio;
|
||||||
|
@ -104,6 +109,8 @@ EndPriority()
|
||||||
def_ilb(l)
|
def_ilb(l)
|
||||||
label l;
|
label l;
|
||||||
{
|
{
|
||||||
|
/* Instruction label definition. Forget about line number.
|
||||||
|
*/
|
||||||
C_df_ilb(l);
|
C_df_ilb(l);
|
||||||
oldlineno = 0;
|
oldlineno = 0;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +118,11 @@ def_ilb(l)
|
||||||
DoLineno(nd)
|
DoLineno(nd)
|
||||||
register t_node *nd;
|
register t_node *nd;
|
||||||
{
|
{
|
||||||
if (! options['L'] && nd->nd_lineno && nd->nd_lineno != oldlineno) {
|
/* Generate line number information, if necessary.
|
||||||
|
*/
|
||||||
|
if (! options['L'] &&
|
||||||
|
nd->nd_lineno &&
|
||||||
|
nd->nd_lineno != oldlineno) {
|
||||||
oldlineno = nd->nd_lineno;
|
oldlineno = nd->nd_lineno;
|
||||||
C_lin((arith) nd->nd_lineno);
|
C_lin((arith) nd->nd_lineno);
|
||||||
}
|
}
|
||||||
|
@ -119,6 +130,11 @@ DoLineno(nd)
|
||||||
|
|
||||||
DoFilename(needed)
|
DoFilename(needed)
|
||||||
{
|
{
|
||||||
|
/* Generate filename information, when needed.
|
||||||
|
This routine is called at the generation of a
|
||||||
|
procedure entry, and after generating a call to
|
||||||
|
another procedure.
|
||||||
|
*/
|
||||||
static label filename_label = 0;
|
static label filename_label = 0;
|
||||||
|
|
||||||
oldlineno = 0; /* always invalidate remembered line number */
|
oldlineno = 0; /* always invalidate remembered line number */
|
||||||
|
@ -182,6 +198,9 @@ WalkModule(module)
|
||||||
C_ine_dlb(data_label, (arith) 0);
|
C_ine_dlb(data_label, (arith) 0);
|
||||||
}
|
}
|
||||||
else if (! options['R']) {
|
else if (! options['R']) {
|
||||||
|
/* put funny value in BSS, in an attempt to detect
|
||||||
|
uninitialized variables
|
||||||
|
*/
|
||||||
C_cal("killbss");
|
C_cal("killbss");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +211,7 @@ WalkModule(module)
|
||||||
}
|
}
|
||||||
WalkDefList(sc->sc_def, MkCalls);
|
WalkDefList(sc->sc_def, MkCalls);
|
||||||
proclevel++;
|
proclevel++;
|
||||||
WalkNode(module->mod_body, NO_EXIT_LABEL);
|
WalkNode(module->mod_body, NO_EXIT_LABEL, REACH_FLAG);
|
||||||
DO_DEBUG(options['X'], PrNode(module->mod_body, 0));
|
DO_DEBUG(options['X'], PrNode(module->mod_body, 0));
|
||||||
def_ilb(RETURN_LABEL);
|
def_ilb(RETURN_LABEL);
|
||||||
EndPriority();
|
EndPriority();
|
||||||
|
@ -215,10 +234,13 @@ WalkProcedure(procedure)
|
||||||
register t_scope *procscope = procedure->prc_vis->sc_scope;
|
register t_scope *procscope = procedure->prc_vis->sc_scope;
|
||||||
register t_type *tp;
|
register t_type *tp;
|
||||||
register t_param *param;
|
register t_param *param;
|
||||||
int too_big = 0;
|
int too_big = 0; /* returnsize larger than returnarea */
|
||||||
arith StackAdjustment = 0;
|
arith StackAdjustment = 0; /* space for conformant arrays */
|
||||||
arith retsav = 0;
|
arith retsav = 0; /* temporary space for return value */
|
||||||
arith func_res_size = 0;
|
arith func_res_size = 0;
|
||||||
|
int partno = C_getid();
|
||||||
|
int partno2 = C_getid();
|
||||||
|
int end_reached; /* can fall through ... */
|
||||||
|
|
||||||
proclevel++;
|
proclevel++;
|
||||||
CurrVis = procedure->prc_vis;
|
CurrVis = procedure->prc_vis;
|
||||||
|
@ -242,17 +264,22 @@ WalkProcedure(procedure)
|
||||||
|
|
||||||
/* Generate code for this procedure
|
/* Generate code for this procedure
|
||||||
*/
|
*/
|
||||||
C_pro_narg(procscope->sc_name);
|
|
||||||
C_ms_par(procedure->df_type->prc_nbpar +
|
|
||||||
(too_big ? func_res_size : 0));
|
|
||||||
TmpOpen(procscope);
|
TmpOpen(procscope);
|
||||||
|
C_insertpart(partno2);
|
||||||
|
C_insertpart(partno);
|
||||||
|
|
||||||
|
text_label = 1; /* label at end of procedure */
|
||||||
|
|
||||||
|
end_reached = WalkNode(procedure->prc_body, NO_EXIT_LABEL, REACH_FLAG);
|
||||||
|
|
||||||
|
C_beginpart(partno);
|
||||||
DoPriority();
|
DoPriority();
|
||||||
/* generate code for filename only when the procedure can be
|
/* generate code for filename only when the procedure can be
|
||||||
exported, either directly or by taking the address.
|
exported, either directly or by taking the address.
|
||||||
This cannot be done if the level is not zero (because in
|
This cannot be done if the level is bigger than one (because in
|
||||||
this case it is a nested procedure).
|
this case it is a nested procedure).
|
||||||
*/
|
*/
|
||||||
DoFilename(! procscope->sc_level);
|
DoFilename(procscope->sc_level == 1);
|
||||||
|
|
||||||
/* Generate calls to initialization routines of modules defined within
|
/* Generate calls to initialization routines of modules defined within
|
||||||
this procedure
|
this procedure
|
||||||
|
@ -261,7 +288,7 @@ WalkProcedure(procedure)
|
||||||
|
|
||||||
/* Make sure that arguments of size < word_size are on a
|
/* Make sure that arguments of size < word_size are on a
|
||||||
fixed place.
|
fixed place.
|
||||||
Also make copies of conformant arrays when neccessary.
|
Also make copies of parameters when neccessary.
|
||||||
*/
|
*/
|
||||||
for (param = ParamList(procedure->df_type);
|
for (param = ParamList(procedure->df_type);
|
||||||
param;
|
param;
|
||||||
|
@ -273,17 +300,37 @@ WalkProcedure(procedure)
|
||||||
if (tp->tp_size < word_size &&
|
if (tp->tp_size < word_size &&
|
||||||
(int) word_size % (int) tp->tp_size == 0) {
|
(int) word_size % (int) tp->tp_size == 0) {
|
||||||
C_lol(param->par_def->var_off);
|
C_lol(param->par_def->var_off);
|
||||||
STL(param->par_def->var_off, tp->tp_size);
|
STL(param->par_def->var_off,
|
||||||
|
tp->tp_size);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
if (IsBigParamTp(tp) &&
|
||||||
|
(param->par_def->df_flags & D_DEFINED)){
|
||||||
|
/* Value parameter changed in body.
|
||||||
|
Make a copy
|
||||||
|
*/
|
||||||
|
arith tmp = TmpSpace(tp->tp_size,
|
||||||
|
tp->tp_align);
|
||||||
|
LOL(param->par_def->var_off,
|
||||||
|
pointer_size);
|
||||||
|
C_lal(tmp);
|
||||||
|
CodeConst(WA(tp->tp_size),
|
||||||
|
(int)pointer_size);
|
||||||
|
C_bls(pointer_size);
|
||||||
|
C_lal(tmp);
|
||||||
|
STL(param->par_def->var_off,
|
||||||
|
pointer_size);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
if (param->par_def->df_flags & D_DEFINED) {
|
||||||
/* Here, we have to make a copy of the
|
/* Here, we have to make a copy of the
|
||||||
array. We must also remember how much
|
array. We must also remember how much
|
||||||
room is reserved for copies, because
|
room is reserved for copies, because
|
||||||
we have to adjust the stack pointer before
|
we have to adjust the stack pointer before
|
||||||
a RET is done. This is even more complicated
|
a RET is done. This is even more complicated
|
||||||
when the procedure returns a value.
|
when the procedure returns a value.
|
||||||
Then, the value must be saved (in retval),
|
Then, the value must be saved,
|
||||||
the stack adjusted, the return value pushed
|
the stack adjusted, the return value pushed
|
||||||
again, and then RET
|
again, and then RET
|
||||||
*/
|
*/
|
||||||
|
@ -295,9 +342,8 @@ WalkProcedure(procedure)
|
||||||
needed if the value itself
|
needed if the value itself
|
||||||
is returned
|
is returned
|
||||||
*/
|
*/
|
||||||
procscope->sc_off -=
|
retsav= TmpSpace(func_res_size,
|
||||||
func_res_size;
|
1);
|
||||||
retsav = procscope->sc_off;
|
|
||||||
}
|
}
|
||||||
StackAdjustment = NewPtr();
|
StackAdjustment = NewPtr();
|
||||||
C_lor((arith) 1);
|
C_lor((arith) 1);
|
||||||
|
@ -316,12 +362,13 @@ WalkProcedure(procedure)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
C_endpart(partno);
|
||||||
text_label = 1; /* label at end of procedure */
|
|
||||||
|
|
||||||
WalkNode(procedure->prc_body, NO_EXIT_LABEL);
|
|
||||||
DO_DEBUG(options['X'], PrNode(procedure->prc_body, 0));
|
DO_DEBUG(options['X'], PrNode(procedure->prc_body, 0));
|
||||||
if (func_res_size) {
|
if ((end_reached & REACH_FLAG) && func_res_size) {
|
||||||
|
node_warning(procscope->sc_end,
|
||||||
|
W_ORDINARY,
|
||||||
|
"function procedure \"%s\" does not always return a value",
|
||||||
|
procedure->df_idf->id_text);
|
||||||
c_loc(M2_NORESULT);
|
c_loc(M2_NORESULT);
|
||||||
C_trp();
|
C_trp();
|
||||||
C_asp(-func_res_size);
|
C_asp(-func_res_size);
|
||||||
|
@ -357,10 +404,16 @@ WalkProcedure(procedure)
|
||||||
}
|
}
|
||||||
EndPriority();
|
EndPriority();
|
||||||
C_ret(func_res_size);
|
C_ret(func_res_size);
|
||||||
|
C_beginpart(partno2);
|
||||||
|
C_pro(procscope->sc_name, -procscope->sc_off);
|
||||||
|
C_ms_par(procedure->df_type->prc_nbpar +
|
||||||
|
(too_big ? func_res_size : 0));
|
||||||
if (! options['n']) WalkDefList(procscope->sc_def, RegisterMessage);
|
if (! options['n']) WalkDefList(procscope->sc_def, RegisterMessage);
|
||||||
|
C_endpart(partno2);
|
||||||
C_end(-procscope->sc_off);
|
C_end(-procscope->sc_off);
|
||||||
if (! fit(procscope->sc_off, (int) word_size)) {
|
if (! fit(procscope->sc_off, (int) word_size)) {
|
||||||
node_error(procedure->prc_body, "maximum local byte count exceeded");
|
node_error(procedure->prc_body,
|
||||||
|
"maximum local byte count exceeded");
|
||||||
}
|
}
|
||||||
TmpClose();
|
TmpClose();
|
||||||
CurrVis = savevis;
|
CurrVis = savevis;
|
||||||
|
@ -409,19 +462,22 @@ MkCalls(df)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkLink(nd, exit_label)
|
WalkLink(nd, exit_label, end_reached)
|
||||||
register t_node *nd;
|
register t_node *nd;
|
||||||
label exit_label;
|
label exit_label;
|
||||||
{
|
{
|
||||||
/* Walk node "nd", which is a link.
|
/* Walk node "nd", which is a link.
|
||||||
|
"exit_label" is set to a label number when inside a LOOP.
|
||||||
|
"end_reached" maintains info about reachability (REACH_FLAG),
|
||||||
|
and whether an EXIT statement was seen (EXIT_FLAG).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (nd && nd->nd_class == Link) { /* statement list */
|
while (nd && nd->nd_class == Link) { /* statement list */
|
||||||
WalkNode(nd->nd_left, exit_label);
|
end_reached = WalkNode(nd->nd_left, exit_label, end_reached);
|
||||||
nd = nd->nd_right;
|
nd = nd->nd_right;
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkNode(nd, exit_label);
|
return WalkNode(nd, exit_label, end_reached);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
|
@ -434,7 +490,8 @@ ForLoopVarExpr(nd)
|
||||||
CodeCoercion(tp, BaseType(tp));
|
CodeCoercion(tp, BaseType(tp));
|
||||||
}
|
}
|
||||||
|
|
||||||
WalkStat(nd, exit_label)
|
int
|
||||||
|
WalkStat(nd, exit_label, end_reached)
|
||||||
register t_node *nd;
|
register t_node *nd;
|
||||||
label exit_label;
|
label exit_label;
|
||||||
{
|
{
|
||||||
|
@ -445,8 +502,11 @@ WalkStat(nd, exit_label)
|
||||||
|
|
||||||
assert(nd->nd_class == Stat);
|
assert(nd->nd_class == Stat);
|
||||||
|
|
||||||
if (nd->nd_symb == ';') return;
|
if (nd->nd_symb == ';') return 1;
|
||||||
|
|
||||||
|
if (! end_reached & REACH_FLAG) {
|
||||||
|
node_warning(nd, W_ORDINARY, "statement not reached");
|
||||||
|
}
|
||||||
DoLineno(nd);
|
DoLineno(nd);
|
||||||
options['R'] = (nd->nd_flags & ROPTION);
|
options['R'] = (nd->nd_flags & ROPTION);
|
||||||
options['A'] = (nd->nd_flags & AOPTION);
|
options['A'] = (nd->nd_flags & AOPTION);
|
||||||
|
@ -467,24 +527,26 @@ WalkStat(nd, exit_label)
|
||||||
|
|
||||||
case IF:
|
case IF:
|
||||||
{ label l1 = ++text_label, l3 = ++text_label;
|
{ label l1 = ++text_label, l3 = ++text_label;
|
||||||
|
int end_r;
|
||||||
|
|
||||||
ExpectBool(left, l3, l1);
|
ExpectBool(left, l3, l1);
|
||||||
assert(right->nd_symb == THEN);
|
assert(right->nd_symb == THEN);
|
||||||
LblWalkNode(l3, right->nd_left, exit_label);
|
end_r = LblWalkNode(l3, right->nd_left, exit_label, end_reached);
|
||||||
|
|
||||||
if (right->nd_right) { /* ELSE part */
|
if (right->nd_right) { /* ELSE part */
|
||||||
label l2 = ++text_label;
|
label l2 = ++text_label;
|
||||||
|
|
||||||
C_bra(l2);
|
C_bra(l2);
|
||||||
LblWalkNode(l1, right->nd_right, exit_label);
|
end_reached = end_r | LblWalkNode(l1, right->nd_right, exit_label, end_reached);
|
||||||
l1 = l2;
|
l1 = l2;
|
||||||
}
|
}
|
||||||
|
else end_reached |= end_r;
|
||||||
def_ilb(l1);
|
def_ilb(l1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CASE:
|
case CASE:
|
||||||
CaseCode(nd, exit_label);
|
end_reached = CaseCode(nd, exit_label, end_reached);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WHILE:
|
case WHILE:
|
||||||
|
@ -492,10 +554,10 @@ WalkStat(nd, exit_label)
|
||||||
exit = ++text_label,
|
exit = ++text_label,
|
||||||
dummy = ++text_label;
|
dummy = ++text_label;
|
||||||
|
|
||||||
def_ilb(loop);
|
C_bra(dummy);
|
||||||
ExpectBool(left, dummy, exit);
|
end_reached |= LblWalkNode(loop, right, exit_label, end_reached);
|
||||||
LblWalkNode(dummy, right, exit_label);
|
def_ilb(dummy);
|
||||||
C_bra(loop);
|
ExpectBool(left, loop, exit);
|
||||||
def_ilb(exit);
|
def_ilb(exit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -503,7 +565,7 @@ WalkStat(nd, exit_label)
|
||||||
case REPEAT:
|
case REPEAT:
|
||||||
{ label loop = ++text_label, exit = ++text_label;
|
{ label loop = ++text_label, exit = ++text_label;
|
||||||
|
|
||||||
LblWalkNode(loop, left, exit_label);
|
end_reached = LblWalkNode(loop, left, exit_label, end_reached);
|
||||||
ExpectBool(right, exit, loop);
|
ExpectBool(right, exit, loop);
|
||||||
def_ilb(exit);
|
def_ilb(exit);
|
||||||
break;
|
break;
|
||||||
|
@ -512,7 +574,10 @@ WalkStat(nd, exit_label)
|
||||||
case LOOP:
|
case LOOP:
|
||||||
{ label loop = ++text_label, exit = ++text_label;
|
{ label loop = ++text_label, exit = ++text_label;
|
||||||
|
|
||||||
LblWalkNode(loop, right, exit);
|
if (LblWalkNode(loop, right, exit, end_reached) & EXIT_FLAG) {
|
||||||
|
end_reached &= REACH_FLAG;
|
||||||
|
}
|
||||||
|
else end_reached = 0;
|
||||||
C_bra(loop);
|
C_bra(loop);
|
||||||
def_ilb(exit);
|
def_ilb(exit);
|
||||||
break;
|
break;
|
||||||
|
@ -575,7 +640,7 @@ WalkStat(nd, exit_label)
|
||||||
|
|
||||||
ForLoopVarExpr(nd);
|
ForLoopVarExpr(nd);
|
||||||
C_stl(tmp2);
|
C_stl(tmp2);
|
||||||
WalkNode(right, exit_label);
|
end_reached |= WalkNode(right, exit_label, end_reached);
|
||||||
C_lol(tmp2);
|
C_lol(tmp2);
|
||||||
ForLoopVarExpr(nd);
|
ForLoopVarExpr(nd);
|
||||||
C_beq(x);
|
C_beq(x);
|
||||||
|
@ -583,7 +648,7 @@ WalkStat(nd, exit_label)
|
||||||
C_trp();
|
C_trp();
|
||||||
def_ilb(x);
|
def_ilb(x);
|
||||||
}
|
}
|
||||||
else WalkNode(right, exit_label);
|
else end_reached |= WalkNode(right, exit_label, end_reached);
|
||||||
nd->nd_def->df_flags &= ~D_FORLOOP;
|
nd->nd_def->df_flags &= ~D_FORLOOP;
|
||||||
FreeInt(tmp2);
|
FreeInt(tmp2);
|
||||||
if (stepsize) {
|
if (stepsize) {
|
||||||
|
@ -601,7 +666,7 @@ WalkStat(nd, exit_label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WalkNode(right, exit_label);
|
end_reached |= WalkNode(right, exit_label, end_reached);
|
||||||
nd->nd_def->df_flags &= ~D_FORLOOP;
|
nd->nd_def->df_flags &= ~D_FORLOOP;
|
||||||
}
|
}
|
||||||
C_bra(l1);
|
C_bra(l1);
|
||||||
|
@ -620,13 +685,14 @@ WalkStat(nd, exit_label)
|
||||||
struct withdesig wds;
|
struct withdesig wds;
|
||||||
t_desig ds;
|
t_desig ds;
|
||||||
|
|
||||||
if (! WalkDesignator(left, &ds, D_USED|D_DEFINED)) break;
|
if (! WalkDesignator(left, &ds, D_USED)) break;
|
||||||
if (left->nd_type->tp_fund != T_RECORD) {
|
if (left->nd_type->tp_fund != T_RECORD) {
|
||||||
node_error(left, "record variable expected");
|
node_error(left, "record variable expected");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
wds.w_next = WithDesigs;
|
wds.w_next = WithDesigs;
|
||||||
|
wds.w_flags = D_USED;
|
||||||
WithDesigs = &wds;
|
WithDesigs = &wds;
|
||||||
wds.w_scope = left->nd_type->rec_scope;
|
wds.w_scope = left->nd_type->rec_scope;
|
||||||
CodeAddress(&ds);
|
CodeAddress(&ds);
|
||||||
|
@ -642,20 +708,23 @@ WalkStat(nd, exit_label)
|
||||||
link.sc_scope = wds.w_scope;
|
link.sc_scope = wds.w_scope;
|
||||||
link.sc_next = CurrVis;
|
link.sc_next = CurrVis;
|
||||||
CurrVis = &link;
|
CurrVis = &link;
|
||||||
WalkNode(right, exit_label);
|
end_reached = WalkNode(right, exit_label, end_reached);
|
||||||
CurrVis = link.sc_next;
|
CurrVis = link.sc_next;
|
||||||
WithDesigs = wds.w_next;
|
WithDesigs = wds.w_next;
|
||||||
FreePtr(ds.dsg_offset);
|
FreePtr(ds.dsg_offset);
|
||||||
|
WalkDesignator(left, &ds, wds.w_flags & (D_USED|D_DEFINED));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EXIT:
|
case EXIT:
|
||||||
assert(exit_label != 0);
|
assert(exit_label != 0);
|
||||||
|
|
||||||
|
if (end_reached & REACH_FLAG) end_reached = EXIT_FLAG;
|
||||||
C_bra(exit_label);
|
C_bra(exit_label);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RETURN:
|
case RETURN:
|
||||||
|
end_reached &= ~REACH_FLAG;
|
||||||
if (right) {
|
if (right) {
|
||||||
if (! ChkExpression(right)) break;
|
if (! ChkExpression(right)) break;
|
||||||
/* The type of the return-expression must be
|
/* The type of the return-expression must be
|
||||||
|
@ -677,6 +746,7 @@ WalkStat(nd, exit_label)
|
||||||
default:
|
default:
|
||||||
crash("(WalkStat)");
|
crash("(WalkStat)");
|
||||||
}
|
}
|
||||||
|
return end_reached;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int NodeCrash();
|
extern int NodeCrash();
|
||||||
|
@ -900,16 +970,18 @@ UseWarnings(df)
|
||||||
}
|
}
|
||||||
switch(df->df_flags & (D_USED|D_DEFINED|D_VALPAR|D_VARPAR)) {
|
switch(df->df_flags & (D_USED|D_DEFINED|D_VALPAR|D_VARPAR)) {
|
||||||
case 0:
|
case 0:
|
||||||
case D_VALPAR:
|
|
||||||
case D_VARPAR:
|
case D_VARPAR:
|
||||||
warning = "never used/assigned";
|
warning = "never used/assigned";
|
||||||
break;
|
break;
|
||||||
case D_USED|D_VARPAR:
|
case D_USED|D_VARPAR:
|
||||||
warning = "never assigned, could be value parameter";
|
if (df->df_type->tp_fund != T_EQUAL) {
|
||||||
|
warning = "never assigned, could be value parameter";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case D_USED:
|
case D_USED:
|
||||||
warning = "never assigned";
|
warning = "never assigned";
|
||||||
break;
|
break;
|
||||||
|
case D_VALPAR:
|
||||||
case D_DEFINED:
|
case D_DEFINED:
|
||||||
case D_DEFINED|D_VALPAR:
|
case D_DEFINED|D_VALPAR:
|
||||||
warning = "never used";
|
warning = "never used";
|
||||||
|
@ -924,7 +996,10 @@ warn:
|
||||||
"%s \"%s\" %s",
|
"%s \"%s\" %s",
|
||||||
(df->df_flags & D_VALPAR) ? "value parameter" :
|
(df->df_flags & D_VALPAR) ? "value parameter" :
|
||||||
(df->df_flags & D_VARPAR) ? "variable parameter" :
|
(df->df_flags & D_VARPAR) ? "variable parameter" :
|
||||||
"identifier",
|
(df->df_kind == D_VARIABLE) ? "variable" :
|
||||||
|
(df->df_kind == D_TYPE) ? "type" :
|
||||||
|
(df->df_kind == D_CONST) ? "constant" :
|
||||||
|
"procedure",
|
||||||
df->df_idf->id_text, warning);
|
df->df_idf->id_text, warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
extern int (*WalkTable[])();
|
extern int (*WalkTable[])();
|
||||||
|
|
||||||
#define WalkNode(xnd, xlab) (*WalkTable[(xnd)->nd_class])((xnd), (xlab))
|
#define WalkNode(xnd, xlab, rch) (*WalkTable[(xnd)->nd_class])((xnd), (xlab),(rch))
|
||||||
|
|
||||||
extern label text_label;
|
extern label text_label;
|
||||||
extern label data_label;
|
extern label data_label;
|
||||||
|
|
Loading…
Add table
Reference in a new issue