📄 decl.c
字号:
foreach(identifiers, level, checkref, NULL); if (!IR->wants_callb && isstruct(rty)) { Symbol *a; a = newarray(n + 2, sizeof *a, FUNC); a[0] = retv; memcpy(&a[1], callee, (n+1)*sizeof *callee); callee = a; a = newarray(n + 2, sizeof *a, FUNC); NEW(a[0], FUNC); *a[0] = *retv; memcpy(&a[1], caller, (n+1)*sizeof *callee); caller = a; } if (!IR->wants_argb) for (i = 0; caller[i]; i++) if (isstruct(caller[i]->type)) { caller[i]->type = ptr(caller[i]->type); callee[i]->type = ptr(callee[i]->type); caller[i]->structarg = callee[i]->structarg = 1; } if (glevel > 1) for (i = 0; callee[i]; i++) callee[i]->sclass = AUTO; if (cfunc->sclass != STATIC) (*IR->export)(cfunc); if (glevel && IR->stabsym) { swtoseg(CODE); (*IR->stabsym)(cfunc); } swtoseg(CODE); (*IR->function)(cfunc, caller, callee, cfunc->u.f.ncalls); if (glevel && IR->stabfend) (*IR->stabfend)(cfunc, lineno); foreach(stmtlabs, LABELS, checklab, NULL); exitscope(); expect('}'); labels = stmtlabs = NULL; retv = NULL; cfunc = NULL;}static void oldparam(Symbol p, void *cl) { int i; Symbol *callee = cl; for (i = 0; callee[i]; i++) if (p->name == callee[i]->name) { callee[i] = p; return; } error("declared parameter `%s' is missing\n", p->name);}void compound(int loop, struct swtch *swp, int lev) { Code cp; int nregs; walk(NULL, 0, 0); cp = code(Blockbeg); enterscope(); assert(level >= LOCAL); if (level == LOCAL && events.entry) apply(events.entry, cfunc, NULL); definept(NULL); expect('{'); autos = registers = NULL; if (level == LOCAL && IR->wants_callb && isstruct(freturn(cfunc->type))) { retv = genident(AUTO, ptr(unqual(freturn(cfunc->type))), level); retv->defined = 1; retv->ref = 1; registers = append(retv, registers); } while (kind[t] == CHAR || kind[t] == STATIC || istypename(t, tsym) && getchr() != ':') decl(dcllocal); { int i; Symbol *a = ltov(&autos, STMT); nregs = length(registers); for (i = 0; a[i]; i++) registers = append(a[i], registers); cp->u.block.locals = ltov(®isters, FUNC); } if (events.blockentry) apply(events.blockentry, cp->u.block.locals, NULL); while (kind[t] == IF || kind[t] == ID) statement(loop, swp, lev); walk(NULL, 0, 0); foreach(identifiers, level, checkref, NULL); { int i = nregs, j; Symbol p; for ( ; (p = cp->u.block.locals[i]) != NULL; i++) { for (j = i; j > nregs && cp->u.block.locals[j-1]->ref < p->ref; j--) cp->u.block.locals[j] = cp->u.block.locals[j-1]; cp->u.block.locals[j] = p; } } if (level == LOCAL) { Code cp; for (cp = codelist; cp->kind < Label; cp = cp->prev) ; if (cp->kind != Jump) { if (freturn(cfunc->type) != voidtype) { warning("missing return value\n"); retcode(cnsttree(inttype, 0L)); } else retcode(NULL); } } if (events.blockexit) apply(events.blockexit, cp->u.block.locals, NULL); cp->u.block.level = level; cp->u.block.identifiers = identifiers; cp->u.block.types = types; code(Blockend)->u.begin = cp; if (reachable(Gen)) definept(NULL); if (level > LOCAL) { exitscope(); expect('}'); }}static void checkref(Symbol p, void *cl) { if (p->scope >= PARAM && (isvolatile(p->type) || isfunc(p->type))) p->addressed = 1; if (Aflag >= 2 && p->defined && p->ref == 0) { if (p->sclass == STATIC) warning("static `%t %s' is not referenced\n", p->type, p->name); else if (p->scope == PARAM) warning("parameter `%t %s' is not referenced\n", p->type, p->name); else if (p->scope >= LOCAL && p->sclass != EXTERN) warning("local `%t %s' is not referenced\n", p->type, p->name); } if (p->sclass == AUTO && (p->scope == PARAM && regcount == 0 || p->scope >= LOCAL) && !p->addressed && isscalar(p->type) && p->ref >= 3.0) p->sclass = REGISTER; if (level == GLOBAL && p->sclass == STATIC && !p->defined && isfunc(p->type) && p->ref) error("undefined static `%t %s'\n", p->type, p->name); assert(!(level == GLOBAL && p->sclass == STATIC && !p->defined && !isfunc(p->type)));}static Symbol dcllocal(int sclass, char *id, Type ty, Coordinate *pos) { Symbol p, q; if (sclass == 0) sclass = isfunc(ty) ? EXTERN : AUTO; else if (isfunc(ty) && sclass != EXTERN) { error("invalid storage class `%k' for `%t %s'\n", sclass, ty, id); sclass = EXTERN; } else if (sclass == REGISTER && (isvolatile(ty) || isstruct(ty) || isarray(ty))) { warning("register declaration ignored for `%t %s'\n", ty, id); sclass = AUTO; } q = lookup(id, identifiers); if (q && q->scope >= level || q && q->scope == PARAM && level == LOCAL) if (sclass == EXTERN && q->sclass == EXTERN && eqtype(q->type, ty, 1)) ty = compose(ty, q->type); else error("redeclaration of `%s' previously declared at %w\n", q->name, &q->src); assert(level >= LOCAL); p = install(id, &identifiers, level, sclass == STATIC || sclass == EXTERN ? PERM : FUNC); p->type = ty; p->sclass = sclass; p->src = *pos; switch (sclass) { case EXTERN: q = lookup(id, globals); if (q == NULL || q->sclass == TYPEDEF || q->sclass == ENUM) { q = lookup(id, externals); if (q == NULL) { q = install(p->name, &externals, GLOBAL, PERM); q->type = p->type; q->sclass = EXTERN; q->src = src; (*IR->defsymbol)(q); } } if (!eqtype(p->type, q->type, 1)) warning("declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src); p->u.alias = q; break; case STATIC: (*IR->defsymbol)(p); initglobal(p, 0); if (!p->defined) if (p->type->size > 0) { defglobal(p, BSS); (*IR->space)(p->type->size); } else error("undefined size for `%t %s'\n", p->type, p->name); p->defined = 1; break; case REGISTER: registers = append(p, registers); regcount++; p->defined = 1; break; case AUTO: autos = append(p, autos); p->defined = 1; if (isarray(ty)) p->addressed = 1; break; default: assert(0); } if (t == '=') { Tree e; if (sclass == EXTERN) error("illegal initialization of `extern %s'\n", id); t = gettok(); definept(NULL); if (isscalar(p->type) || isstruct(p->type) && t != '{') { if (t == '{') { t = gettok(); e = expr1(0); expect('}'); } else e = expr1(0); } else { Symbol t1; Type ty = p->type, ty1 = ty; while (isarray(ty1)) ty1 = ty1->type; if (!isconst(ty) && (!isarray(ty) || !isconst(ty1))) ty = qual(CONST, ty); t1 = genident(STATIC, ty, GLOBAL); initglobal(t1, 1); if (isarray(p->type) && p->type->size == 0 && t1->type->size > 0) p->type = array(p->type->type, t1->type->size/t1->type->type->size, 0); e = idtree(t1); } walk(root(asgn(p, e)), 0, 0); p->ref = 1; } if (!isfunc(p->type) && p->defined && p->type->size <= 0) error("undefined size for `%t %s'\n", p->type, id); return p;}void finalize(void) { foreach(externals, GLOBAL, doextern, NULL); foreach(identifiers, GLOBAL, doglobal, NULL); foreach(identifiers, GLOBAL, checkref, NULL); foreach(constants, CONSTANTS, doconst, NULL);}static void doextern(Symbol p, void *cl) { (*IR->import)(p);}static void doglobal(Symbol p, void *cl) { if (!p->defined && (p->sclass == EXTERN || isfunc(p->type) && p->sclass == AUTO)) (*IR->import)(p); else if (!p->defined && !isfunc(p->type) && (p->sclass == AUTO || p->sclass == STATIC)) { if (isarray(p->type) && p->type->size == 0 && p->type->type->size > 0) p->type = array(p->type->type, 1, 0); if (p->type->size > 0) { defglobal(p, BSS); (*IR->space)(p->type->size); if (glevel > 0 && IR->stabsym) (*IR->stabsym)(p); } else error("undefined size for `%t %s'\n", p->type, p->name); p->defined = 1; } if (Pflag && !isfunc(p->type) && !p->generated && p->sclass != EXTERN) printdecl(p, p->type);}void doconst(Symbol p, void *cl) { if (p->u.c.loc) { assert(p->u.c.loc->u.seg == 0); defglobal(p->u.c.loc, LIT); if (isarray(p->type) && p->type->type == widechar) { unsigned int *s = p->u.c.v.p; int n = p->type->size/widechar->size; while (n-- > 0) { Value v; v.u = *s++; (*IR->defconst)(widechar->op, widechar->size, v); } } else if (isarray(p->type)) (*IR->defstring)(p->type->size, p->u.c.v.p); else (*IR->defconst)(p->type->op, p->type->size, p->u.c.v); p->u.c.loc = NULL; }}void checklab(Symbol p, void *cl) { if (!p->defined) error("undefined label `%s'\n", p->name); p->defined = 1;}Type enumdcl(void) { char *tag; Type ty; Symbol p; Coordinate pos; t = gettok(); pos = src; if (t == ID) { tag = token; t = gettok(); } else tag = ""; if (t == '{') { static char follow[] = { IF, 0 }; int n = 0; long k = -1; List idlist = 0; ty = newstruct(ENUM, tag); t = gettok(); if (t != ID) error("expecting an enumerator identifier\n"); while (t == ID) { char *id = token; Coordinate s; if (tsym && tsym->scope == level) error("redeclaration of `%s' previously declared at %w\n", token, &tsym->src); s = src; t = gettok(); if (t == '=') { t = gettok(); k = intexpr(0, 0); } else { if (k == inttype->u.sym->u.limits.max.i) error("overflow in value for enumeration constant `%s'\n", id); k++; } p = install(id, &identifiers, level, level < LOCAL ? PERM : FUNC); p->src = s; p->type = ty; p->sclass = ENUM; p->u.value = k; idlist = append(p, idlist); n++; if (Aflag >= 2 && n == 128) warning("more than 127 enumeration constants in `%t'\n", ty); if (t != ',') break; t = gettok(); if (Aflag >= 2 && t == '}') warning("non-ANSI trailing comma in enumerator list\n"); } test('}', follow); ty->type = inttype; ty->size = ty->type->size; ty->align = ty->type->align; ty->u.sym->u.idlist = ltov(&idlist, PERM); ty->u.sym->defined = 1; } else if ((p = lookup(tag, types)) != NULL && p->type->op == ENUM) { ty = p->type; if (t == ';') error("empty declaration\n"); } else { error("unknown enumeration `%s'\n", tag); ty = newstruct(ENUM, tag); ty->type = inttype; } if (*tag && xref) use(p, pos); return ty;}Type typename(void) { Type ty = specifier(NULL); if (t == '*' || t == '(' || t == '[') { ty = dclr(ty, NULL, NULL, 1); if (Aflag >= 1 && !hasproto(ty)) warning("missing prototype\n"); } return ty;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -