/* H I G H L E V E L S Y M B O L E N T R Y */ #include #include #include #include #include #include "parameters.h" #include "LLlex.h" #include "def.h" #include "idf.h" #include "main.h" #include "node.h" #include "scope.h" #include "type.h" #include "progs.h" #include "enter.h" #ifdef DBSYMTAB #include "stab.h" #endif extern int proclevel; extern int parlevel; struct def *Enter(char *name, long kind, register struct type *type, int pnam) { /* Enter a definition for "name" with kind "kind" and type "type" in the Current Scope. If it is a standard name, also put its number in the definition structure, and mark the name as set, to inhibit warnings about used before set. */ register struct def *df; df = define(str2idf(name, 0), CurrentScope, kind); df->df_type = type; if (pnam) { df->df_value.df_reqname = pnam; df->df_flags |= D_SET; } #ifdef DBSYMTAB else if (options['g']) stb_string(df, kind); #endif /* DBSYMTAB */ return df; } void EnterProgList(register struct node *Idlist) { register struct node *idlist = Idlist; register struct def *df; for (; idlist; idlist = idlist->nd_next) if (!strcmp(input, idlist->nd_IDF->id_text) || !strcmp(output, idlist->nd_IDF->id_text)) { /* the occurence of input or output as program- * parameter is their declaration as a GLOBAL * variable of type text */ if ( (df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE)) ) { df->df_type = text_type; df->df_flags |= (D_SET | D_PROGPAR | D_NOREG); if (!strcmp(input, idlist->nd_IDF->id_text)) { df->var_name = input; set_inp(); } else { df->var_name = output; set_outp(); } #ifdef DBSYMTAB if (options['g']) stb_string(df, D_VARIABLE); #endif /* DBSYMTAB */ } } else { if ( (df = define(idlist->nd_IDF, CurrentScope, D_PARAMETER)) ) { df->df_type = error_type; df->df_flags |= D_PROGPAR; df->var_name = idlist->nd_IDF->id_text; } } FreeNode(Idlist); } void EnterEnumList(struct node *Idlist, register struct type *type) { /* Put a list of enumeration literals in the symbol table. They all have type "type". Also assign numbers to them. */ register struct def *df, *df1 = 0; register struct node *idlist = Idlist; type->enm_ncst = 0; for (; idlist; idlist = idlist->nd_next) if ( (df = define(idlist->nd_IDF, CurrentScope, D_ENUM)) ) { df->df_type = type; df->enm_val = (type->enm_ncst)++; df->df_flags |= D_SET; if (!df1) { type->enm_enums = df; } else df1->enm_next = df; df1 = df; } FreeNode(Idlist); } void EnterFieldList(struct node *Idlist, register struct type *type, struct scope *scope, arith *addr, unsigned short packed) { /* Put a list of fields in the symbol table. They all have type "type", and are put in scope "scope". */ register struct def *df; register struct node *idlist = Idlist; for (; idlist; idlist = idlist->nd_next) if ( (df = define(idlist->nd_IDF, scope, D_FIELD)) ) { df->df_type = type; if (packed) { df->fld_flags |= F_PACKED; df->fld_off = align(*addr, type->tp_palign); *addr = df->fld_off + type->tp_psize; } else { df->fld_off = align(*addr, type->tp_align); *addr = df->fld_off + type->tp_size; } } FreeNode(Idlist); } void EnterVarList(struct node *Idlist, struct type *type, int local) { /* Enter a list of identifiers representing variables into the name list. "type" represents the type of the variables. "local" is set if the variables are declared local to a procedure. */ register struct def *df; register struct node *idlist = Idlist; register struct scopelist *sc = CurrVis; for (; idlist; idlist = idlist->nd_next) { if (!(df = define(idlist->nd_IDF, CurrentScope, D_VARIABLE))) continue; /* skip this identifier */ df->df_type = type; if (local) { /* subtract size, which is already aligned, of * variable to the offset, as the variable list * exists only local to a procedure */ sc->sc_scope->sc_off -= type->tp_size; df->var_off = sc->sc_scope->sc_off; } else { /* Global name */ df->var_name = df->df_idf->id_text; df->df_flags |= D_NOREG; } #ifdef DBSYMTAB if (options['g']) stb_string(df, D_VARIABLE); #endif /* DBSYMTAB */ } FreeNode(Idlist); } static void LinkParam(struct paramlist **parlist, struct def *df) { static struct paramlist *pr; if (!*parlist) *parlist = pr = new_paramlist(); else { pr->next = new_paramlist(); pr = pr->next; } pr->par_def = df; } arith EnterParamList(register struct node *fpl, struct paramlist **parlist) { register arith nb_pars = (proclevel > 1) ? pointer_size : 0; register struct node *id; struct type *tp; struct def *df; for (; fpl; fpl = fpl->nd_right) { assert(fpl->nd_class == Link); tp = fpl->nd_type; for (id = fpl->nd_left; id; id = id->nd_next) if ( (df = define(id->nd_IDF, CurrentScope, D_VARIABLE)) ) { df->var_off = nb_pars; if (fpl->nd_INT & D_VARPAR || IsConformantArray(tp)) nb_pars += pointer_size; else nb_pars += tp->tp_size; LinkParam(parlist, df); df->df_type = tp; df->df_flags |= fpl->nd_INT; } while (IsConformantArray(tp)) { /* we need room for the descriptors */ tp->arr_sclevel = CurrentScope->sc_level; tp->arr_cfdescr = nb_pars; nb_pars += 3 * word_size; tp = tp->arr_elem; } } return nb_pars; } arith EnterParTypes(register struct node *fpl, struct paramlist **parlist) { /* parameters.h in heading of procedural and functional parameters (only types are important, not the names). */ register arith nb_pars = 0; register struct node *id; struct type *tp; struct def *df; for (; fpl; fpl = fpl->nd_right) { tp = fpl->nd_type; for (id = fpl->nd_left; id; id = id->nd_next) if ( (df = new_def()) ) { if (fpl->nd_INT & D_VARPAR || IsConformantArray(tp)) nb_pars += pointer_size; else nb_pars += tp->tp_size; LinkParam(parlist, df); df->df_type = tp; df->df_flags |= fpl->nd_INT; } while (IsConformantArray(tp)) { nb_pars += 3 * word_size; tp = tp->arr_elem; } } return nb_pars; }