diff options
Diffstat (limited to 'lcc/src/types.c')
-rw-r--r-- | lcc/src/types.c | 748 |
1 files changed, 0 insertions, 748 deletions
diff --git a/lcc/src/types.c b/lcc/src/types.c deleted file mode 100644 index 4aa3d18..0000000 --- a/lcc/src/types.c +++ /dev/null @@ -1,748 +0,0 @@ -#include "c.h" -#include <float.h> - - -static Field isfield(const char *, Field); -static Type type(int, Type, int, int, void *); - -static struct entry { - struct type type; - struct entry *link; -} *typetable[128]; -static int maxlevel; - -static Symbol pointersym; - -Type chartype; /* char */ -Type doubletype; /* double */ -Type floattype; /* float */ -Type inttype; /* signed int */ -Type longdouble; /* long double */ -Type longtype; /* long */ -Type longlong; /* long long */ -Type shorttype; /* signed short int */ -Type signedchar; /* signed char */ -Type unsignedchar; /* unsigned char */ -Type unsignedlong; /* unsigned long int */ -Type unsignedlonglong; /* unsigned long long int */ -Type unsignedshort; /* unsigned short int */ -Type unsignedtype; /* unsigned int */ -Type funcptype; /* void (*)() */ -Type charptype; /* char* */ -Type voidptype; /* void* */ -Type voidtype; /* basic types: void */ -Type unsignedptr; /* unsigned type to hold void* */ -Type signedptr; /* signed type to hold void* */ -Type widechar; /* unsigned type that represents wchar_t */ - -static Type xxinit(int op, char *name, Metrics m) { - Symbol p = install(string(name), &types, GLOBAL, PERM); - Type ty = type(op, 0, m.size, m.align, p); - - assert(ty->align == 0 || ty->size%ty->align == 0); - p->type = ty; - p->addressed = m.outofline; - switch (ty->op) { - case INT: - p->u.limits.max.i = ones(8*ty->size)>>1; - p->u.limits.min.i = -p->u.limits.max.i - 1; - break; - case UNSIGNED: - p->u.limits.max.u = ones(8*ty->size); - p->u.limits.min.u = 0; - break; - case FLOAT: - if (ty->size == sizeof (float)) - p->u.limits.max.d = FLT_MAX; - else if (ty->size == sizeof (double)) - p->u.limits.max.d = DBL_MAX; - else - p->u.limits.max.d = LDBL_MAX; - p->u.limits.min.d = -p->u.limits.max.d; - break; - default: assert(0); - } - return ty; -} -static Type type(int op, Type ty, int size, int align, void *sym) { - unsigned h = (op^((unsigned long)ty>>3)) -&(NELEMS(typetable)-1); - struct entry *tn; - - if (op != FUNCTION && (op != ARRAY || size > 0)) - for (tn = typetable[h]; tn; tn = tn->link) - if (tn->type.op == op && tn->type.type == ty - && tn->type.size == size && tn->type.align == align - && tn->type.u.sym == sym) - return &tn->type; - NEW0(tn, PERM); - tn->type.op = op; - tn->type.type = ty; - tn->type.size = size; - tn->type.align = align; - tn->type.u.sym = sym; - tn->link = typetable[h]; - typetable[h] = tn; - return &tn->type; -} -void type_init(int argc, char *argv[]) { - static int inited; - int i; - - if (inited) - return; - inited = 1; - if (!IR) - return; - for (i = 1; i < argc; i++) { - int size, align, outofline; - if (strncmp(argv[i], "-unsigned_char=", 15) == 0) - IR->unsigned_char = argv[i][15] - '0'; -#define xx(name) \ - else if (sscanf(argv[i], "-" #name "=%d,%d,%d", &size, &align, &outofline) == 3) { \ - IR->name.size = size; IR->name.align = align; \ - IR->name.outofline = outofline; } - xx(charmetric) - xx(shortmetric) - xx(intmetric) - xx(longmetric) - xx(longlongmetric) - xx(floatmetric) - xx(doublemetric) - xx(longdoublemetric) - xx(ptrmetric) - xx(structmetric) -#undef xx - } -#define xx(v,name,op,metrics) v=xxinit(op,name,IR->metrics) - xx(chartype, "char", IR->unsigned_char ? UNSIGNED : INT,charmetric); - xx(doubletype, "double", FLOAT, doublemetric); - xx(floattype, "float", FLOAT, floatmetric); - xx(inttype, "int", INT, intmetric); - xx(longdouble, "long double", FLOAT, longdoublemetric); - xx(longtype, "long int", INT, longmetric); - xx(longlong, "long long int", INT, longlongmetric); - xx(shorttype, "short", INT, shortmetric); - xx(signedchar, "signed char", INT, charmetric); - xx(unsignedchar, "unsigned char", UNSIGNED,charmetric); - xx(unsignedlong, "unsigned long", UNSIGNED,longmetric); - xx(unsignedshort, "unsigned short", UNSIGNED,shortmetric); - xx(unsignedtype, "unsigned int", UNSIGNED,intmetric); - xx(unsignedlonglong,"unsigned long long",UNSIGNED,longlongmetric); -#undef xx - { - Symbol p; - p = install(string("void"), &types, GLOBAL, PERM); - voidtype = type(VOID, NULL, 0, 0, p); - p->type = voidtype; - } - pointersym = install(string("T*"), &types, GLOBAL, PERM); - pointersym->addressed = IR->ptrmetric.outofline; - pointersym->u.limits.max.p = (void*)ones(8*IR->ptrmetric.size); - pointersym->u.limits.min.p = 0; - voidptype = ptr(voidtype); - funcptype = ptr(func(voidtype, NULL, 1)); - charptype = ptr(chartype); -#define xx(v,t) if (v==NULL && t->size==voidptype->size && t->align==voidptype->align) v=t - xx(unsignedptr,unsignedshort); - xx(unsignedptr,unsignedtype); - xx(unsignedptr,unsignedlong); - xx(unsignedptr,unsignedlonglong); - if (unsignedptr == NULL) - unsignedptr = type(UNSIGNED, NULL, voidptype->size, voidptype->align, voidptype->u.sym); - xx(signedptr,shorttype); - xx(signedptr,inttype); - xx(signedptr,longtype); - xx(signedptr,longlong); - if (signedptr == NULL) - signedptr = type(INT, NULL, voidptype->size, voidptype->align, voidptype->u.sym); -#undef xx - widechar = unsignedshort; - for (i = 0; i < argc; i++) { -#define xx(name,type) \ - if (strcmp(argv[i], "-wchar_t=" #name) == 0) \ - widechar = type; - xx(unsigned_char,unsignedchar) - xx(unsigned_int,unsignedtype) - xx(unsigned_short,unsignedshort) - } -#undef xx -} -void rmtypes(int lev) { - if (maxlevel >= lev) { - int i; - maxlevel = 0; - for (i = 0; i < NELEMS(typetable); i++) { - struct entry *tn, **tq = &typetable[i]; - while ((tn = *tq) != NULL) - if (tn->type.op == FUNCTION) - tq = &tn->link; - else if (tn->type.u.sym && tn->type.u.sym->scope >= lev) - *tq = tn->link; - else { - if (tn->type.u.sym && tn->type.u.sym->scope > maxlevel) - maxlevel = tn->type.u.sym->scope; - tq = &tn->link; - } - - } - } -} -Type ptr(Type ty) { - return type(POINTER, ty, IR->ptrmetric.size, - IR->ptrmetric.align, pointersym); -} -Type deref(Type ty) { - if (isptr(ty)) - ty = ty->type; - else - error("type error: %s\n", "pointer expected"); - return isenum(ty) ? unqual(ty)->type : ty; -} -Type array(Type ty, int n, int a) { - assert(ty); - if (isfunc(ty)) { - error("illegal type `array of %t'\n", ty); - return array(inttype, n, 0); - } - if (isarray(ty) && ty->size == 0) - error("missing array size\n"); - if (ty->size == 0) { - if (unqual(ty) == voidtype) - error("illegal type `array of %t'\n", ty); - else if (Aflag >= 2) - warning("declaring type array of %t' is undefined\n", ty); - - } else if (n > INT_MAX/ty->size) { - error("size of `array of %t' exceeds %d bytes\n", - ty, INT_MAX); - n = 1; - } - return type(ARRAY, ty, n*ty->size, - a ? a : ty->align, NULL); -} -Type atop(Type ty) { - if (isarray(ty)) - return ptr(ty->type); - error("type error: %s\n", "array expected"); - return ptr(ty); -} -Type qual(int op, Type ty) { - if (isarray(ty)) - ty = type(ARRAY, qual(op, ty->type), ty->size, - ty->align, NULL); - else if (isfunc(ty)) - warning("qualified function type ignored\n"); - else if ((isconst(ty) && op == CONST) - || (isvolatile(ty) && op == VOLATILE)) - error("illegal type `%k %t'\n", op, ty); - else { - if (isqual(ty)) { - op += ty->op; - ty = ty->type; - } - ty = type(op, ty, ty->size, ty->align, NULL); - } - return ty; -} -Type func(Type ty, Type *proto, int style) { - if (ty && (isarray(ty) || isfunc(ty))) - error("illegal return type `%t'\n", ty); - ty = type(FUNCTION, ty, 0, 0, NULL); - ty->u.f.proto = proto; - ty->u.f.oldstyle = style; - return ty; -} -Type freturn(Type ty) { - if (isfunc(ty)) - return ty->type; - error("type error: %s\n", "function expected"); - return inttype; -} -int variadic(Type ty) { - if (isfunc(ty) && ty->u.f.proto) { - int i; - for (i = 0; ty->u.f.proto[i]; i++) - ; - return i > 1 && ty->u.f.proto[i-1] == voidtype; - } - return 0; -} -Type newstruct(int op, char *tag) { - Symbol p; - - assert(tag); - if (*tag == 0) - tag = stringd(genlabel(1)); - else - if ((p = lookup(tag, types)) != NULL && (p->scope == level - || (p->scope == PARAM && level == PARAM+1))) { - if (p->type->op == op && !p->defined) - return p->type; - error("redefinition of `%s' previously defined at %w\n", - p->name, &p->src); - } - p = install(tag, &types, level, PERM); - p->type = type(op, NULL, 0, 0, p); - if (p->scope > maxlevel) - maxlevel = p->scope; - p->src = src; - return p->type; -} -Field newfield(char *name, Type ty, Type fty) { - Field p, *q = &ty->u.sym->u.s.flist; - - if (name == NULL) - name = stringd(genlabel(1)); - for (p = *q; p; q = &p->link, p = *q) - if (p->name == name) - error("duplicate field name `%s' in `%t'\n", - name, ty); - NEW0(p, PERM); - *q = p; - p->name = name; - p->type = fty; - if (xref) { /* omit */ - if (ty->u.sym->u.s.ftab == NULL) /* omit */ - ty->u.sym->u.s.ftab = table(NULL, level); /* omit */ - install(name, &ty->u.sym->u.s.ftab, 0, PERM)->src = src;/* omit */ - } /* omit */ - return p; -} -int eqtype(Type ty1, Type ty2, int ret) { - if (ty1 == ty2) - return 1; - if (ty1->op != ty2->op) - return 0; - switch (ty1->op) { - case ENUM: case UNION: case STRUCT: - case UNSIGNED: case INT: case FLOAT: - return 0; - case POINTER: return eqtype(ty1->type, ty2->type, 1); - case VOLATILE: case CONST+VOLATILE: - case CONST: return eqtype(ty1->type, ty2->type, 1); - case ARRAY: if (eqtype(ty1->type, ty2->type, 1)) { - if (ty1->size == ty2->size) - return 1; - if (ty1->size == 0 || ty2->size == 0) - return ret; - } - return 0; - case FUNCTION: if (eqtype(ty1->type, ty2->type, 1)) { - Type *p1 = ty1->u.f.proto, *p2 = ty2->u.f.proto; - if (p1 == p2) - return 1; - if (p1 && p2) { - for ( ; *p1 && *p2; p1++, p2++) - if (eqtype(unqual(*p1), unqual(*p2), 1) == 0) - return 0; - if (*p1 == NULL && *p2 == NULL) - return 1; - } else { - if (variadic(p1 ? ty1 : ty2)) - return 0; - if (p1 == NULL) - p1 = p2; - for ( ; *p1; p1++) { - Type ty = unqual(*p1); - if (promote(ty) != (isenum(ty) ? ty->type : ty)) - return 0; - } - return 1; - } - } - return 0; - } - assert(0); return 0; -} -Type promote(Type ty) { - ty = unqual(ty); - switch (ty->op) { - case ENUM: - return inttype; - case INT: - if (ty->size < inttype->size) - return inttype; - break; - case UNSIGNED: - if (ty->size < inttype->size) - return inttype; - if (ty->size < unsignedtype->size) - return unsignedtype; - break; - case FLOAT: - if (ty->size < doubletype->size) - return doubletype; - } - return ty; -} -Type signedint(Type ty) { - if (ty->op == INT) - return ty; - assert(ty->op == UNSIGNED); -#define xx(t) if (ty->size == t->size) return t - xx(inttype); - xx(longtype); - xx(longlong); -#undef xx - assert(0); return NULL; -} -Type compose(Type ty1, Type ty2) { - if (ty1 == ty2) - return ty1; - assert(ty1->op == ty2->op); - switch (ty1->op) { - case POINTER: - return ptr(compose(ty1->type, ty2->type)); - case CONST+VOLATILE: - return qual(CONST, qual(VOLATILE, - compose(ty1->type, ty2->type))); - case CONST: case VOLATILE: - return qual(ty1->op, compose(ty1->type, ty2->type)); - case ARRAY: { Type ty = compose(ty1->type, ty2->type); - if (ty1->size && ((ty1->type->size && ty2->size == 0) || ty1->size == ty2->size)) - return array(ty, ty1->size/ty1->type->size, ty1->align); - if (ty2->size && ty2->type->size && ty1->size == 0) - return array(ty, ty2->size/ty2->type->size, ty2->align); - return array(ty, 0, 0); } - case FUNCTION: { Type *p1 = ty1->u.f.proto, *p2 = ty2->u.f.proto; - Type ty = compose(ty1->type, ty2->type); - List tlist = NULL; - if (p1 == NULL && p2 == NULL) - return func(ty, NULL, 1); - if (p1 && p2 == NULL) - return func(ty, p1, ty1->u.f.oldstyle); - if (p2 && p1 == NULL) - return func(ty, p2, ty2->u.f.oldstyle); - for ( ; *p1 && *p2; p1++, p2++) { - Type ty = compose(unqual(*p1), unqual(*p2)); - if (isconst(*p1) || isconst(*p2)) - ty = qual(CONST, ty); - if (isvolatile(*p1) || isvolatile(*p2)) - ty = qual(VOLATILE, ty); - tlist = append(ty, tlist); - } - assert(*p1 == NULL && *p2 == NULL); - return func(ty, ltov(&tlist, PERM), 0); } - } - assert(0); return NULL; -} -int ttob(Type ty) { - switch (ty->op) { - case CONST: case VOLATILE: case CONST+VOLATILE: - return ttob(ty->type); - case VOID: case INT: case UNSIGNED: case FLOAT: - return ty->op + sizeop(ty->size); - case POINTER: - return POINTER + sizeop(voidptype->size); - case FUNCTION: - return POINTER + sizeop(funcptype->size); - case ARRAY: case STRUCT: case UNION: - return STRUCT; - case ENUM: - return INT + sizeop(inttype->size); - } - assert(0); return INT; -} -Type btot(int op, int size) { -#define xx(ty) if (size == (ty)->size) return ty; - switch (optype(op)) { - case F: - xx(floattype); - xx(doubletype); - xx(longdouble); - assert(0); return 0; - case I: - if (chartype->op == INT) - xx(chartype); - xx(signedchar); - xx(shorttype); - xx(inttype); - xx(longtype); - xx(longlong); - assert(0); return 0; - case U: - if (chartype->op == UNSIGNED) - xx(chartype); - xx(unsignedchar); - xx(unsignedshort); - xx(unsignedtype); - xx(unsignedlong); - xx(unsignedlonglong); - assert(0); return 0; - case P: - xx(voidptype); - xx(funcptype); - assert(0); return 0; - } -#undef xx - assert(0); return 0; -} -int hasproto(Type ty) { - if (ty == 0) - return 1; - switch (ty->op) { - case CONST: case VOLATILE: case CONST+VOLATILE: case POINTER: - case ARRAY: - return hasproto(ty->type); - case FUNCTION: - return hasproto(ty->type) && ty->u.f.proto; - case STRUCT: case UNION: - case VOID: case FLOAT: case ENUM: case INT: case UNSIGNED: - return 1; - } - assert(0); return 0; -} -/* fieldlist - construct a flat list of fields in type ty */ -Field fieldlist(Type ty) { - return ty->u.sym->u.s.flist; -} - -/* fieldref - find field name of type ty, return entry */ -Field fieldref(const char *name, Type ty) { - Field p = isfield(name, unqual(ty)->u.sym->u.s.flist); - - if (p && xref) { - Symbol q; - assert(unqual(ty)->u.sym->u.s.ftab); - q = lookup(name, unqual(ty)->u.sym->u.s.ftab); - assert(q); - use(q, src); - } - return p; -} - -/* ftype - return a function type for rty function (ty,...)' */ -Type ftype(Type rty, Type ty) { - List list = append(ty, NULL); - - list = append(voidtype, list); - return func(rty, ltov(&list, PERM), 0); -} - -/* isfield - if name is a field in flist, return pointer to the field structure */ -static Field isfield(const char *name, Field flist) { - for ( ; flist; flist = flist->link) - if (flist->name == name) - break; - return flist; -} - -/* outtype - output type ty */ -void outtype(Type ty, FILE *f) { - switch (ty->op) { - case CONST+VOLATILE: case CONST: case VOLATILE: - fprint(f, "%k %t", ty->op, ty->type); - break; - case STRUCT: case UNION: case ENUM: - assert(ty->u.sym); - if (ty->size == 0) - fprint(f, "incomplete "); - assert(ty->u.sym->name); - if (*ty->u.sym->name >= '1' && *ty->u.sym->name <= '9') { - Symbol p = findtype(ty); - if (p == 0) - fprint(f, "%k defined at %w", ty->op, &ty->u.sym->src); - else - fprint(f, p->name); - } else { - fprint(f, "%k %s", ty->op, ty->u.sym->name); - if (ty->size == 0) - fprint(f, " defined at %w", &ty->u.sym->src); - } - break; - case VOID: case FLOAT: case INT: case UNSIGNED: - fprint(f, ty->u.sym->name); - break; - case POINTER: - fprint(f, "pointer to %t", ty->type); - break; - case FUNCTION: - fprint(f, "%t function", ty->type); - if (ty->u.f.proto && ty->u.f.proto[0]) { - int i; - fprint(f, "(%t", ty->u.f.proto[0]); - for (i = 1; ty->u.f.proto[i]; i++) - if (ty->u.f.proto[i] == voidtype) - fprint(f, ",..."); - else - fprint(f, ",%t", ty->u.f.proto[i]); - fprint(f, ")"); - } else if (ty->u.f.proto && ty->u.f.proto[0] == 0) - fprint(f, "(void)"); - - break; - case ARRAY: - if (ty->size > 0 && ty->type && ty->type->size > 0) { - fprint(f, "array %d", ty->size/ty->type->size); - while (ty->type && isarray(ty->type) && ty->type->type->size > 0) { - ty = ty->type; - fprint(f, ",%d", ty->size/ty->type->size); - } - } else - fprint(f, "incomplete array"); - if (ty->type) - fprint(f, " of %t", ty->type); - break; - default: assert(0); - } -} - -/* printdecl - output a C declaration for symbol p of type ty */ -void printdecl(Symbol p, Type ty) { - switch (p->sclass) { - case AUTO: - fprint(stderr, "%s;\n", typestring(ty, p->name)); - break; - case STATIC: case EXTERN: - fprint(stderr, "%k %s;\n", p->sclass, typestring(ty, p->name)); - break; - case TYPEDEF: case ENUM: - break; - default: assert(0); - } -} - -/* printproto - output a prototype declaration for function p */ -void printproto(Symbol p, Symbol callee[]) { - if (p->type->u.f.proto) - printdecl(p, p->type); - else { - int i; - List list = 0; - if (callee[0] == 0) - list = append(voidtype, list); - else - for (i = 0; callee[i]; i++) - list = append(callee[i]->type, list); - printdecl(p, func(freturn(p->type), ltov(&list, PERM), 0)); - } -} - -/* prtype - print details of type ty on f with given indent */ -static void prtype(Type ty, FILE *f, int indent, unsigned mark) { - switch (ty->op) { - default: - fprint(f, "(%d %d %d [%p])", ty->op, ty->size, ty->align, ty->u.sym); - break; - case FLOAT: case INT: case UNSIGNED: case VOID: - fprint(f, "(%k %d %d [\"%s\"])", ty->op, ty->size, ty->align, ty->u.sym->name); - break; - case CONST+VOLATILE: case CONST: case VOLATILE: case POINTER: case ARRAY: - fprint(f, "(%k %d %d ", ty->op, ty->size, ty->align); - prtype(ty->type, f, indent+1, mark); - fprint(f, ")"); - break; - case STRUCT: case UNION: - fprint(f, "(%k %d %d [\"%s\"]", ty->op, ty->size, ty->align, ty->u.sym->name); - if (ty->x.marked != mark) { - Field p; - ty->x.marked = mark; - for (p = ty->u.sym->u.s.flist; p; p = p->link) { - fprint(f, "\n%I", indent+1); - prtype(p->type, f, indent+1, mark); - fprint(f, " %s@%d", p->name, p->offset); - if (p->lsb) - fprint(f, ":%d..%d", - fieldsize(p) + fieldright(p), fieldright(p)); - } - fprint(f, "\n%I", indent); - } - fprint(f, ")"); - break; - case ENUM: - fprint(f, "(%k %d %d [\"%s\"]", ty->op, ty->size, ty->align, ty->u.sym->name); - if (ty->x.marked != mark) { - int i; - Symbol *p = ty->u.sym->u.idlist; - ty->x.marked = mark; - for (i = 0; p[i] != NULL; i++) - fprint(f, "%I%s=%d\n", indent+1, p[i]->name, p[i]->u.value); - } - fprint(f, ")"); - break; - case FUNCTION: - fprint(f, "(%k %d %d ", ty->op, ty->size, ty->align); - prtype(ty->type, f, indent+1, mark); - if (ty->u.f.proto) { - int i; - fprint(f, "\n%I{", indent+1); - for (i = 0; ty->u.f.proto[i]; i++) { - if (i > 0) - fprint(f, "%I", indent+2); - prtype(ty->u.f.proto[i], f, indent+2, mark); - fprint(f, "\n"); - } - fprint(f, "%I}", indent+1); - } - fprint(f, ")"); - break; - } -} - -/* printtype - print details of type ty on fd */ -void printtype(Type ty, int fd) { - static unsigned mark; - prtype(ty, fd == 1 ? stdout : stderr, 0, ++mark); - fprint(fd == 1 ? stdout : stderr, "\n"); -} - -/* typestring - return ty as C declaration for str, which may be "" */ -char *typestring(Type ty, char *str) { - for ( ; ty; ty = ty->type) { - Symbol p; - switch (ty->op) { - case CONST+VOLATILE: case CONST: case VOLATILE: - if (isptr(ty->type)) - str = stringf("%k %s", ty->op, str); - else - return stringf("%k %s", ty->op, typestring(ty->type, str)); - break; - case STRUCT: case UNION: case ENUM: - assert(ty->u.sym); - if ((p = findtype(ty)) != NULL) - return *str ? stringf("%s %s", p->name, str) : p->name; - if (*ty->u.sym->name >= '1' && *ty->u.sym->name <= '9') - warning("unnamed %k in prototype\n", ty->op); - if (*str) - return stringf("%k %s %s", ty->op, ty->u.sym->name, str); - else - return stringf("%k %s", ty->op, ty->u.sym->name); - case VOID: case FLOAT: case INT: case UNSIGNED: - return *str ? stringf("%s %s", ty->u.sym->name, str) : ty->u.sym->name; - case POINTER: - if (!ischar(ty->type) && (p = findtype(ty)) != NULL) - return *str ? stringf("%s %s", p->name, str) : p->name; - str = stringf(isarray(ty->type) || isfunc(ty->type) ? "(*%s)" : "*%s", str); - break; - case FUNCTION: - if ((p = findtype(ty)) != NULL) - return *str ? stringf("%s %s", p->name, str) : p->name; - if (ty->u.f.proto == 0) - str = stringf("%s()", str); - else if (ty->u.f.proto[0]) { - int i; - str = stringf("%s(%s", str, typestring(ty->u.f.proto[0], "")); - for (i = 1; ty->u.f.proto[i]; i++) - if (ty->u.f.proto[i] == voidtype) - str = stringf("%s, ...", str); - else - str = stringf("%s, %s", str, typestring(ty->u.f.proto[i], "")); - str = stringf("%s)", str); - } else - str = stringf("%s(void)", str); - break; - case ARRAY: - if ((p = findtype(ty)) != NULL) - return *str ? stringf("%s %s", p->name, str) : p->name; - if (ty->type && ty->type->size > 0) - str = stringf("%s[%d]", str, ty->size/ty->type->size); - else - str = stringf("%s[]", str); - break; - default: assert(0); - } - } - assert(0); return 0; -} - |