PushBack();
*tg++ = '\0'; /* mark the end of the identifier */
idef = ptok->tk_idf = idf_hashed(buf, tg - buf, hash);
+ idef->id_file = ptok->tk_file;
+ idef->id_line = ptok->tk_line;
#ifndef NOPP
if (idef->id_macro && ReplaceMacros && replace(idef))
/* macro replacement should be performed */
int fp_used;
#endif NOFLOAT
+/* global function info */
+char *func_name;
+struct type *func_type;
+int func_notypegiven;
+
#ifdef USE_TMP
static int tmp_id;
static int pro_id;
#endif USE_TMP
-static char *pro_name;
extern char options[];
char *symbol2str();
static label return_label, return2_label;
static char return_expr_occurred;
-static struct type *func_tp;
static arith func_size;
static label func_res_label;
static char *last_fn_given = "";
static label file_name_label;
-begin_proc(name, def) /* to be called when entering a procedure */
- char *name;
- register struct def *def;
+begin_proc(ds, idf) /* to be called when entering a procedure */
+ struct decspecs *ds;
+ struct idf *idf;
{
/* begin_proc() is called at the entrance of a new function
and performs the necessary code generation:
does not fit in the return area
- a fil pseudo instruction
*/
- register struct type *tp = def->df_type;
+ register char *name = idf->id_text;
+ register struct def *def = idf->id_def;
#ifndef USE_TMP
code_scope(name, def);
DfaStartFunction(name);
#endif DATAFLOW
- if (tp->tp_fund != FUNCTION) {
+ /* set global function info */
+ func_name = name;
+ if (def->df_type->tp_fund != FUNCTION) {
error("making function body for non-function");
- tp = error_type;
+ func_type = error_type;
}
- else
- tp = tp->tp_up;
- func_tp = tp;
- func_size = ATW(tp->tp_size);
- pro_name = name;
+ else {
+ func_type = def->df_type->tp_up;
+ }
+ func_notypegiven = ds->ds_notypegiven;
+ func_size = ATW(func_type->tp_size);
+
#ifndef USE_TMP
C_pro_narg(name);
#else
C_insertpart(pro_id = C_getid());
#endif
- if (is_struct_or_union(tp->tp_fund)) {
+ if (is_struct_or_union(func_type->tp_fund)) {
C_df_dlb(func_res_label = data_label());
C_bss_cst(func_size, (arith)0, 1);
}
if (return_expr_occurred) {
if (func_res_label != 0) {
C_lae_dlb(func_res_label, (arith)0);
- store_block(func_size, func_tp->tp_align);
+ store_block(func_size, func_type->tp_align);
C_lae_dlb(func_res_label, (arith)0);
C_ret(pointer_size);
}
C_ret(func_size);
}
else C_ret((arith) 0);
-
/* getting the number of "local" bytes is posponed until here,
because copying the function result in "func_res_label" may
need temporaries! However, local_level is now L_FORMAL2, because
nbytes = ATW(- local_level->sl_max_block);
#ifdef USE_TMP
C_beginpart(pro_id);
- C_pro(pro_name, nbytes);
+ C_pro(func_name, nbytes);
#endif
if (fbytes > max_int) {
error("%s has more than %ld parameter bytes",
- pro_name, (long) max_int);
+ func_name, (long) max_int);
}
C_ms_par(fbytes); /* # bytes for formals */
if (sp_occurred[SP_SETJMP]) { /* indicate use of "setjmp" */
C_end(nbytes);
if (nbytes > max_int) {
error("%s has more than %ld bytes of local variables",
- pro_name, (long) max_int);
+ func_name, (long) max_int);
}
options['n'] = optionsn;
}
/* do_return_expr() generates the expression and the jump for
a return statement with an expression.
*/
- ch7cast(&expr, RETURN, func_tp);
+ ch7cast(&expr, RETURN, func_type);
code_expr(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
C_bra(return_label);
return_expr_occurred = 1;
signed, unsigned or floating
*/
static int
-convtype(tp)/* bad name ???*/
+convtype(tp)
register struct type *tp;
{
switch (tp->tp_fund) {
*/
/* some adjustments as described in RM 8.2 */
- if (tp == 0)
+ if (tp == 0) {
+ ds->ds_notypegiven = 1;
tp = int_type;
+ }
switch (ds->ds_size) {
case SHORT:
if (tp == int_type)
struct decspecs {
struct decspecs *next;
struct type *ds_type; /* single type */
+ int ds_notypegiven; /* set if type not given explicitly */
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 */
char df_initialized; /* an initialization has been generated */
char df_alloc; /* 0, ALLOC_SEEN or ALLOC_DONE */
char df_used; /* set if idf is used */
+ char *df_file; /* file containing the definition */
+ long df_line; /* line number of the definition */
char df_formal_array; /* to warn if sizeof is taken */
arith df_address;
};
def->df_sc == ENUM ? ", =" : " at",
def->df_address
);
+ print("%s, line %u",
+ def->df_file ? def->df_file : "NO_FILE", def->df_line);
def = def->next;
}
dumplevel--;
extern char *symbol2str();
extern char options[];
-extern char loptions[];
/* There are three general error-message functions:
lexerror() lexical and pre-processor error messages
switch (lvl) {
case L_GLOBAL:
global_redecl(idf, sc, type);
+ def->df_file = idf->id_file;
+ def->df_line = idf->id_line;
break;
case L_FORMAL1: /* formal declaration */
error("formal %s redeclared", idf->id_text);
def->df_formal_array = formal_array;
def->df_sc = sc;
def->df_level = L_FORMAL2; /* CJ */
+ def->df_file = idf->id_file;
+ def->df_line = idf->id_line;
}
else
if ( lvl >= L_LOCAL &&
newdef->df_level = lvl;
newdef->df_type = type;
newdef->df_sc = sc;
+ newdef->df_file = idf->id_file;
+ newdef->df_line = idf->id_line;
/* link it into the name list in the proper place */
idf->id_def = newdef;
update_ahead(idf);
int id_resmac; /* if nonzero: keyword of macroproc. */
#endif NOPP
int id_reserved; /* non-zero for reserved words */
+ char *id_file; /* used for warnings */
+ long id_line;
struct def *id_def; /* variables, typedefs, enum-constants */
struct sdef *id_sdef; /* selector tags */
struct tag *id_struct; /* struct and union tags */
extern struct tokenname tkidf[], tkother[];
extern char *symbol2str();
-char options[128]; /* one for every char */
+extern char options[128];
#ifndef NOPP
int inc_pos = 1; /* place where next -I goes */
cat <<'--EOT--'
+/* Generated by make.tokcase */
+/* $Header: */
#include "Lpars.h"
char *
}
switch (tok) {
--EOT--
+
sed '
/{[A-Z]/!d
s/.*{\(.*\),.*\(".*"\).*$/ case \1 :\
return \2;/
'
+
cat <<'--EOT--'
case '\n':
case '\f':
+cat <<'--EOT--'
+/* Generated by make.tokfile */
+/* $Header: */
+--EOT--
+
sed '
/{[A-Z]/!d
s/.*{//
extern int inc_total;
#endif NOPP
-extern char options[];
+char options[128]; /* one for every char */
extern int idfsize;
int txt2int();
do_option(text)
char *text;
{
- switch(*text++) {
+ register char opt;
+
+ switch (opt = *text++) {
default:
- fatal("illegal option: %c", *--text);
+ fatal("illegal option: %c", opt);
break;
case '-':
options[*text] = 1; /* flags, debug options etc. */
#ifndef NOROPTION
case 'R': /* strict version */
#endif
- options[*(text-1)] = 1;
+ options[opt] = 1;
break;
+
#ifdef NOROPTION
case 'R':
warning("-R option not implemented");
break;
#else NOCROSS
{
- register arith size, align;
+ register arith sz, algn;
char c;
while (c = *text++) {
- size = txt2int(&text);
- align = 0;
+ sz = txt2int(&text);
+ algn = 0;
if (*text == '.') {
text++;
- align = txt2int(&text);
+ algn = txt2int(&text);
}
switch (c) {
case 's': /* short */
- if (size != (arith)0)
- short_size = size;
- if (align != 0)
- short_align = align;
+ if (sz != (arith)0)
+ short_size = sz;
+ if (algn != 0)
+ short_align = algn;
break;
case 'w': /* word */
- if (size != (arith)0)
- dword_size = (word_size = size) << 1;
- if (align != 0)
- word_align = align;
+ if (sz != (arith)0)
+ dword_size = (word_size = sz) << 1;
+ if (algn != 0)
+ word_align = algn;
break;
case 'i': /* int */
- if (size != (arith)0)
- int_size = size;
- if (align != 0)
- int_align = align;
+ if (sz != (arith)0)
+ int_size = sz;
+ if (algn != 0)
+ int_align = algn;
break;
case 'l': /* long */
- if (size != (arith)0)
- long_size = size;
- if (align != 0)
- long_align = align;
+ if (sz != (arith)0)
+ long_size = sz;
+ if (algn != 0)
+ long_align = algn;
break;
case 'f': /* float */
#ifndef NOFLOAT
- if (size != (arith)0)
- float_size = size;
- if (align != 0)
- float_align = align;
+ if (sz != (arith)0)
+ float_size = sz;
+ if (algn != 0)
+ float_align = algn;
#endif NOFLOAT
break;
case 'd': /* double */
#ifndef NOFLOAT
- if (size != (arith)0)
- double_size = size;
- if (align != 0)
- double_align = align;
+ if (sz != (arith)0)
+ double_size = sz;
+ if (algn != 0)
+ double_align = algn;
#endif NOFLOAT
break;
case 'p': /* pointer */
- if (size != (arith)0)
- pointer_size = size;
- if (align != 0)
- pointer_align = align;
+ if (sz != (arith)0)
+ pointer_size = sz;
+ if (algn != 0)
+ pointer_align = algn;
break;
case 'r': /* adjust bitfields right */
#ifndef NOBITFIELD
#endif NOBITFIELD
break;
case 'S': /* initial struct alignment */
- if (size != (arith)0)
- struct_align = size;
+ if (sz != (arith)0)
+ struct_align = sz;
break;
case 'U': /* initial union alignment */
- if (size != (arith)0)
- union_align = size;
+ if (sz != (arith)0)
+ union_align = sz;
break;
default:
error("-V: bad type indicator %c\n", c);
is a function, not an old-fashioned
initialization.
*/
- function(&Dc)
+ function(&Ds, &Dc)
|
non_function(&Ds, &Dc)
]
;
/* 10.1 */
-function(struct declarator *dc;)
+function(struct decspecs *ds; struct declarator *dc;)
{
arith fbytes;
}
init_idf(idf);
stack_level(); /* L_FORMAL1 declarations */
declare_params(dc);
- begin_proc(idf->id_text, idf->id_def);
+ begin_proc(ds, idf); /* sets global function info */
stack_level(); /* L_FORMAL2 declarations */
}
declaration*
count *= tp->tp_size;
dtp = array_of(tp, count);
break;
+ default:
+ crash("bad constructor in construct_type");
+ /*NOTREACHED*/
}
return dtp;
}
}
struct type *
-standard_type(fund, sign, algn, size)
- int algn; arith size;
+standard_type(fund, sgn, algn, sz)
+ int algn; arith sz;
{
register struct type *tp = create_type(fund);
- tp->tp_unsigned = sign;
+ tp->tp_unsigned = sgn;
tp->tp_align = algn;
- tp->tp_size = size;
+ tp->tp_size = sz;
return tp;
}