📄 decl.c
字号:
retv = genident(AUTO, ptr(rty), PARAM);
cp = compound(0, NULL, 0);
FunctionInfo.cp = cp;
for (cp = codelist; cp->kind < Label; cp = cp->prev);
if (cp->kind != Jump) {
if (rty != voidtype
&& (rty != inttype || Aflag >= 1))
warning(StrTab[360]);// <missing return value\n>
retcode(NULL);
}
definelab(cfunc->u.f.label);
definept(NULL,POINT_ENDFN);
if (events.exit)
apply(events.exit, cfunc, NULL);
walk(NULL, 0, 0);
exitscope();
assert(level == PARAM);
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 0
if (cfunc->sclass != STATIC)
(*IR->export) (cfunc);
#endif
if (glevel) {
swtoseg(CODE);
(*IR->stabsym) (cfunc);
}
swtoseg(CODE);
if (cfunc->u.f.ncalls)
FunctionHasCalls = 1;
else
FunctionHasCalls = 0;
FunctionInfo.FnNrOfLines = src.y - cfunc->src.y;
(*IR->function) (cfunc, caller, callee, cfunc->u.f.ncalls);
if (cfunc->sclass != STATIC)
(*IR->export) (cfunc);
if (glevel && IR->stabfend)
(*IR->stabfend) (cfunc, lineno);
outflush();
foreach(stmtlabs, LABELS, checklab, NULL);
exitscope();
expect('}');
AddToFunctionsList(cfunc);
labels = stmtlabs = NULL;
retv = NULL;
cfunc = NULL;
ResetExceptions();
}
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(StrTab[362], p->name);// <declared parameter `%s' is missing\n>
}
Code compound(int loop, struct swtch * swp, int lev)
{
Code cp;
int nregs;
walk(NULL, 0, 0);
cp = code(Blockbeg);
enterscope();
assert(level >= LOCAL);
autos = registers = NULL;
if (level == LOCAL && IR->wants_callb
&& isstruct(freturn(cfunc->type))) {
retv = genident(AUTO, ptr(freturn(cfunc->type)), level);
retv->defined = 1;
retv->ref = (float) 1.0;
registers = append(retv, registers);
}
if (level == LOCAL && events.entry)
apply(events.entry, cfunc, NULL);
expect('{');
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);
}
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;
}
}
cp->u.block.level = level;
cp->u.block.identifiers = identifiers;
cp->u.block.types = types;
code(Blockend)->u.begin = cp;
if (level > LOCAL) {
exitscope();
expect('}');
}
return cp;
}
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(StrTab[363],// <static `%t %s' is not referenced\n>
p->type, p->name);
else if (p->scope == PARAM && Aflag > 1)
warning(StrTab[364],// <parameter `%t %s' is not referenced\n>
p->type, p->name);
else if (p->scope >= LOCAL && p->sclass != EXTERN)
warning(StrTab[365],// <local `%t %s' is not referenced\n>
p->type, p->name);
}
if (p->scope >= LOCAL && p->sclass == EXTERN) {
Symbol q = lookup(p->name, externals);
assert(q);
q->ref += p->ref;
}
if (p->scope >= LOCAL && p->sclass != EXTERN ) {
if (Aflag &&
p->assigned == 1 && p->references == 1 && p->addressed == 0) {
warning(StrTab[366],p->name);// < %s is assigned a value that is never used\n>
}
else if (p->assigned == 0 && p->references > 0) {
if (p->type && p->type->op != ARRAY && p->type->op != STRUCT)
warning(StrTab[367],p->name);// < possible usage of %s before definition\n>
}
}
if (level == GLOBAL && p->sclass == STATIC && !p->defined
&& isfunc(p->type) && p->ref)
error(StrTab[368], p->type, p->name);// <undefined static `%t %s'\n>
assert(!(level == GLOBAL && p->sclass == STATIC && !p->defined && !isfunc(p->type)));
}
static Symbol dcllocal(int sclass, char *id, Type ty, Coordinate * pos,int callAttributes)
{
Symbol p, q;
if (sclass == 0)
sclass = isfunc(ty) ? EXTERN : AUTO;
else if (isfunc(ty) && sclass != EXTERN) {
error(StrTab[369],// <invalid storage class `%k' for `%t %s'\n>
sclass, ty, id);
sclass = EXTERN;
}
else if (sclass == REGISTER
&& (isvolatile(ty) || isstruct(ty) || isarray(ty))) {
warning(StrTab[370],// <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(StrTab[371], q->name, &q->src);// <redeclaration of `%s' previously declared at %w\n>
assert(level >= LOCAL);
p = install(id, &identifiers, level, FUNC);
p->type = ty;
p->sclass = sclass;
p->src = *pos;
p->Flags = callAttributes;
switch (sclass) {
case EXTERN:
if (q && q->scope == GLOBAL && q->sclass == STATIC) {
p->sclass = STATIC;
p->scope = GLOBAL;
(*IR->defsymbol) (p);
p->sclass = EXTERN;
p->scope = level;
}
else
(*IR->defsymbol) (p);
{
Symbol r = lookup(id, externals);
if (r == NULL) {
r = install(p->name, &externals, GLOBAL, PERM);
r->src = p->src;
r->type = p->type;
r->sclass = p->sclass;
q = lookup(id, globals);
if (q && q->sclass != TYPEDEF && q->sclass != ENUM)
r = q;
}
if (r && !eqtype(r->type, p->type, 1))
warning(StrTab[372], r->name, &r->src);// <declaration of `%s' does not match previous declaration at %w\n>
} 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(StrTab[373],// <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;
break;
default:
assert(0);
}
if (t == '=') {
Tree e;
if (sclass == EXTERN)
error(StrTab[374], id);// <illegal initialization of `extern %s'\n>
t = gettok();
definept(NULL,0);
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 = (float) 1.0;
p->firstuse = p->lastuse = StatementCount;
}
#if 0
else if (glevel >= 2 && OptimizeFlag == 0
&& ty && ty->op == POINTER && sclass == AUTO) {
/* Initialize all uninitialized pointers to a known value */
Tree e = tree(CNSTP, inttype, NULL, NULL);
int wasAssigned = p->assigned;
e->u.v.i = 0xffbadbad;
walk(root(asgn(p,e)),0,0);
p->assigned = wasAssigned;
}
#endif
if (!isfunc(p->type) && p->defined && p->type->size <= 0)
error(StrTab[375], p->type, id);// <undefined size for `%t %s'\n>
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)
{
Symbol q = lookup(p->name, identifiers);
if (q)
q->ref += p->ref;
else {
(*IR->defsymbol) (p);
(*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(StrTab[376],// <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))
(*IR->defstring) (p->type->size, p->u.c.v.p,p->type->type->size);
else
(*IR->defconst) (ttob(p->type), p->u.c.v);
p->u.c.loc->defined = 1;
p->u.c.loc = NULL;
}
}
void checklab(Symbol p, void *cl)
{
if (!p->defined)
error(StrTab[377], p->name);// <undefined label `%s'\n>
p->defined = 1;
}
Type enumdcl(void)
{
char *tag;
Type ty;
Symbol p;
Coordinate pos;
t = gettok();
pos = src;
p = NULL; /* Better be sure that p is initialized before use */
if (t == ID) {
tag = token;
t = gettok();
}
else
tag = "";
if (t == '{') {
static char follow[] = {IF, 0};
int n = 0, k = -1;
List idlist = 0;
ty = newstruct(ENUM, tag);
t = gettok();
if (t != ID)
error(StrTab[378]);// <expecting an enumerator identifier\n>
while (t == ID) {
char *id = token;
Coordinate s;
if (tsym && tsym->scope == level)
error(StrTab[379],// <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 == INT_MAX)
error(StrTab[380], id);// <overflow in value for enumeration constant `%s'\n>
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(StrTab[381], ty);// <more than 127 enumeration constants in `%t'\n>
if (t != ',')
break;
t = gettok();
if (Aflag >= 2 && t == '}')
warning(StrTab[382]);// <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(StrTab[383]);// <empty declaration\n>
}
else {
error(StrTab[384], tag);// <unknown enumeration `%s'\n>
ty = newstruct(ENUM, tag);
ty->type = inttype;
}
if (*tag && xref)
use(p, pos);
return ty;
}
Type typename(void)
{
int callAttributes = 0,dllExport=0;
Type ty = specifier(NULL, NULL, &callAttributes,&dllExport);
if (t == '*' || t == '(' || t == '[') {
ty = dclr(ty, NULL, NULL, 1, &callAttributes);
if (Aflag >= 1 && !hasproto(ty))
warning(StrTab[385]);// <missing prototype\n>
}
return ty;
}
void DumpCalledFunctions(DefinedFunctionsList *rvp)
{
int i = 0;
Symbol s;
Symbol *calledFnTab = rvp->FunctionInfo.CalledFunctions;
while (calledFnTab[i]) {
s = (Symbol)calledFnTab[i];
fprintf(xrefFile,"%s ",s->name);
i++;
}
fprintf(xrefFile,"\n");
}
void DumpDefinedFunctions(void)
{
DefinedFunctionsList *rvp;
rvp = DefinedFunctions;
while (rvp) {
if (rvp->func->scope == GLOBAL && rvp->func->sclass != STATIC) {
fprintf(xrefFile,"e %s %d\n",rvp->func->name,rvp->func->src.y);
DumpCalledFunctions(rvp);
}
rvp = rvp->Next;
}
rvp = DefinedFunctions;
while (rvp) {
if (rvp->func->sclass == STATIC) {
fprintf(xrefFile,"s %s %d\n",rvp->func->name,rvp->func->src.y);
DumpCalledFunctions(rvp);
}
rvp = rvp->Next;
}
}
void CheckStaticUses(void)
{
DefinedFunctionsList *rvp;
rvp = DefinedFunctions;
return;
while (rvp) {
if (rvp->func->sclass == STATIC) {
if (rvp->func->x.callused == 0 && rvp->func->ref == 0.0) {
warning(StrTab[386],rvp->func->name);// <static function %s is never used\n>
}
}
rvp = rvp->Next;
}
}
int GetLastFunctionLabel(void)
{
return cfunc->u.f.label;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -