ANSI requires separate name space for labels, and made to use idf module

This commit is contained in:
ceriel 1991-06-19 16:12:56 +00:00
parent 3a074a6f99
commit 9f43986877
21 changed files with 105 additions and 266 deletions

View file

@ -22,12 +22,15 @@
#include "class.h"
#include "assert.h"
#include "sizes.h"
#include "specials.h" /* registration of special identifiers */
/* Data about the token yielded */
struct token dot, ahead, aside;
int token_nmb = 0; /* number of the ahead token */
int tk_nmb_at_last_syn_err = -5/*ERR_SHADOW*/;
/* token number at last syntax error */
int idfsize = IDFSIZE;
char sp_occurred[SP_TOTAL+1];
#ifndef NOPP
int ReplaceMacros = 1; /* replacing macros */
@ -307,7 +310,6 @@ garbage:
{
register char *tg = &buf[0];
register int pos = -1;
register int hash;
register struct idf *idef;
extern int idfsize; /* ??? */
#ifndef NOPP
@ -319,20 +321,18 @@ garbage:
ch = GetChar();
}
#endif
hash = STARTHASH();
do { /* read the identifier */
if (++pos < idfsize) {
*tg++ = ch;
hash = ENHASH(hash, ch);
}
ch = GetChar();
} while (in_idf(ch));
hash = STOPHASH(hash);
if (ch != EOI)
UnGetChar();
*tg++ = '\0'; /* mark the end of the identifier */
idef = ptok->tk_idf = idf_hashed(buf, (int) (tg - buf), hash);
idef = ptok->tk_idf = str2idf(buf, 1);
sp_occurred[idef->id_special] = 1;
idef->id_file = ptok->tk_file;
idef->id_line = ptok->tk_line;
#ifndef NOPP

View file

@ -41,7 +41,7 @@ insert_token(tk)
dot.tk_idf = gen_idf();
break;
case TYPE_IDENTIFIER:
dot.tk_idf = str2idf("int");
dot.tk_idf = str2idf("int", 0);
break;
case STRING:
dot.tk_bts = Salloc("", 1);

View file

@ -277,7 +277,7 @@ initializer(struct idf *idf; int sc;)
stb_string(idf->id_def, sc, idf->id_text);
}
#endif /* DBSYMTAB */
init_idf(idf);
idf_initialized(idf);
}
;

View file

@ -59,6 +59,8 @@ newline() {
print(" ");
}
int dumpidf();
dumpidftab(msg, opt)
char msg[];
{
@ -68,18 +70,10 @@ dumpidftab(msg, opt)
Unless opt & 2, reserved identifiers are not dumped.
Unless opt & 4, universal identifiers are not dumped.
*/
int i;
print(">>> DUMPIDF, %s (start)", msg);
dumpstack();
for (i = 0; i < HASHSIZE; i++) {
register struct idf *notch = idf_hashtable[i];
while (notch) {
dumpidf(notch, opt);
notch = notch->next;
}
}
idfappfun(dumpidf, opt);
newline();
print(">>> DUMPIDF, %s (end)\n", msg);
}
@ -151,13 +145,6 @@ dumpidf(idf, opt)
}
dumptags(idf->id_struct);
}
if (idf->id_enum) {
if (!started++) {
newline();
print("%s:", idf->id_text);
}
dumptags(idf->id_enum);
}
}
dumpdefs(def, opt)

View file

