📄 decl.c
字号:
t = '*';
goto restart;
case STDCALL:
t = gettok();
*attributes = STDCALLATTRIBUTE;
goto restart;
case '(':
t = gettok();
if (t == STDCALL) {
t = gettok();
*attributes = STDCALLATTRIBUTE;
}
else if (t == DLLIMPORT) {
t = '*';
*attributes = DLLIMPORTATTRIBUTE;
}
if (abstract
&& (t == REGISTER || istypename(t, tsym) || t == ')')) {
Symbol *args;
ty = tnode(FUNCTION, ty);
enterscope();
if (level > PARAM)
enterscope();
args = parameters(ty);
exitparams(args);
}
else {
ty = dclr1(id, params, abstract, attributes);
expect(')');
if (abstract && ty == NULL
&& (id == NULL || *id == NULL))
return tnode(FUNCTION, NULL);
} break;
case '[':
break;
default:
return ty;
}
while (t == '(' || t == '[')
switch (t) {
case '(':
t = gettok(); {
Symbol *args;
ty = tnode(FUNCTION, ty);
enterscope();
if (level > PARAM)
enterscope();
args = parameters(ty);
if (params && *params == NULL)
*params = args;
else
exitparams(args);
}
break;
case '[':
t = gettok(); {
int n = 0;
if (kind[t] == ID) {
n = intexpr(']', 1);
if (n <= 0) {
error(StrTab[323], n);// <`%d' is an illegal array size\n>
n = 1;
}
}
else
expect(']');
ty = tnode(ARRAY, ty);
ty->size = n;
} break;
default:
assert(0);
}
return ty;
}
static Symbol *parameters(Type fty)
{
List list = NULL;
Symbol *params;
int callAttributes, dummy;
Type tmpType;
if (kind[t] == STATIC || istypename(t, tsym)) {
int n = 0;
Type ty1 = NULL;
for (;;) {
Type ty;
int sclass = 0;
char *id = NULL;
if (ty1 && t == ELLIPSIS) {
static struct symbol sentinel;
if (sentinel.type == NULL) {
sentinel.type = voidtype;
sentinel.defined = 1;
}
if (ty1 == voidtype)
error(StrTab[324]);// <illegal formal parameter types\n>
list = append(&sentinel, list);
t = gettok();
break;
}
if (!istypename(t, tsym) && t != REGISTER)
error(StrTab[325]);// <missing parameter type\n>
n++;
tmpType = specifier(&sclass, NULL, &dummy,&dummy);
ty = dclr(tmpType, &id, NULL, 1, &callAttributes);
if (ty == voidtype && (ty1 || id)
|| ty1 == voidtype)
error(StrTab[326]);// <illegal formal parameter types\n>
if (id == NULL)
id = stringd(n);
if (ty != voidtype)
list = append(dclparam(sclass, id, ty, &src,callAttributes), list);
if (Aflag >= 1 && !hasproto(ty))
warning(StrTab[327]);// <missing prototype\n>
if (ty1 == NULL)
ty1 = ty;
if (t != ',')
break;
t = gettok();
}
fty->u.f.proto = newarray(length(list) + 1,
sizeof(Type *), PERM);
params = ltov(&list, FUNC);
for (n = 0; params[n]; n++)
fty->u.f.proto[n] = params[n]->type;
fty->u.f.proto[n] = NULL;
fty->u.f.oldstyle = 0;
}
else {
if (t == ID)
for (;;) {
Symbol p;
if (t != ID) {
error(StrTab[328]);// <expecting an identifier\n>
break;
}
p = dclparam(0, token, inttype, &src,callAttributes);
p->defined = 0;
list = append(p, list);
t = gettok();
if (t != ',')
break;
t = gettok();
}
params = ltov(&list, FUNC);
fty->u.f.proto = NULL;
fty->u.f.oldstyle = 1;
}
if (t != ')') {
static char stop[] = {CHAR, STATIC, IF, ')', 0};
expect(')');
skipto('{', stop);
}
if (t == ')')
t = gettok();
return params;
}
static void exitparams(Symbol params[])
{
assert(params);
if (params[0] && !params[0]->defined)
error(StrTab[329]);// <extraneous old-style parameter list\n>
if (level > PARAM)
exitscope();
exitscope();
}
static Symbol dclparam(int sclass, char *id, Type ty, Coordinate * pos,int callAttributes)
{
Symbol p;
if (isfunc(ty))
ty = ptr(ty);
else if (isarray(ty))
ty = atop(ty);
if (sclass == 0)
sclass = AUTO;
else if (sclass != REGISTER) {
error(StrTab[330],// <invalid storage class `%k' for `%t%s\n>
sclass, ty, stringf(id ? " %s'" : StrTab[331], id));// <' parameter>
sclass = AUTO;
}
else if (isvolatile(ty) || isstruct(ty)) {
warning(StrTab[332],// <register declaration ignored for `%t%s\n>
ty, stringf(id ? " %s'" : StrTab[333], id));// <' parameter>
sclass = AUTO;
}
p = lookup(id, identifiers);
if (p && p->scope == level)
error(StrTab[334], id, &p->src);// <duplicate declaration for `%s' previously declared at %w\n>
else
p = install(id, &identifiers, level, FUNC);
p->sclass = sclass;
p->src = *pos;
p->type = ty;
p->defined = 1;
if (t == '=') {
error(StrTab[335], id);// <illegal initialization for parameter `%s'\n>
t = gettok();
(void) expr1(0);
}
return p;
}
static Type structdcl(int op)
{
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 stop[] = {IF, ',', 0};
ty = newstruct(op, tag);
ty->u.sym->src = pos;
ty->u.sym->defined = 1;
t = gettok();
if (istypename(t, tsym))
fields(ty);
else
error(StrTab[336], op);// <invalid %k field declarations\n>
test('}', stop);
}
else if (*tag && (p = lookup(tag, types)) != NULL
&& p->type->op == op) {
ty = p->type;
if (t == ';' && p->scope < level)
ty = newstruct(op, tag);
}
else {
if (*tag == 0)
error(StrTab[337], op);// <missing %k tag\n>
ty = newstruct(op, tag);
}
if (*tag && xref)
use(ty->u.sym, pos);
return ty;
}
static void fields(Type ty)
{
{
int n = 0;
int callAttributes;
int dummy;
while (istypename(t, tsym)) {
static char stop[] = {IF, CHAR, '}', 0};
Type ty1 = specifier(NULL, NULL, &callAttributes,&dummy);
for (;;) {
Field p;
char *id = NULL;
Type fty = dclr(ty1, &id, NULL, 0, &dummy);
p = newfield(id, ty, fty);
if (Aflag >= 1 && !hasproto(p->type)) {
if (id)
warning(StrTab[338], id);// <missing prototype for %s\n>
else
warning(StrTab[339]);// <missing prototype\n>
}
if (t == ':') {
if (unqual(p->type) != inttype
&& unqual(p->type) != unsignedtype) {
if (unqual(p->type) != unsignedshort
&& unqual(p->type) != unsignedlong)
error(StrTab[340],// <`%t' is an illegal bit-field type\n>
p->type);
else if (Aflag > 1)
warning(StrTab[341], p->type);// <promoting %t to int\n>
p->type = inttype;
}
t = gettok();
p->bitsize = (short)intexpr(0, 0);
if (p->bitsize > 8 * inttype->size || p->bitsize < 0) {
error(StrTab[342],// <`%d' is an illegal bit-field size\n>
p->bitsize);
p->bitsize = (short)(8 * inttype->size);
}
else if (p->bitsize == 0 && id) {
warning(StrTab[343], p->type, id);// <extraneous 0-width bit field `%t %s' ignored\n>
p->name = stringd(genlabel(1));
}
p->lsb = 1;
}
else if (id == NULL && Xflag && isstruct(p->type)) {
if (Aflag >= 2)
warning(StrTab[344], ty);// <non-ANSI unnamed substructure in `%t'\n>
if (p->type->size == 0)
error(StrTab[345], p->type);// <undefined size for field `%t'\n>
p->name = NULL;
break;
}
else {
if (id == 0 && isstruct(p->type)) {
if (Aflag >= 2)
warning(StrTab[346]);// <non-ANSI unnamed substructure\n>
if (p->type->size == 0)
error(StrTab[347],p->type);// <undefined size for field '%t'\n>
p->name = 0;
break;
}
else if (isfunc(p->type))
error(StrTab[348], p->type);// <`%t' is an illegal field type\n>
else if (p->type->size == 0) {
warning(StrTab[349], p->type, id);// <undefined size for field `%t %s'\n>
p->type->size = p->type->align;
}
}
if (isconst(p->type))
ty->u.sym->u.s.cfields = 1;
if (isvolatile(p->type))
ty->u.sym->u.s.vfields = 1;
if (dummy) {
if (fty->op == POINTER) {
if (fty->type->op != FUNCTION)
error(StrTab[350]);// <incorrect _stdcall usage>
else
fty->type->u.f.isStdCall = 1;
}
else
fty->u.f.isStdCall = 1;
}
n++;
if (Aflag >= 2 && n == 128)
warning(StrTab[351], ty);// <more than 127 fields in `%t'\n>
if (t != ',')
break;
t = gettok();
}
test(';', stop);
}
}
{
int bits = 0, off = 0, overflow = 0;
Field p, *q = &ty->u.sym->u.s.flist;
ty->align = IR->structmetric.align;
for (p = *q; p; p = p->link) {
int a = p->type->align ? p->type->align : 1;
if (a > DefaultAlignment) a = DefaultAlignment;
if (p->lsb)
a = unsignedtype->align;
if (ty->op == UNION)
off = bits = 0;
else if (p->bitsize == 0 || bits == 0
|| bits - 1 + p->bitsize > 8 * unsignedtype->size) {
off = add(off, bits2bytes(bits - 1));
bits = 0;
chkoverflow(off, a - 1);
off = roundup(off, a);
}
if (a > ty->align)
ty->align = a;
p->offset = off;
if (p->lsb) {
if (bits == 0)
bits = 1;
if (IR->little_endian)
p->lsb = (short)bits;
else
p->lsb = (short)(8 * unsignedtype->size - bits + 1 - p->bitsize + 1);
bits += p->bitsize;
}
else
off = add(off, p->type->size);
if (off + bits2bytes(bits - 1) > ty->size)
ty->size = off + bits2bytes(bits - 1);
if (p->name == NULL
|| !('1' <= *p->name && *p->name <= '9')) {
*q = p;
q = &p->link;
}
}
*q = NULL;
chkoverflow(ty->size, ty->align - 1);
ty->size = roundup(ty->size, ty->align);
if (overflow) {
error(StrTab[352], ty, INT_MAX);// <size of `%t' exceeds %d bytes\n>
ty->size = INT_MAX & (~(ty->align - 1));
}
if (Xflag)
checkfields(ty);
}
}
static void funcdefn(int sclass, char *id, Type ty, Symbol params[], Coordinate pt, int callAttributes)
{
int i, n;
Symbol *callee, *caller, p;
Type rty = freturn(ty);
Code cp;
if (isstruct(rty) && rty->size == 0)
error(StrTab[353], rty);// <illegal use of incomplete type `%t'\n>
memset(&FunctionInfo,0,sizeof(FunctionInfo));
StatementCount = 1;
hasAllocA = 0;
for (n = 0; params[n]; n++);
if (n > 0 && params[n - 1]->name == NULL)
params[--n] = NULL;
if (Aflag >= 2 && n > 31)
warning(StrTab[354], id);// <more than 31 parameters in function `%s'\n>
for (i=0; i<n;i++) {
params[i]->firstuse = StatementCount;
params[i]->x.isArgument = 1;
}
StatementCount++;
FunctionNodes = 0;
if (ty->u.f.oldstyle) {
if (Aflag >= 1)
warning(StrTab[429],id); // <old style function definition for %s\n>
caller = params;
callee = newarray(n + 1, sizeof *callee, FUNC);
memcpy(callee, caller, (n + 1) * sizeof *callee);
enterscope();
assert(level == PARAM);
while (kind[t] == STATIC || istypename(t, tsym))
decl(dclparam);
foreach(identifiers, PARAM, oldparam, callee);
for (i = 0; (p = callee[i]) != NULL; i++) {
if (!p->defined)
callee[i] = dclparam(0, p->name, inttype, &p->src,0);
*caller[i] = *p;
caller[i]->sclass = AUTO;
if (unqual(p->type) == floattype)
caller[i]->type = doubletype;
else
caller[i]->type = promote(p->type);
}
p = lookup(id, identifiers);
if (p && p->scope == GLOBAL && isfunc(p->type)
&& p->type->u.f.proto) {
Type *proto = p->type->u.f.proto;
for (i = 0; caller[i] && proto[i]; i++) {
Type ty = unqual(proto[i]);
if (eqtype(isenum(ty) ? ty->type : ty,
unqual(caller[i]->type), 1) == 0)
break;
}
if (proto[i] || caller[i])
error(StrTab[355], id);// <conflicting argument declarations for function `%s'\n>
}
else {
Type *proto = newarray(n + 1, sizeof *proto, PERM);
if (Aflag >= 1)
warning(StrTab[356], id);// <missing prototype for `%s'\n>
for (i = 0; i < n; i++)
proto[i] = caller[i]->type;
proto[i] = NULL;
ty = func(rty, proto, 1);
}
for (i=0; i < n; i++) {
callee[i]->x.isArgument = 1;
}
}
else {
callee = params;
caller = newarray(n + 1, sizeof *caller, FUNC);
for (i = 0; (p = callee[i]) != NULL && p->name; i++) {
NEW(caller[i], FUNC);
*caller[i] = *p;
caller[i]->type = promote(p->type);
caller[i]->sclass = AUTO;
if ('1' <= *p->name && *p->name <= '9')
error(StrTab[357], i + 1, id);// <missing name for parameter %d to function `%s'\n>
}
caller[i] = NULL;
}
for (i = 0; (p = callee[i]) != NULL; i++)
if (p->type->size == 0) {
error(StrTab[358],// <undefined size for parameter `%t %s'\n>
p->type, p->name);
caller[i]->type = p->type = inttype;
}
if (Aflag >= 1 && sclass != STATIC && strcmp(id, "main") == 0) {
if (ty->u.f.oldstyle)
warning(StrTab[430], rty, id); // <`%t %s()' is a non-ANSI definition\n>
else if (!(rty == inttype
&& (n == 0 && callee[0] == NULL
|| n == 2 && callee[0]->type == inttype
&& isptr(callee[1]->type) && callee[1]->type->type == ptr(chartype)
&& !variadic(ty))))
warning(StrTab[431], typestring(ty, id)); // <`%s' is a non-ANSI definition\n>
}
p = lookup(id, identifiers);
if (p && isfunc(p->type) && p->defined)
error(StrTab[359],// <redefinition of `%s' previously defined at %w\n>
p->name, &p->src);
cfunc = dclglobal(sclass, id, ty, &pt, callAttributes);
cfunc->u.f.label = genlabel(1);
cfunc->u.f.callee = callee;
cfunc->u.f.pt = src;
cfunc->defined = 1;
cfunc->Flags = (unsigned char)callAttributes;
if (xref)
use(cfunc, cfunc->src);
if (Pflag)
printproto(cfunc, cfunc->u.f.callee);
if (ncalled >= 0)
ncalled = findfunc(cfunc->name, pt.file);
labels = table(NULL, LABELS);
stmtlabs = table(NULL, LABELS);
refinc = (float) 1.0;
regcount = 0;
codelist = &codehead;
codelist->next = NULL;
definept(NULL,POINT_STARTFN);
if (!IR->wants_callb && isstruct(rty))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -