#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 */
{
register char *tg = &buf[0];
register int pos = -1;
- register int hash;
register struct idf *idef;
extern int idfsize; /* ??? */
#ifndef NOPP
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
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);
stb_string(idf->id_def, sc, idf->id_text);
}
#endif /* DBSYMTAB */
- init_idf(idf);
+ idf_initialized(idf);
}
;
print(" ");
}
+int dumpidf();
+
dumpidftab(msg, opt)
char msg[];
{
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);
}
}
dumptags(idf->id_struct);
}
- if (idf->id_enum) {
- if (!started++) {
- newline();
- print("%s:", idf->id_text);
- }
- dumptags(idf->id_enum);
- }
}
dumpdefs(def, opt)
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 ||
#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 */
-
-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.).
- */
+#ifdef DEBUG
+#define IDF_DEBUG
+#endif
-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 = ¬ch->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()
sprint(buff, "#%d in %s, line %u",
++name_cnt, dot.tk_file, dot.tk_line);
- return str2idf(buff);
+ return str2idf(buff, 1);
}
int
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);
}
}
}
}
-init_idf(idf)
+idf_initialized(idf)
register struct idf *idf;
{
/* The topmost definition of idf is set to initialized.
#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 {
/* ALLOCDEF "dependency" 10 */
#endif /* NOPP */
-extern struct idf *str2idf(), *idf_hashed();
-
extern int level;
extern struct idf *gen_idf();
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");
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
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;
}
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)
{
/* 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);
}
compile(argc - 1, &argv[1]);
#ifdef DEBUG
- hash_stat();
+ if (options['h']) hash_stat();
if (options['m']) Info();
#endif DEBUG
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();
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
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();
}
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");
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,
%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\
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,
break;
}
- macro_def(str2idf(name), mactext, -1, (int)maclen, NOFLAG);
+ macro_def(str2idf(name, 0), mactext, -1, (int)maclen, NOFLAG);
break;
}
#ifndef NOPP
case 'U' : /* -Uname : undefine predefined */
- if (*text) do_undef(str2idf(text));
+ if (*text) do_undef(str2idf(text, 0));
break;
#endif NOPP
#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 */
}
*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;
}
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;
register char *p = buf;
register struct idf *idef;
register int pos = -1;
- register int hash;
extern int idfsize;
int NoExpandMacro;
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);
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);
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.
*/
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);
}
;
';'
{
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
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
*/
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;
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");
*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 */
*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 */