@ -154,25 +154,19 @@ idf2expr(expr)
def = idf->id_def;
}
/* now def != 0 */
if (def->df_type->tp_fund == LABEL) {
expr_error(expr, "illegal use of label %s", idf->id_text);
expr->ex_type = error_type;
}
else {
#ifndef LINT
if (!InSizeof) {
if (! def->df_used) {
if (!InSizeof) {
if (! def->df_used) {
#ifndef PREPEND_SCOPES
code_scope(idf->id_text, def);
code_scope(idf->id_text, def);
#endif /* PREPEND_SCOPES */
def->df_used = 1;
}
def->df_used = 1;
}
}
#endif LINT
expr->ex_type = def->df_type;
if (expr->ex_type == error_type) {
expr->ex_flags |= EX_ERROR;
}
expr->ex_type = def->df_type;
if (expr->ex_type == error_type) {
expr->ex_flags |= EX_ERROR;
}
expr->ex_lvalue =
( def->df_type->tp_fund == FUNCTION ||

View file

@ -29,146 +29,16 @@
#include "sizes.h"
#include "Lpars.h"
#include "assert.h"
#include "specials.h" /* registration of special identifiers */
int idfsize = IDFSIZE;
extern char options[];
extern arith NewLocal();
extern char *symbol2str();
char sp_occurred[SP_TOTAL+1]; /* indicate occurrence of special id */
#ifdef DEBUG
#define IDF_DEBUG
#endif
struct idf *idf_hashtable[HASHSIZE];
/* All identifiers can in principle be reached through
idf_hashtable; idf_hashtable[hc] is the start of a chain of
idf's whose tags all hash to hc. Each idf is the start of
a chain of def's for that idf, sorted according to level,
with the most recent one on top.
Any identifier occurring on a level is entered into this
list, regardless of the nature of its declaration
(variable, selector, structure tag, etc.).
*/
static struct idf *
idf_new(tg, size)
register char *tg;
register int size;
{
#define IBUFSIZ 2048
static unsigned int icnt;
static char *ip;
register char *p;
register struct idf *id = new_idf();
if (size > icnt) {
icnt = size > IBUFSIZ ? size : IBUFSIZ;
p = malloc(icnt); /* yes, malloc, not Malloc */
if (! p) p = Malloc(size);
}
else p = ip;
icnt -= size;
id->id_text = p;
while (size--) {
*p++ = *tg++;
}
ip = p;
return id;
}
struct idf *
idf_hashed(tg, size, hc)
char *tg;
int size; /* includes the '\0' character */
int hc;
{
/* The tag tg with length size and known hash value hc is
looked up in the identifier table; if not found, it is
entered. A pointer to it is returned.
The identifier has already been truncated to idfsize
characters.
*/
register struct idf **hook = &idf_hashtable[hc], *notch;
while ((notch = *hook)) {
register char *s1 = tg;
register char *cp = notch->id_text;
register int cmp;
while (!(cmp = (*s1 - *cp++))) {
if (*s1++ == '\0') {
break;
}
}
if (cmp < 0)
break;
if (cmp == 0) {
/* suppose that special identifiers, as
"__setjmp", are already inserted
*/
sp_occurred[notch->id_special] = 1;
return notch;
}
hook = &notch->next;
}
/* a new struct idf must be inserted at the hook */
notch = idf_new(tg, size);
notch->next = *hook;
*hook = notch; /* hooked in */
#ifndef NOPP
/* notch->id_resmac = 0; */
#endif NOPP
return notch;
}
#ifdef DEBUG
hash_stat()
{
if (options['h']) {
register int i;
print("Hash table tally:\n");
for (i = 0; i < HASHSIZE; i++) {
register struct idf *notch = idf_hashtable[i];
int cnt = 0;
while (notch) {
cnt++;
notch = notch->next;
}
print("%d %d\n", i, cnt);
}
print("End hash table tally\n");
}
}
#endif DEBUG
struct idf *
str2idf(tg)
char tg[];
{
/* str2idf() returns an entry in the symbol table for the
identifier tg. If necessary, an entry is created.
It is used where the text of the identifier is available
but its hash value is not; otherwise idf_hashed() is to
be used.
*/
register char *cp = tg;
register int hash;
register int pos = -1;
register int ch;
char ntg[IDFSIZE + 1];
register char *ncp = ntg;
hash = STARTHASH();
while (++pos < idfsize && (ch = *cp++)) {
*ncp++ = ch;
hash = ENHASH(hash, ch);
}
hash = STOPHASH(hash);
*ncp++ = '\0';
return idf_hashed(ntg, (int) (ncp - ntg), hash);
}
#include <idf_pkg.body>
struct idf *
gen_idf()
@ -181,7 +51,7 @@ gen_idf()
sprint(buff, "#%d in %s, line %u",
++name_cnt, dot.tk_file, dot.tk_line);
return str2idf(buff);
return str2idf(buff, 1);
}
int
@ -236,10 +106,7 @@ declare_idf(ds, dc, lvl)
symbol2str(type->tp_fund));
} else error("void is not a complete type");
}
else if (type->tp_fund != LABEL) {
/* CJ */
strict("%s has size 0", idf->id_text);
}
else strict("%s has size 0", idf->id_text);
}
}
@ -522,7 +389,7 @@ declare_params(dc)
}
}
init_idf(idf)
idf_initialized(idf)
register struct idf *idf;
{
/* The topmost definition of idf is set to initialized.

View file

@ -7,30 +7,35 @@
#include "nopp.h"
#define HASHSIZE 307 /* must be odd */
#define STARTHASH() (0)
#define ENHASH(hs,ch) ((hs << 2) + ch)
#define STOPHASH(hs) ((unsigned)hs % HASHSIZE)
struct idf {
struct idf *next;
char *id_text;
struct id_u {
#ifndef NOPP
struct macro *id_macro;
int id_resmac; /* if nonzero: keyword of macroproc. */
struct macro *idd_macro;
int idd_resmac; /* if nonzero: keyword of macroproc. */
#endif NOPP
int id_reserved; /* non-zero for reserved words */
char *id_file; /* file containing the occurrence */
unsigned int id_line; /* line number of the occurrence */
struct def *id_def; /* variables, typedefs, enum-constants */
struct sdef *id_sdef; /* selector tags */
struct tag *id_struct; /* struct and union tags */
struct tag *id_enum; /* enum tags */
int id_special; /* special action needed at occurrence */
int idd_reserved; /* non-zero for reserved words */
char *idd_file; /* file containing the occurrence */
unsigned int idd_line; /* line number of the occurrence */
struct def *idd_label; /* labels */
struct def *idd_def; /* variables, typedefs, enum-constants */
struct sdef *idd_sdef; /* selector tags */
struct tag *idd_struct; /* struct and union tags */
int idd_special; /* special action needed at occurrence */
};
/* ALLOCDEF "idf" 50 */
#define IDF_TYPE struct id_u
#define id_macro id_user.idd_macro
#define id_resmac id_user.idd_resmac
#define id_reserved id_user.idd_reserved
#define id_file id_user.idd_file
#define id_line id_user.idd_line
#define id_label id_user.idd_label
#define id_def id_user.idd_def
#define id_sdef id_user.idd_sdef
#define id_struct id_user.idd_struct
#define id_enum id_user.idd_struct
#define id_special id_user.idd_special
#include <idf_pkg.spec>
#ifndef NOPP
struct dependency {
@ -41,7 +46,5 @@ struct dependency {
/* ALLOCDEF "dependency" 10 */
#endif /* NOPP */
extern struct idf *str2idf(), *idf_hashed();
extern int level;
extern struct idf *gen_idf();

View file

@ -56,7 +56,7 @@ init_pp()
register struct mkey *mk = &mkey[0];
while (mk->mk_reserved) {
register struct idf *idf = str2idf(mk->mk_reserved);
register struct idf *idf = str2idf(mk->mk_reserved, 0);
if (idf->id_resmac)
fatal("maximum identifier length insufficient");
@ -75,22 +75,22 @@ init_pp()
sprint(dbuf, "\"%s %02d %d\"", months[tp->tm_mon],
tp->tm_mday, tp->tm_year+1900);
if (tp->tm_mday < 10) dbuf[5] = ' '; /* hack */
macro_def(str2idf("__DATE__"), dbuf, -1, strlen(dbuf), NOUNDEF);
macro_def(str2idf("__DATE__", 0), dbuf, -1, strlen(dbuf), NOUNDEF);
/* __TIME__ */
sprint(tbuf, "\"%02d:%02d:%02d\"", tp->tm_hour, tp->tm_min, tp->tm_sec);
macro_def(str2idf("__TIME__"), tbuf, -1, strlen(tbuf), NOUNDEF);
macro_def(str2idf("__TIME__", 0), tbuf, -1, strlen(tbuf), NOUNDEF);
/* __LINE__ */
macro_def(str2idf("__LINE__"), "0", -1, 1, NOUNDEF | FUNC);
macro_def(str2idf("__LINE__", 0), "0", -1, 1, NOUNDEF | FUNC);
/* __FILE__ */
macro_def(str2idf("__FILE__"), "", -1, 1, NOUNDEF | FUNC);
macro_def(str2idf("__FILE__", 0), "", -1, 1, NOUNDEF | FUNC);
/* __STDC__ */
macro_def(str2idf("__STDC__"), "1", -1, 1, NOUNDEF);
macro_def(str2idf("__STDC__", 0), "1", -1, 1, NOUNDEF);
/* defined(??) */
macro_def(str2idf("defined"), "", 1, 1, NOUNDEF | FUNC);
macro_def(str2idf("defined", 0), "", 1, 1, NOUNDEF | FUNC);
}
#endif NOPP

View file

@ -128,10 +128,12 @@ end_brace(stl)
while (se) {
register struct idf *idf = se->se_idf;
register struct def *def = idf->id_def;
if (def) {
lint_1_local(idf, def);
if (idf->id_def) {
lint_1_local(idf, idf->id_def);
}
if (stl->sl_level == L_LOCAL && idf->id_label) {
lint_1_local(idf, idf->id_label);
}
se = se->next;
}

View file

@ -23,26 +23,19 @@ enter_label(idf, defining)
scope, i.e., on the lowest possible level.
If defining, the label comes from a label statement.
*/
register struct def *def = idf->id_def;
register struct def *def = idf->id_label;
if (def) {
if (def->df_sc == LABEL) {
if (defining && def->df_initialized)
error("redeclaration of label %s",
idf->id_text);
}
else { /* there may still be room for it */
if (def->df_level == level) /* but alas, no */
error("%s is not a label", idf->id_text);
else {
add_def(idf, LABEL, label_type, L_LOCAL);
}
}
if (defining && def->df_initialized)
error("redeclaration of label %s", idf->id_text);
}
else {
add_def(idf, LABEL, label_type, L_LOCAL);
def = new_def();
def->df_sc = LABEL;
idf->id_label = def;
def->df_file = idf->id_file;
def->df_line = idf->id_line;
}
def = idf->id_def; /* might be changed by 1 of the 2 add_defs */
if (def->df_address == 0)
def->df_address = (arith) text_label();
if (defining)
@ -54,6 +47,6 @@ unstack_label(idf)
{
/* The scope in which the label idf occurred is left.
*/
if (!idf->id_def->df_initialized && !is_anon_idf(idf))
if (!idf->id_label->df_initialized && !is_anon_idf(idf))
error("label %s not defined", idf->id_text);
}

View file

@ -121,7 +121,7 @@ main(argc, argv)
compile(argc - 1, &argv[1]);
#ifdef DEBUG
hash_stat();
if (options['h']) hash_stat();
if (options['m']) Info();
#endif DEBUG
@ -175,7 +175,7 @@ char *source;
add_dependency(s)
char *s;
{
register struct idf *p = str2idf(s);
register struct idf *p = str2idf(s, 1);
if (! p->id_resmac) {
register struct dependency *q = new_dependency();
@ -347,7 +347,6 @@ init()
double_type = standard_type(DOUBLE, 0, double_align, double_size);
lngdbl_type = standard_type(LNGDBL, 0, lngdbl_align, lngdbl_size);
void_type = standard_type(VOID, 0, 1, (arith)-1);
label_type = standard_type(LABEL, 0, 0, (arith)0);
error_type = standard_type(ERRONEOUS, 0, 1, (arith)1);
/* Pointer Arithmetic type: all arithmetics concerning
@ -375,11 +374,11 @@ init()
string_type = construct_type(POINTER, schar_type, 0, (arith)0, NO_PROTO);
/* Define the standard type identifiers. */
add_def(str2idf("char"), TYPEDEF, schar_type, L_UNIVERSAL);
add_def(str2idf("int"), TYPEDEF, int_type, L_UNIVERSAL);
add_def(str2idf("float"), TYPEDEF, float_type, L_UNIVERSAL);
add_def(str2idf("double"), TYPEDEF, double_type, L_UNIVERSAL);
add_def(str2idf("void"), TYPEDEF, void_type, L_UNIVERSAL);
add_def(str2idf("char", 0), TYPEDEF, schar_type, L_UNIVERSAL);
add_def(str2idf("int", 0), TYPEDEF, int_type, L_UNIVERSAL);
add_def(str2idf("float", 0), TYPEDEF, float_type, L_UNIVERSAL);
add_def(str2idf("double", 0), TYPEDEF, double_type, L_UNIVERSAL);
add_def(str2idf("void", 0), TYPEDEF, void_type, L_UNIVERSAL);
stack_level();
}
@ -387,7 +386,7 @@ init_specials(si)
register struct sp_id *si;
{
while (si->si_identifier) {
struct idf *idf = str2idf(si->si_identifier);
struct idf *idf = str2idf(si->si_identifier, 0);
if (idf->id_special)
fatal("maximum identifier length insufficient");
@ -473,7 +472,7 @@ Info()
extern int cnt_string_cst, cnt_formal,
cnt_decl_unary, cnt_def, cnt_expr, cnt_field,
cnt_e_stack, cnt_localvar, cnt_proto, cnt_repl,
cnt_args, cnt_idf, cnt_macro, cnt_stack_level,
cnt_args, cnt_macro, cnt_stack_level,
cnt_stack_entry, cnt_stmt_block, cnt_sdef, cnt_tag,
cnt_switch_hdr, cnt_case_entry, cnt_type, cnt_brace,
cnt_lint_stack_entry, cnt_state, cnt_auto_def,
@ -482,7 +481,7 @@ Info()
%6d string_cst\n%6d formal\n\
%6d decl_unary\n%6d def\n%6d expr\n%6d field\n\
%6d e_stack\n%6d localvar\n%6d proto\n%6d repl\n\
%6d args\n%6d idf\n%6d macro\n%6d stack_level\n\
%6d args\n%6d macro\n%6d stack_level\n\
%6d stack_entry\n%6d stmt_block\n%6d sdef\n%6d tag\n\
%6d switch_hdr\n%6d case_entry\n%6d type\n%6d brace\n\
%6d lint_stack_entry\n%6d state\n%6d auto_def\n\
@ -490,7 +489,7 @@ Info()
cnt_string_cst, cnt_formal,
cnt_decl_unary, cnt_def, cnt_expr, cnt_field,
cnt_e_stack, cnt_localvar, cnt_proto, cnt_repl,
cnt_args, cnt_idf, cnt_macro, cnt_stack_level,
cnt_args, cnt_macro, cnt_stack_level,
cnt_stack_entry, cnt_stmt_block, cnt_sdef, cnt_tag,
cnt_switch_hdr, cnt_case_entry, cnt_type, cnt_brace,
cnt_lint_stack_entry, cnt_state, cnt_auto_def,

View file

@ -146,7 +146,7 @@ next_option: /* to allow combined one-char options */
break;
}
macro_def(str2idf(name), mactext, -1, (int)maclen, NOFLAG);
macro_def(str2idf(name, 0), mactext, -1, (int)maclen, NOFLAG);
break;
}
@ -203,7 +203,7 @@ next_option: /* to allow combined one-char options */
#ifndef NOPP
case 'U' : /* -Uname : undefine predefined */
if (*text) do_undef(str2idf(text));
if (*text) do_undef(str2idf(text, 0));
break;
#endif NOPP

View file

@ -205,7 +205,7 @@ function(struct decspecs *ds; struct declarator *dc;)
#ifdef LINT
lint_start_function();
#endif LINT
init_idf(idf);
idf_initialized(idf);
stack_level(); /* L_FORMAL1 declarations */
declare_params(dc);
begin_proc(ds, idf); /* sets global function info */

View file

@ -181,7 +181,7 @@ struct idf **idpp;
}
*idpp = tp->tp_idf;
switch(tp->tp_fund) {
case ENUM: tg = tp->tp_idf->id_enum; break;
case ENUM:
case UNION:
case STRUCT: tg = tp->tp_idf->id_struct; break;
}
@ -331,7 +331,7 @@ struct type *tp;
ident = tp->tp_idf;
switch (tp->tp_fund) {
case ENUM: tgpp = &(ident->id_enum); break;
case ENUM:
case STRUCT:
case UNION: tgpp = &(ident->id_struct); break;
default: return;

View file

@ -326,7 +326,6 @@ actual(repl)
register char *p = buf;
register struct idf *idef;
register int pos = -1;
register int hash;
extern int idfsize;
int NoExpandMacro;
@ -335,26 +334,23 @@ actual(repl)
ch = GetChar();
} else NoExpandMacro = 0;
hash = STARTHASH();
do {
if (++pos < idfsize) {
*p++ = ch;
hash = ENHASH(hash, ch);
}
ch = GetChar();
} while (in_idf(ch));
hash = STOPHASH(hash);
*p++ = '\0';
UnGetChar();
/* When the identifier has an associated macro
replacement list, it's expanded.
*/
idef = idf_hashed(buf, (int) (p - buf), hash);
if (NoExpandMacro || !replace(idef)) {
if ((idef->id_macro
&& (idef->id_macro->mc_flag & NOREPLACE))
|| NoExpandMacro)
idef = findidf(buf);
if (!idef || NoExpandMacro || !replace(idef)) {
if (NoExpandMacro
|| (idef && idef->id_macro
&& (idef->id_macro->mc_flag & NOREPLACE)))
stash(repl, NOEXPM, !nostashraw);
for (p = buf; *p != '\0'; p++)
stash(repl, *p, !nostashraw);

View file

@ -130,11 +130,14 @@ unstack_level()
local_level->sl_entry = se->next;
free_stack_entry(se);
if (level == L_LOCAL && (def = idf->id_label)) {
unstack_label(idf);
free_def(def);
idf->id_label = 0;
}
while ((def = idf->id_def) && def->df_level >= level) {
/* unlink it from the def list under the idf block */
if (def->df_sc == LABEL)
unstack_label(idf);
else if (def->df_sc == REGISTER || def->df_sc == AUTO)
if (def->df_sc == REGISTER || def->df_sc == AUTO)
FreeLocal(def->df_address);
idf->id_def = def->next;
free_def(def);
@ -154,11 +157,6 @@ unstack_level()
idf->id_struct = tag->next;
free_tag(tag);
}
while ((tag = idf->id_enum) && tag->tg_level >= level) {
/* unlink it from the enum list under the idf block */
idf->id_enum = tag->next;
free_tag(tag);
}
}
/* Unlink the local stack level from the stack.
*/

View file

@ -128,7 +128,7 @@ label
lint_label();
#endif LINT
define_label(idf);
C_df_ilb((label)idf->id_def->df_address);
C_df_ilb((label)idf->id_label->df_address);
}
;
@ -455,7 +455,7 @@ jump
';'
{
apply_label(idf);
C_bra((label)idf->id_def->df_address);
C_bra((label)idf->id_label->df_address);
#ifdef LINT
lint_jump_stmt(idf);
#endif LINT

View file

@ -183,7 +183,7 @@ declare_struct(fund, idf, tpp)
if (*tpp) error("multiple types in declaration");
if (!idf)
idf = gen_idf();
tgp = (fund == ENUM ? &idf->id_enum : &idf->id_struct);
tgp = &idf->id_struct;
tg = *tgp;
if (tg
&& tg->tg_type->tp_size < 0
@ -243,7 +243,7 @@ apply_struct(fund, idf, tpp)
*/
register struct tag **tgp;
tgp = (is_struct_or_union(fund) ? &idf->id_struct : &idf->id_enum);
tgp = &idf->id_struct;
if (*tgp)
*tpp = (*tgp)->tg_type;

View file

@ -138,7 +138,7 @@ reserve(resv)
as reserved words.
*/
while (resv->tn_symbol) {
struct idf *idf = str2idf(resv->tn_name);
struct idf *idf = str2idf(resv->tn_name, 0);
if (idf->id_reserved)
fatal("maximum identifier length insufficient");

View file

@ -34,7 +34,7 @@ struct type
*int_type, *uint_type,
*long_type, *ulong_type,
*float_type, *double_type, *lngdbl_type,
*void_type, *label_type,
*void_type,
*string_type, *funint_type, *error_type;
struct type *pa_type; /* Pointer-Arithmetic type */

View file

@ -73,7 +73,7 @@ extern struct type
*int_type, *uint_type,
*long_type, *ulong_type,
*float_type, *double_type, *lngdbl_type,
*void_type, *label_type,
*void_type,
*string_type, *funint_type, *error_type;
extern struct type *pa_type; /* type.c */