/* * Initialize the initialisation stack by putting an entry for the variable * which is to be initialized on it. */ void prepinit(void) { istk_t *istk; if (initerr) return; /* free memory used in last initialisation */ while ((istk = initstk) != NULL) { initstk = istk->i_nxt; free(istk); } /* * If the type which is to be initialized is an incomplete type, * it must be duplicated. */ if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type)) initsym->s_type = duptyp(initsym->s_type); istk = initstk = xcalloc(1, sizeof (istk_t)); istk->i_subt = initsym->s_type; istk->i_cnt = 1; }
/* * Called after a function declaration which introduces a function definition * and before an (optional) old style argument declaration list. * * Puts all symbols declared in the Prototype or in an old style argument * list back to the symbol table. * * Does the usual checking of storage class, type (return value), * redeclaration etc.. */ void funcdef(sym_t *fsym) { int n, warn; sym_t *arg, *sym, *rdsym; funcsym = fsym; /* * Put all symbols declared in the argument list back to the * symbol table. */ for (sym = dcs->d_fpsyms; sym != NULL; sym = sym->s_dlnxt) { if (sym->s_blklev != -1) { if (sym->s_blklev != 1) lerror("funcdef() 1"); inssym(1, sym); } } /* * In osfunc() we did not know whether it is an old style function * definition or only an old style declaration, if there are no * arguments inside the argument list ("f()"). */ if (!fsym->s_type->t_proto && fsym->s_args == NULL) fsym->s_osdef = 1; chktyp(fsym); /* * chktyp() checks for almost all possible errors, but not for * incomplete return values (these are allowed in declarations) */ if (fsym->s_type->t_subt->t_tspec != VOID && incompl(fsym->s_type->t_subt)) { /* cannot return incomplete type */ error(67); } fsym->s_def = DEF; if (fsym->s_scl == TYPEDEF) { fsym->s_scl = EXTERN; /* illegal storage class */ error(8); } if (dcs->d_inline) fsym->s_inline = 1; /* * Arguments in new style function declarations need a name. * (void is already removed from the list of arguments) */ n = 1; for (arg = fsym->s_type->t_args; arg != NULL; arg = arg->s_nxt) { if (arg->s_scl == ABSTRACT) { if (arg->s_name != unnamed) lerror("funcdef() 2"); /* formal parameter lacks name: param #%d */ error(59, n); } else { if (arg->s_name == unnamed) lerror("funcdef() 3"); } n++; } /* * We must also remember the position. s_dpos is overwritten * if this is an old style definition and we had already a * prototype. */ STRUCT_ASSIGN(dcs->d_fdpos, fsym->s_dpos); if ((rdsym = dcs->d_rdcsym) != NULL) { if (!isredec(fsym, (warn = 0, &warn))) { /* * Print nothing if the newly defined function * is defined in old style. A better warning will * be printed in cluparg(). */ if (warn && !fsym->s_osdef) { /* redeclaration of %s */ (*(sflag ? error : warning))(27, fsym->s_name); prevdecl(-1, rdsym); } /* copy usage information */ cpuinfo(fsym, rdsym); /* * If the old symbol was a prototype and the new * one is none, overtake the position of the * declaration of the prototype. */ if (fsym->s_osdef && rdsym->s_type->t_proto) STRUCT_ASSIGN(fsym->s_dpos, rdsym->s_dpos); /* complete the type */ compltyp(fsym, rdsym); /* once a function is inline it remains inline */ if (rdsym->s_inline) fsym->s_inline = 1; } /* remove the old symbol from the symbol table */ rmsym(rdsym); } if (fsym->s_osdef && !fsym->s_type->t_proto) { if (sflag && hflag && strcmp(fsym->s_name, "main") != 0) /* function definition is not a prototype */ warning(286); } if (dcs->d_notyp) /* return value is implicitly declared to be int */ fsym->s_rimpl = 1; reached = 1; }
static void pushinit(void) { istk_t *istk; int cnt; sym_t *m; istk = initstk; /* Extend an incomplete array type by one element */ if (istk->i_cnt == 0) { /* * Inside of other aggregate types must not be an incomplete * type. */ if (istk->i_nxt->i_nxt != NULL) lerror("pushinit() 1"); istk->i_cnt = 1; if (istk->i_type->t_tspec != ARRAY) lerror("pushinit() 2"); istk->i_type->t_dim++; /* from now its a complete type */ setcompl(istk->i_type, 0); } if (istk->i_cnt <= 0) lerror("pushinit() 3"); if (istk->i_type != NULL && issclt(istk->i_type->t_tspec)) lerror("pushinit() 4"); initstk = xcalloc(1, sizeof (istk_t)); initstk->i_nxt = istk; initstk->i_type = istk->i_subt; if (initstk->i_type->t_tspec == FUNC) lerror("pushinit() 5"); istk = initstk; switch (istk->i_type->t_tspec) { case ARRAY: if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) { /* initialisation of an incomplete type */ error(175); initerr = 1; return; } istk->i_subt = istk->i_type->t_subt; istk->i_nolimit = incompl(istk->i_type); istk->i_cnt = istk->i_type->t_dim; break; case UNION: if (tflag) /* initialisation of union is illegal in trad. C */ warning(238); /* FALLTHROUGH */ case STRUCT: if (incompl(istk->i_type)) { /* initialisation of an incomplete type */ error(175); initerr = 1; return; } cnt = 0; for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) { if (m->s_field && m->s_name == unnamed) continue; if (++cnt == 1) { istk->i_mem = m; istk->i_subt = m->s_type; } } if (cnt == 0) { /* cannot init. struct/union with no named member */ error(179); initerr = 1; return; } istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1; break; default: istk->i_cnt = 1; break; } }