📄 decl.c
字号:
if (smin >= min_sshort && smax <= max_sshort) return tp_sshort; else return tp_integer; } } else return tp_integer; } case TK_CHAR: if (type == tp_schar && (signedchars != 1 && !hassignedchar)) { return tp_sshort; } return type; default: return type; } type = type->basetype; }}Type *findbasetype(type, flags)Type *type;int flags;{ if (debug>1) { fprintf(outf, "findbasetype("); dumptypename(type, 1); fprintf(outf, ",%d) = ", flags); type = findbasetype_(type, flags); dumptypename(type, 1); fprintf(outf, "\n"); return type; } return findbasetype_(type, flags);}Expr *arraysize(tp, incskipped)Type *tp;int incskipped;{ Expr *ex, *minv, *maxv; int denom; ord_range_expr(tp->indextype, &minv, &maxv); if (maxv->kind == EK_VAR && maxv->val.i == (long)mp_maxint && !exprdependsvar(minv, mp_maxint)) { return NULL; } else { ex = makeexpr_plus(makeexpr_minus(copyexpr(maxv), copyexpr(minv)), makeexpr_long(1)); if (tp->smin && !incskipped) { ex = makeexpr_minus(ex, copyexpr(tp->smin)); } if (tp->smax) { denom = (tp->basetype == tp_sshort) ? 16 : 8; denom >>= tp->escale; ex = makeexpr_div(makeexpr_plus(ex, makeexpr_long(denom-1)), makeexpr_long(denom)); } return ex; }}Type *promote_type(tp)Type *tp;{ Type *tp2; if (tp->kind == TK_ENUM) { if (promote_enums == 0 || (promote_enums < 0 && (useenum))) return tp; } if (tp->kind == TK_ENUM || tp->kind == TK_SUBR || tp->kind == TK_INTEGER || tp->kind == TK_CHAR || tp->kind == TK_BOOLEAN) { tp2 = findbasetype(tp, ODECL_NOPRES); if (tp2 == tp_ushort && sizeof_int == 16) return tp_uint; else if (tp2 == tp_sbyte || tp2 == tp_ubyte || tp2 == tp_abyte || tp2 == tp_char || tp2 == tp_sshort || tp2 == tp_ushort || tp2 == tp_boolean || tp2->kind == TK_ENUM) { return tp_int; } } if (tp == tp_real) return tp_longreal; return tp;}Type *promote_type_bin(t1, t2)Type *t1, *t2;{ t1 = promote_type(t1); t2 = promote_type(t2); if (t1 == tp_longreal || t2 == tp_longreal) return tp_longreal; if (t1 == tp_unsigned || t2 == tp_unsigned) return tp_unsigned; if (t1 == tp_integer || t2 == tp_integer) { if ((t1 == tp_uint || t2 == tp_uint) && sizeof_int > 0 && sizeof_int < (sizeof_long > 0 ? sizeof_long : 32)) return tp_uint; return tp_integer; } if (t1 == tp_uint || t2 == tp_uint) return tp_uint; return t1;}#if 0void predeclare_varstruct(mp)Meaning *mp;{ if (mp->ctx && mp->ctx->kind == MK_FUNCTION && mp->ctx->varstructflag && (usePPMacros != 0 || prototypes != 0) && !strlist_find(varstructdecllist, mp->ctx->name)) { output("struct "); output(format_s(name_LOC, mp->ctx->name)); output(" ;\n"); strlist_insert(&varstructdecllist, mp->ctx->name); }}#endifStatic void declare_args(type, isheader, isforward)Type *type;int isheader, isforward;{ Meaning *mp = type->fbase; Type *tp; int firstflag = 0; int usePP, dopromote, proto, showtypes, shownames; int staticlink; char *name;#if 1 /* This seems to work better! */ isforward = !isheader;#endif usePP = (isforward && usePPMacros != 0); dopromote = (promoteargs == 1 || (promoteargs < 0 && (usePP || !fullprototyping))); if (ansiC == 1 && blockkind != TOK_EXPORT) usePP = 0; if (usePP) proto = (prototypes) ? prototypes : 1; else proto = (isforward || fullprototyping) ? prototypes : 0; showtypes = (proto > 0); shownames = (proto == 1 || isheader); staticlink = (type->issigned || (type->meaning && type->meaning->ctx->kind == MK_FUNCTION && type->meaning->ctx->varstructflag)); if (mp || staticlink) { if (usePP) output(" PP("); else if (spacefuncs) output(" "); output("("); if (showtypes || shownames) { firstflag = 0; while (mp) { if (firstflag++) if (spacecommas) output(",\002 "); else output(",\002"); name = (mp->othername && isheader) ? mp->othername : mp->name; tp = (mp->othername) ? mp->rectype : mp->type; if (!showtypes) { output(name); } else { output(storageclassname(varstorageclass(mp))); if (!shownames || (isforward && *name == '_')) { out_type(tp, (mp->isref) ? ODECL_REF : 0); } else { if (dopromote) tp = promote_type(tp); if (mp->dtype) output(mp->dtype->name); else outbasetype(tp, ODECL_CHARSTAR|ODECL_FREEARRAY); outdeclarator(tp, name, ODECL_CHARSTAR | ODECL_FREEARRAY | ODECL_SPACE | ((mp->isref) ? ODECL_REF : 0)); } } if (isheader) mp->wasdeclared = showtypes; if (mp->type == tp_strptr && mp->anyvarflag) { /* VAR STRING parameter */ if (spacecommas) output(",\002 "); else output(",\002"); if (showtypes) { if (useAnyptrMacros == 1 || useconsts == 2) output("Const "); else if (ansiC > 0) output("const "); output("int"); } if (shownames) { if (showtypes) output(" "); output(format_s(name_STRMAX, mp->name)); } } mp = mp->xnext; } if (staticlink) { /* sub-procedure with static link */ if (firstflag++) if (spacecommas) output(",\002 "); else output(",\002"); if (type->issigned) { if (showtypes) if (tp_special_anyptr) output("Anyptr "); else if (voidstar) output("void *"); else output("char *"); if (shownames) output("_link"); } else { mp = type->meaning->ctx; if (showtypes) { output("struct "); output(format_s(name_LOC, mp->name)); output(" *"); } if (shownames) { output(format_s(name_LINK, mp->name)); } } } } output(")"); if (usePP) output(")"); } else { if (usePP) output(" PV()"); else { if (spacefuncs) output(" "); if (void_args) output("(void)"); else output("()"); } }}void outdeclarator(type, name, flags)Type *type;char *name;int flags;{ int i, depth, anyptrs, anyarrays, spaceafter; Expr *dimen[30]; Expr *ex, *maxv; Type *tp, *functype, *basetype; Expr funcdummy; /* yow */ anyptrs = 0; anyarrays = 0; functype = NULL; basetype = findbasetype(type, flags); depth = 0; if (flags & ODECL_REF) dimen[depth++] = NULL; if (new_array_size) { dimen[depth++] = copyexpr(new_array_size); anyarrays = 1; new_array_size = NULL; } for (tp = type; tp && tp != basetype; tp = tp->basetype) { switch (tp->kind) { case TK_POINTER: if (tp->basetype) { switch (tp->basetype->kind) { case TK_VOID: if (tp->basetype == tp_void && tp_special_anyptr) { tp = tp_special_anyptr; continue; } break; case TK_ARRAY: /* ptr to array of x => ptr to x */ case TK_STRING: /* or => array of x */ case TK_SET: if (stararrays == 1 || !(flags & ODECL_FREEARRAY) || (tp->basetype->structdefd && stararrays != 2)) { tp = tp->basetype; flags &= ~ODECL_CHARSTAR;#ifdef PRES_PTR_ARRAY if (tp->preserved && !(flags & ODECL_NOPRES)) continue;#endif } else { continue; } break; default: break; } } dimen[depth++] = NULL; anyptrs++; if (tp->kind == TK_POINTER && tp->basetype->kind != TK_POINTER && tp->fbase && tp->fbase->wasdeclared) break; continue; case TK_ARRAY: flags &= ~ODECL_CHARSTAR; if (tp->meaning && tp->meaning->kind == MK_TYPE && tp->meaning->wasdeclared) break; if (tp->structdefd) { /* conformant array */ if (!variablearrays && !(tp->basetype->kind == TK_ARRAY && tp->basetype->structdefd)) /* avoid mult. notes */ note("Conformant array code may not work in all compilers [101]"); } ex = arraysize(tp, 1); if (!ex) ex = makeexpr_name("", tp_integer); dimen[depth++] = ex; anyarrays++; if (tp->fbase && tp->fbase->wasdeclared) break; continue; case TK_SET: ord_range_expr(tp->indextype, NULL, &maxv); maxv = enum_to_int(copyexpr(maxv)); if (ord_type(maxv->val.type)->kind == TK_CHAR) maxv->val.type = tp_integer; dimen[depth++] = makeexpr_plus(makeexpr_div(maxv, makeexpr_setbits()), makeexpr_long(2)); break; case TK_STRING: if ((flags & ODECL_CHARSTAR) && stararrays == 1) { dimen[depth++] = NULL; } else { ord_range_expr(tp->indextype, NULL, &maxv); dimen[depth++] = makeexpr_plus(copyexpr(maxv), makeexpr_long(1)); } continue; case TK_FILE: break; case TK_CPROCPTR: dimen[depth++] = NULL; anyptrs++; if (procptrprototypes) continue; dimen[depth++] = &funcdummy; break; case TK_FUNCTION: dimen[depth++] = &funcdummy; if (!functype) functype = tp; continue; default: break; } break; } if (!*name && depth && (spaceexprs > 0 || (spaceexprs != 0 && !dimen[depth-1]))) output(" "); /* spacing for abstract declarator */ if ((flags & ODECL_FUNCTION) && anyptrs) output(" "); spaceafter = ((spacestars == 1 || spacestars == 3 || (spacestars == 2 && (flags & ODECL_REF) && depth == 1)) && depth > 0 && !dimen[depth-1]); if ((flags & ODECL_SPACE) && !spaceafter) output((flags & ODECL_SPMRG) ? " \005" : " "); if (anyarrays > 1 && !(flags & ODECL_FUNCTION)) output("\003"); for (i = depth; --i >= 0; ) { if (!dimen[i]) { if (i == 0 && (flags & ODECL_REF)) { if ((flags & ODECL_SPACE) && spaceafter && spacestars == 3) { output((flags & ODECL_SPMRG) ? " \005" : " "); spaceafter = 0; } output("&"); } else output("*"); } if (i > 0 && ((dimen[i] && !dimen[i-1]) || (dimen[i-1] && !dimen[i] && extraparens > 0))) output("("); } if (flags & ODECL_FUNCTION) output("\n"); if (anyarrays > 1 && (flags & ODECL_FUNCTION)) output("\003"); if ((flags & ODECL_SPACE) && spaceafter) output((flags & ODECL_SPMRG) ? " \005" : " "); output(name); for (i = 0; i < depth; i++) { if (i > 0 && ((dimen[i] && !dimen[i-1]) || (dimen[i-1] && !dimen[i] && extraparens > 0))) output(")"); if (dimen[i]) { if (dimen[i] == &funcdummy) { if (lookback(1) == ')') output("\002"); if (functype) declare_args(functype, (flags & ODECL_HEADER) != 0, (flags & ODECL_FORWARD) != 0); else if (spacefuncs) output(" ()"); else output("()"); } else { if (lookback(1) == ']') output("\002"); output("["); if (!(flags & ODECL_FREEARRAY) || stararrays == 0 || i > 0) out_expr(dimen[i]); freeexpr(dimen[i]); output("]"); } } } if (anyarrays > 1) output("\004");}/* Find out if types t1 and t2 will work out to be the same C type, for purposes of type-casting */Type *canonicaltype(type)Type *type;{ if (type->kind == TK_SUBR || type->kind == TK_ENUM || type->kind == TK_PROCPTR) type = findbasetype(type, 0); if (type == tp_char) return tp_ubyte; if (type->kind == TK_POINTER) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -