home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 379a.lha / p2c1_13a / src / src.zoo / decl2.c < prev    next >
C/C++ Source or Header  |  1990-03-10  |  26KB  |  1,003 lines

  1. /* "p2c", a Pascal to C translator.
  2.    Copyright (C) 1989 David Gillespie.
  3.    Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation (any version).
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; see the file COPYING.  If not, write to
  16. the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  17.  
  18. #define PROTO_DECL2_C
  19. #include "trans.h"
  20.  
  21. #define MAXIMPORTS 100
  22.  
  23. extern struct ptrdesc {
  24.     struct ptrdesc *next;
  25.     Symbol *sym;
  26.     Type *tp;
  27. } *ptrbase;
  28.  
  29. extern struct ctxstack {
  30.     struct ctxstack *next;
  31.     Meaning *ctx, *ctxlast;
  32.     struct tempvarlist *tempvars;
  33.     int tempvarcount, importmark;
  34. } *ctxtop;
  35.  
  36. extern struct tempvarlist {
  37.     struct tempvarlist *next;
  38.     Meaning *tvar;
  39.     int active;
  40. } *tempvars, *stmttempvars;
  41.  
  42. extern int tempvarcount;
  43.  
  44. extern int stringtypecachesize;
  45. extern Type **stringtypecache;
  46.  
  47. extern Meaning *importlist[MAXIMPORTS];
  48. extern int firstimport;
  49.  
  50. extern Type *tp_special_anyptr;
  51.  
  52. extern int wasaliased;
  53. extern int deferallptrs;
  54. extern int anydeferredptrs;
  55. extern int silentalreadydef;
  56. extern int nonloclabelcount;
  57.  
  58. extern Strlist *varstructdecllist;
  59.  
  60. Meaning *addmeaningas(sym, kind, namekind)
  61. Symbol *sym;
  62. enum meaningkind kind, namekind;
  63. {
  64.     Meaning *mp;
  65.  
  66.     mp = ALLOC(1, Meaning, meanings);
  67.     initmeaning(mp);
  68.     setupmeaning(mp, sym, kind, namekind);
  69.     mp->cnext = NULL;
  70.     if (curctx) {
  71.         if (curctxlast)
  72.             curctxlast->cnext = mp;
  73.         else
  74.             curctx->cbase = mp;
  75.         curctxlast = mp;
  76.     }
  77.     return mp;
  78. }
  79.  
  80.  
  81.  
  82. Meaning *addmeaning(sym, kind)
  83. Symbol *sym;
  84. enum meaningkind kind;
  85. {
  86.     return addmeaningas(sym, kind, kind);
  87. }
  88.  
  89.  
  90.  
  91. Meaning *addmeaningafter(mpprev, sym, kind)
  92. Meaning *mpprev;
  93. Symbol *sym;
  94. enum meaningkind kind;
  95. {
  96.     Meaning *mp;
  97.  
  98.     if (!mpprev->cnext && mpprev->ctx == curctx)
  99.         return addmeaning(sym, kind);
  100.     mp = ALLOC(1, Meaning, meanings);
  101.     initmeaning(mp);
  102.     setupmeaning(mp, sym, kind, kind);
  103.     mp->ctx = mpprev->ctx;
  104.     mp->cnext = mpprev->cnext;
  105.     mpprev->cnext = mp;
  106.     return mp;
  107. }
  108.  
  109.  
  110. void unaddmeaning(mp)
  111. Meaning *mp;
  112. {
  113.     Meaning *prev;
  114.  
  115.     prev = mp->ctx;
  116.     while (prev && prev != mp)
  117.     prev = prev->cnext;
  118.     if (prev)
  119.     prev->cnext = mp->cnext;
  120.     else
  121.     mp->ctx = mp->cnext;
  122.     if (!mp->cnext && mp->ctx == curctx)
  123.     curctxlast = prev;
  124. }
  125.  
  126.  
  127. void readdmeaning(mp)
  128. Meaning *mp;
  129. {
  130.     mp->cnext = NULL;
  131.     if (curctx) {
  132.         if (curctxlast)
  133.             curctxlast->cnext = mp;
  134.         else
  135.             curctx->cbase = mp;
  136.         curctxlast = mp;
  137.     }
  138. }
  139.  
  140.  
  141. Meaning *addfield(sym, flast, rectype, tname)
  142. Symbol *sym;
  143. Meaning ***flast;
  144. Type *rectype;
  145. Meaning *tname;
  146. {
  147.     Meaning *mp;
  148.     int altnum;
  149.     Symbol *sym2;
  150.     Strlist *sl;
  151.     char *name, *name2;
  152.  
  153.     mp = ALLOC(1, Meaning, meanings);
  154.     initmeaning(mp);
  155.     mp->sym = sym;
  156.     if (sym) {
  157.         mp->snext = sym->fbase;
  158.         sym->fbase = mp;
  159.         if (sym == curtoksym)
  160.             name2 = curtokcase;
  161.         else
  162.             name2 = sym->name;
  163.     name = name2;
  164.         if (tname)
  165.             sl = strlist_find(fieldmacros,
  166.                               format_ss("%s.%s", tname->sym->name, sym->name));
  167.         else
  168.             sl = NULL;
  169.         if (sl) {
  170.             mp->constdefn = (Expr *)sl->value;
  171.             strlist_delete(&fieldmacros, sl);
  172.             altnum = 0;
  173.         } else {
  174.             altnum = -1;
  175.             do {
  176.                 altnum++;
  177.         if (*fieldformat)
  178.             name = format_ss(fieldformat, name2,
  179.                      tname && tname->name ? tname->name
  180.                                           : "FIELD");
  181.                 sym2 = findsymbol(findaltname(name, altnum));
  182.             } while (!issafename(sym2, 0, 0) ||
  183.              ((sym2->flags & AVOIDFIELD) && !reusefieldnames));
  184.         if (!reusefieldnames)
  185.         sym2->flags |= AVOIDFIELD;
  186.         }
  187.         mp->kind = MK_FIELD;
  188.         mp->name = stralloc(findaltname(name, altnum));
  189.     } else {
  190.         mp->name = stralloc("(variant)");
  191.         mp->kind = MK_VARIANT;
  192.     }
  193.     mp->cnext = NULL;
  194.     **flast = mp;
  195.     *flast = &(mp->cnext);
  196.     mp->ctx = NULL;
  197.     mp->rectype = rectype;
  198.     mp->val.i = 0;
  199.     return mp;
  200. }
  201.  
  202.  
  203.  
  204.  
  205.  
  206. int isfiletype(type)
  207. Type *type;
  208. {
  209.     return (type->kind == TK_POINTER &&
  210.             type->basetype->kind == TK_FILE);
  211. }
  212.  
  213.  
  214. Meaning *isfilevar(ex)
  215. Expr *ex;
  216. {
  217.     Meaning *mp;
  218.  
  219.     if (ex->kind == EK_VAR) {
  220.     mp = (Meaning *)ex->val.i;
  221.     if (mp->kind == MK_VAR)
  222.         return mp;
  223.     } else if (ex->kind == EK_DOT) {
  224.     mp = (Meaning *)ex->val.i;
  225.     if (mp && mp->kind == MK_FIELD)
  226.         return mp;
  227.     }
  228.     return NULL;
  229. }
  230.  
  231.  
  232.  
  233. Type *findbasetype_(type, flags)
  234. Type *type;
  235. int flags;
  236. {
  237.     long smin, smax;
  238.  
  239.     for (;;) {
  240.         switch (type->kind) {
  241.  
  242.             case TK_POINTER:
  243.                 if (type->basetype == tp_void) {     /* ANYPTR */
  244.                     if (tp_special_anyptr)
  245.                         return tp_special_anyptr;   /* write "Anyptr" */
  246.                     if (!voidstar)
  247.                         return tp_abyte;    /* write "char *", not "void *" */
  248.                 }
  249.                 switch (type->basetype->kind) {
  250.  
  251.                     case TK_ARRAY:       /* use basetype's basetype: */
  252.                     case TK_STRING:      /* ^array[5] of array[3] of integer */
  253.                     case TK_SET:         /*  => int (*a)[3]; */
  254.                 if (stararrays == 1 ||
  255.                 !(flags & ODECL_FREEARRAY) ||
  256.                 type->basetype->structdefd) {
  257.                 type = type->basetype;
  258.                 flags &= ~ODECL_CHARSTAR;
  259.             }
  260.                         break;
  261.  
  262.             default:
  263.             break;
  264.                 }
  265.                 break;
  266.  
  267.             case TK_FUNCTION:
  268.             case TK_STRING:
  269.             case TK_SET:
  270.             case TK_SMALLSET:
  271.             case TK_SMALLARRAY:
  272.                 if (!type->basetype)
  273.                     return type;
  274.                 break;
  275.  
  276.             case TK_ARRAY:
  277.                 if (type->meaning && type->meaning->kind == MK_TYPE &&
  278.                     type->meaning->wasdeclared)
  279.                     return type;
  280.                 break;
  281.  
  282.             case TK_FILE:
  283.                 return tp_text->basetype;
  284.  
  285.             case TK_PROCPTR:
  286.         return tp_proc;
  287.  
  288.         case TK_CPROCPTR:
  289.         type = type->basetype->basetype;
  290.         continue;
  291.  
  292.             case TK_ENUM:
  293.                 if (useenum)
  294.                     return type;
  295.                 else if (!enumbyte ||
  296.              type->smax->kind != EK_CONST ||
  297.              type->smax->val.i > 255)
  298.             return tp_sshort;
  299.         else if (type->smax->val.i > 127)
  300.                     return tp_ubyte;
  301.         else
  302.                     return tp_abyte;
  303.  
  304.             case TK_BOOLEAN:
  305.                 if (*name_BOOLEAN)
  306.                     return type;
  307.                 else
  308.                     return tp_ubyte;
  309.  
  310.             case TK_SUBR:
  311.                 if (type == tp_abyte || type == tp_ubyte || type == tp_sbyte ||
  312.                     type == tp_ushort || type == tp_sshort) {
  313.                     return type;
  314.                 } else if ((type->basetype->kind == TK_ENUM && useenum) ||
  315.                            type->basetype->kind == TK_BOOLEAN && *name_BOOLEAN) {
  316.                     return type->basetype;
  317.                 } else {
  318.                     if (ord_range(type, &smin, &smax)) {
  319.                         if (squeezesubr != 0) {
  320.                             if (smin >= 0 && smax <= max_schar)
  321.                                 return tp_abyte;
  322.                             else if (smin >= 0 && smax <= max_uchar)
  323.                                 return tp_ubyte;
  324.                             else if (smin >= min_schar && smax <= max_schar &&
  325.                      (signedchars == 1 || hassignedchar))
  326.                                 return tp_sbyte;
  327.                             else if (smin >= min_sshort && smax <= max_sshort)
  328.                                 return tp_sshort;
  329.                             else if (smin >= 0 && smax <= max_ushort)
  330.                                 return tp_ushort;
  331.                             else
  332.                                 return tp_integer;
  333.                         } else {
  334.                             if (smin >= min_sshort && smax <= max_sshort)
  335.                                 return tp_sshort;
  336.                             else
  337.                                 return tp_integer;
  338.                         }
  339.                     } else
  340.                         return tp_integer;
  341.                 }
  342.  
  343.         case TK_CHAR:
  344.         if (type == tp_schar &&
  345.             (signedchars != 1 && !hassignedchar)) {
  346.             return tp_sshort;
  347.         }
  348.         return type;
  349.  
  350.             default:
  351.                 return type;
  352.         }
  353.         type = type->basetype;
  354.     }
  355. }
  356.  
  357.  
  358. Type *findbasetype(type, flags)
  359. Type *type;
  360. int flags;
  361. {
  362.     if (debug>1) {
  363.     fprintf(outf, "findbasetype(");
  364.     dumptypename(type, 1);
  365.     fprintf(outf, ",%d) = ", flags);
  366.     type = findbasetype_(type, flags);
  367.     dumptypename(type, 1);
  368.     fprintf(outf, "\n");
  369.     return type;
  370.     }
  371.     return findbasetype_(type, flags);
  372. }
  373.  
  374.  
  375.  
  376. Expr *arraysize(tp, incskipped)
  377. Type *tp;
  378. int incskipped;
  379. {
  380.     Expr *ex, *minv, *maxv;
  381.     int denom;
  382.  
  383.     ord_range_expr(tp->indextype, &minv, &maxv);
  384.     if (maxv->kind == EK_VAR && maxv->val.i == (long)mp_maxint &&
  385.     !exprdependsvar(minv, mp_maxint)) {
  386.         return NULL;
  387.     } else {
  388.         ex = makeexpr_plus(makeexpr_minus(copyexpr(maxv),
  389.                                           copyexpr(minv)),
  390.                            makeexpr_long(1));
  391.         if (tp->smin && !incskipped) {
  392.             ex = makeexpr_minus(ex, copyexpr(tp->smin));
  393.         }
  394.         if (tp->smax) {
  395.             denom = (tp->basetype == tp_sshort) ? 16 : 8;
  396.             denom >>= tp->escale;
  397.             ex = makeexpr_div(makeexpr_plus(ex, makeexpr_long(denom-1)),
  398.                               makeexpr_long(denom));
  399.         }
  400.         return ex;
  401.     }
  402. }
  403.  
  404.  
  405.  
  406. Type *promote_type(tp)
  407. Type *tp;
  408. {
  409.     Type *tp2;
  410.  
  411.     if (tp->kind == TK_ENUM) {
  412.     if (promote_enums == 0 ||
  413.         (promote_enums < 0 &&
  414.          (useenum)))
  415.         return tp;
  416.     }
  417.     if (tp->kind == TK_ENUM ||
  418.          tp->kind == TK_SUBR ||
  419.          tp->kind == TK_INTEGER ||
  420.          tp->kind == TK_CHAR ||
  421.          tp->kind == TK_BOOLEAN) {
  422.         tp2 = findbasetype(tp, 0);
  423.     if (tp2 == tp_ushort && sizeof_int == 16)
  424.         return tp_uint;
  425.         else if (tp2 == tp_sbyte || tp2 == tp_ubyte ||
  426.          tp2 == tp_abyte || tp2 == tp_char ||
  427.          tp2 == tp_sshort || tp2 == tp_ushort ||
  428.          tp2 == tp_boolean || tp2->kind == TK_ENUM) {
  429.             return tp_int;
  430.         }
  431.     }
  432.     if (tp == tp_real)
  433.     return tp_longreal;
  434.     return tp;
  435. }
  436.  
  437.  
  438. Type *promote_type_bin(t1, t2)
  439. Type *t1, *t2;
  440. {
  441.     t1 = promote_type(t1);
  442.     t2 = promote_type(t2);
  443.     if (t1 == tp_longreal || t2 == tp_longreal)
  444.     return tp_longreal;
  445.     if (t1 == tp_unsigned || t2 == tp_unsigned)
  446.     return tp_unsigned;
  447.     if (t1 == tp_integer || t2 == tp_integer) {
  448.     if ((t1 == tp_uint || t2 == tp_uint) &&
  449.         sizeof_int > 0 &&
  450.         sizeof_int < (sizeof_long > 0 ? sizeof_long : 32))
  451.         return tp_uint;
  452.     return tp_integer;
  453.     }
  454.     if (t1 == tp_uint || t2 == tp_uint)
  455.     return tp_uint;
  456.     return t1;
  457. }
  458.  
  459.  
  460.  
  461. #if 0
  462. void predeclare_varstruct(mp)
  463. Meaning *mp;
  464. {
  465.     if (mp->ctx &&
  466.      mp->ctx->kind == MK_FUNCTION &&
  467.      mp->ctx->varstructflag &&
  468.      (usePPMacros != 0 || prototypes != 0) &&
  469.      !strlist_find(varstructdecllist, mp->ctx->name)) {
  470.     output("struct ");
  471.     output(format_s(name_LOC, mp->ctx->name));
  472.     output(" ;\n");
  473.     strlist_insert(&varstructdecllist, mp->ctx->name);
  474.     }
  475. }
  476. #endif
  477.  
  478.  
  479. Static void declare_args(type, isheader, isforward)
  480. Type *type;
  481. int isheader, isforward;
  482. {
  483.     Meaning *mp = type->fbase;
  484.     Type *tp;
  485.     int firstflag = 0;
  486.     int usePP, dopromote, proto, showtypes, shownames;
  487.     int staticlink;
  488.     char *name;
  489.  
  490. #if 1   /* This seems to work better! */
  491.     isforward = !isheader;
  492. #endif
  493.     usePP = (isforward && usePPMacros != 0);
  494.     dopromote = (promoteargs == 1 ||
  495.          (promoteargs < 0 && (usePP || !fullprototyping)));
  496.     if (ansiC == 1 && blockkind != TOK_EXPORT)
  497.     usePP = 0;
  498.     if (usePP)
  499.         proto = (prototypes) ? prototypes : 1;
  500.     else
  501.         proto = (isforward || fullprototyping) ? prototypes : 0;
  502.     showtypes = (proto > 0);
  503.     shownames = (proto == 1 || isheader);
  504.     staticlink = (type->issigned ||
  505.                   (type->meaning &&
  506.                    type->meaning->ctx->kind == MK_FUNCTION &&
  507.                    type->meaning->ctx->varstructflag));
  508.     if (mp || staticlink) {
  509.         if (usePP)
  510.             output(" PP(");
  511.         output("(");
  512.         if (showtypes || shownames) {
  513.             firstflag = 0;
  514.             while (mp) {
  515.                 if (firstflag++) output(",\002 ");
  516.                 name = (mp->othername && isheader) ? mp->othername : mp->name;
  517.                 tp = (mp->othername) ? mp->rectype : mp->type;
  518.                 if (!showtypes) {
  519.                     output(name);
  520.                 } else {
  521.             output(storageclassname(varstorageclass(mp)));
  522.             if (!shownames || (isforward && *name == '_')) {
  523.             out_type(tp, 1);
  524.             } else {
  525.             if (dopromote)
  526.                 tp = promote_type(tp);
  527.             outbasetype(tp, ODECL_CHARSTAR|ODECL_FREEARRAY);
  528.             output(" ");
  529.             outdeclarator(tp, name,
  530.                       ODECL_CHARSTAR|ODECL_FREEARRAY);
  531.             }
  532.         }
  533.                 if (isheader)
  534.                     mp->wasdeclared = showtypes;
  535.                 if (mp->type == tp_strptr && mp->anyvarflag) {     /* VAR STRING parameter */
  536.                     output(",\002 ");
  537.                     if (showtypes) {
  538.             if (useAnyptrMacros == 1 || useconsts == 2)
  539.                 output("Const ");
  540.             else if (ansiC > 0)
  541.                 output("const ");
  542.                         output("int");
  543.             }
  544.                     if (shownames) {
  545.                         if (showtypes)
  546.                             output(" ");
  547.                         output(format_s(name_STRMAX, mp->name));
  548.                     }
  549.                 }
  550.                 mp = mp->xnext;
  551.             }
  552.             if (staticlink) {     /* sub-procedure with static link */
  553.                 if (firstflag++) output(",\002 ");
  554.                 if (type->issigned) {
  555.                     if (showtypes)
  556.             if (tp_special_anyptr)
  557.                 output("Anyptr ");
  558.             else if (voidstar)
  559.                 output("void *");
  560.             else
  561.                 output("char *");
  562.                     if (shownames)
  563.                         output("_link");
  564.                 } else {
  565.                     mp = type->meaning->ctx;
  566.                     if (showtypes) {
  567.                         output("struct ");
  568.                         output(format_s(name_LOC, mp->name));
  569.                         output(" *");
  570.                     }
  571.                     if (shownames) {
  572.                         output(format_s(name_LINK, mp->name));
  573.                     }
  574.                 }
  575.             }
  576.         }
  577.         output(")");
  578.         if (usePP)
  579.             output(")");
  580.     } else {
  581.         if (usePP)
  582.             output(" PV()");
  583.         else if (void_args)
  584.             output("(void)");
  585.         else
  586.             output("()");
  587.     }
  588. }
  589.  
  590.  
  591.  
  592. void outdeclarator(type, name, flags)
  593. Type *type;
  594. char *name;
  595. int flags;
  596. {
  597.     int i, depth, anyptrs, anyarrays;
  598.     Expr *dimen[30];
  599.     Expr *ex, *maxv;
  600.     Type *tp, *functype;
  601.     Expr funcdummy;   /* yow */
  602.  
  603.     anyptrs = 0;
  604.     anyarrays = 0;
  605.     functype = NULL;
  606.     for (depth = 0, tp = type; tp; tp = tp->basetype) {
  607.         switch (tp->kind) {
  608.  
  609.             case TK_POINTER:
  610.                 if (tp->basetype) {
  611.                     switch (tp->basetype->kind) {
  612.  
  613.                 case TK_VOID:
  614.                 if (tp->basetype == tp_void &&
  615.                 tp_special_anyptr) {
  616.                 tp = tp_special_anyptr;
  617.                 continue;
  618.                 }
  619.                 break;
  620.  
  621.                         case TK_ARRAY:    /* ptr to array of x => ptr to x */
  622.                         case TK_STRING:   /*                or => array of x */
  623.                         case TK_SET:
  624.                 if (stararrays == 1 ||
  625.                 !(flags & ODECL_FREEARRAY) ||
  626.                 (tp->basetype->structdefd &&
  627.                  stararrays != 2)) {
  628.                 tp = tp->basetype;
  629.                 flags &= ~ODECL_CHARSTAR;
  630.                 } else {
  631.                 continue;
  632.                 }
  633.                             break;
  634.  
  635.             default:
  636.                 break;
  637.                     }
  638.                 }
  639.                 dimen[depth++] = NULL;
  640.                 anyptrs++;
  641.                 continue;
  642.  
  643.             case TK_ARRAY:
  644.         flags &= ~ODECL_CHARSTAR;
  645.                 if (tp->meaning && tp->meaning->kind == MK_TYPE &&
  646.                     tp->meaning->wasdeclared)
  647.                     break;
  648.         if (tp->structdefd) {    /* conformant array */
  649.             if (!variablearrays &&
  650.             !(tp->basetype->kind == TK_ARRAY &&
  651.               tp->basetype->structdefd))   /* avoid mult. notes */
  652.             note("Conformant array code may not work in all compilers [101]");
  653.         }
  654.                 ex = arraysize(tp, 1);
  655.                 if (!ex)
  656.                     ex = makeexpr_name("", tp_integer);
  657.                 dimen[depth++] = ex;
  658.         anyarrays++;
  659.                 continue;
  660.  
  661.             case TK_SET:
  662.                 ord_range_expr(tp->indextype, NULL, &maxv);
  663.                 maxv = enum_to_int(copyexpr(maxv));
  664.                 if (ord_type(maxv->val.type)->kind == TK_CHAR)
  665.                     maxv->val.type = tp_integer;
  666.                 dimen[depth++] = makeexpr_plus(makeexpr_div(maxv, makeexpr_setbits()),
  667.                                                makeexpr_long(2));
  668.                 break;
  669.  
  670.             case TK_STRING:
  671.                 if ((flags & ODECL_CHARSTAR) && stararrays == 1) {
  672.                     dimen[depth++] = NULL;
  673.                 } else {
  674.                     ord_range_expr(tp->indextype, NULL, &maxv);
  675.                     dimen[depth++] = makeexpr_plus(copyexpr(maxv), makeexpr_long(1));
  676.                 }
  677.                 continue;
  678.  
  679.             case TK_FILE:
  680.                 break;
  681.  
  682.         case TK_CPROCPTR:
  683.         dimen[depth++] = NULL;
  684.         anyptrs++;
  685.         if (procptrprototypes)
  686.             continue;
  687.                 dimen[depth++] = &funcdummy;
  688.         break;
  689.  
  690.             case TK_FUNCTION:
  691.                 dimen[depth++] = &funcdummy;
  692.                 if (!functype)
  693.                     functype = tp;
  694.                 continue;
  695.  
  696.         default:
  697.         break;
  698.         }
  699.         break;
  700.     }
  701.     if (!*name && depth && (spaceexprs > 0 ||
  702.                             (spaceexprs != 0 && !dimen[depth-1])))
  703.         output(" ");    /* spacing for abstract declarator */
  704.     if ((flags & ODECL_FUNCTION) && anyptrs)
  705.         output(" ");
  706.     if (anyarrays > 1 && !(flags & ODECL_FUNCTION))
  707.     output("\003");
  708.     for (i = depth; --i >= 0; ) {
  709.         if (!dimen[i])
  710.             output("*");
  711.         if (i > 0 &&
  712.             ((dimen[i] && !dimen[i-1]) ||
  713.              (dimen[i-1] && !dimen[i] && extraparens > 0)))
  714.             output("(");
  715.     }
  716.     if (flags & ODECL_FUNCTION)
  717.         output("\n");
  718.     if (anyarrays > 1 && (flags & ODECL_FUNCTION))
  719.     output("\003");
  720.     output(name);
  721.     for (i = 0; i < depth; i++) {
  722.         if (i > 0 &&
  723.             ((dimen[i] && !dimen[i-1]) ||
  724.              (dimen[i-1] && !dimen[i] && extraparens > 0)))
  725.             output(")");
  726.         if (dimen[i]) {
  727.             if (dimen[i] == &funcdummy) {
  728.         if (lookback(1) == ')')
  729.             output("\002");
  730.         if (functype)
  731.             declare_args(functype, (flags & ODECL_HEADER) != 0,
  732.                            (flags & ODECL_FORWARD) != 0);
  733.         else
  734.             output("()");
  735.             } else {
  736.         if (lookback(1) == ']')
  737.             output("\002");
  738.                 output("[");
  739.                 if (!(flags & ODECL_FREEARRAY) || stararrays == 0 || i > 0)
  740.                     out_expr(dimen[i]);
  741.                 freeexpr(dimen[i]);
  742.                 output("]");
  743.             }
  744.         }
  745.     }
  746.     if (anyarrays > 1)
  747.     output("\004");
  748. }
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755. /* Find out if types t1 and t2 will work out to be the same C type,
  756.    for purposes of type-casting */
  757.  
  758. Type *canonicaltype(type)
  759. Type *type;
  760. {
  761.     if (type->kind == TK_SUBR || type->kind == TK_ENUM ||
  762.         type->kind == TK_PROCPTR)
  763.         type = findbasetype(type, 0);
  764.     if (type == tp_char)
  765.         return tp_ubyte;
  766.     if (type->kind == TK_POINTER) {
  767.         if (type->basetype->kind == TK_ARRAY ||
  768.             type->basetype->kind == TK_STRING ||
  769.             type->basetype->kind == TK_SET)
  770.             return makepointertype(canonicaltype(type->basetype->basetype));
  771.         else if (type->basetype == tp_void)
  772.             return (voidstar) ? tp_anyptr : makepointertype(tp_abyte);
  773.         else if (type->basetype->kind == TK_FILE)
  774.             return tp_text;
  775.         else
  776.             return makepointertype(canonicaltype(type->basetype));
  777.     }
  778.     return type;
  779. }
  780.  
  781.  
  782. int similartypes(t1, t2)
  783. Type *t1, *t2;
  784. {
  785.     t1 = canonicaltype(t1);
  786.     t2 = canonicaltype(t2);
  787.     return (t1 == t2);
  788. }
  789.  
  790.  
  791.  
  792.  
  793.  
  794. Static int checkstructconst(mp)
  795. Meaning *mp;
  796. {
  797.     return (mp->kind == MK_VAR &&
  798.         mp->constdefn &&
  799.             mp->constdefn->kind == EK_CONST &&
  800.             (mp->constdefn->val.type->kind == TK_ARRAY ||
  801.              mp->constdefn->val.type->kind == TK_RECORD));
  802. }
  803.  
  804.  
  805. Static int mixable(mp1, mp2, args, flags)
  806. Meaning *mp1, *mp2;
  807. int args, flags;
  808. {
  809.     Type *tp1 = mp1->type, *tp2 = mp2->type;
  810.  
  811.     if (mixvars == 0)
  812.         return 0;
  813.     if (mp1->kind == MK_FIELD &&
  814.         (mp1->val.i || mp2->val.i) && mixfields == 0)
  815.         return 0;
  816.     if (checkstructconst(mp1) || checkstructconst(mp2))
  817.         return 0;
  818.     if (mp1->comments) {
  819.     if (findcomment(mp1->comments, CMT_NOT | CMT_PRE, -1))
  820.         return 0;
  821.     }
  822.     if (mp2->comments) {
  823.     if (findcomment(mp2->comments, CMT_PRE, -1))
  824.         return 0;
  825.     }
  826.     if ((mp1->constdefn && (mp1->kind == MK_VAR || mp1->kind == MK_VARREF)) ||
  827.     (mp2->constdefn && (mp2->kind == MK_VAR || mp2->kind == MK_VARREF))) {
  828.         if (mixinits == 0)
  829.             return 0;
  830.         if (mixinits != 1 &&
  831.             (!mp1->constdefn || !mp2->constdefn))
  832.             return 0;
  833.     }
  834.     if (args) {
  835.         if (mp1->kind == MK_PARAM && mp1->othername)
  836.             tp1 = mp1->rectype;
  837.         if (mp2->kind == MK_PARAM && mp2->othername)
  838.             tp2 = mp2->rectype;
  839.     }
  840.     if (tp1 == tp2)
  841.         return 1;
  842.     switch (mixtypes) {
  843.         case 0:
  844.             return 0;
  845.         case 1:
  846.             return (findbasetype(tp1, flags) == findbasetype(tp2, flags));
  847.         default:
  848.             if (findbasetype(tp1, flags) != findbasetype(tp2, flags))
  849.         return 0;
  850.             while (tp1->kind == TK_POINTER && tp1->basetype)
  851.                 tp1 = tp1->basetype;
  852.             while (tp2->kind == TK_POINTER && tp2->basetype)
  853.                 tp2 = tp2->basetype;
  854.             return (tp1 == tp2);
  855.     }
  856. }
  857.  
  858.  
  859.  
  860. void declarefiles(fnames)
  861. Strlist *fnames;
  862. {
  863.     Meaning *mp;
  864.     char *cp;
  865.  
  866.     while (fnames) {
  867.     mp = (Meaning *)fnames->value;
  868.     if (mp->kind == MK_VAR || mp->kind == MK_FIELD) {
  869.         if (mp->namedfile) {
  870.         output(storageclassname(varstorageclass(mp)));
  871.         output(format_ss("%s %s", charname,
  872.                  format_s(name_FNVAR, fnames->s)));
  873.         output(format_s("[%s];\n", *name_FNSIZE ? name_FNSIZE : "80"));
  874.         }
  875.         if (mp->bufferedfile && *declbufname) {
  876.         cp = format_s("%s", storageclassname(varstorageclass(mp)));
  877.         if (*cp && isspace(cp[strlen(cp)-1]))
  878.           cp[strlen(cp)-1] = 0;
  879.         if (*cp || !*declbufncname) {
  880.             output(declbufname);
  881.             output("(");
  882.             output(fnames->s);
  883.             output(",");
  884.             output(cp);
  885.         } else {
  886.             output(declbufncname);
  887.             output("(");
  888.             output(fnames->s);
  889.         }
  890.         output(",");
  891.         out_type(mp->type->basetype->basetype, 1);
  892.         output(");\n");
  893.         }
  894.     }
  895.     strlist_eat(&fnames);
  896.     }
  897. }
  898.  
  899.  
  900.  
  901. char *variantfieldname(num)
  902. int num;
  903. {
  904.     if (num >= 0)
  905.         return format_d("U%d", num);
  906.     else
  907.         return format_d("UM%d", -num);
  908. }
  909.  
  910.  
  911. int record_is_union(tp)
  912. Type *tp;
  913. {
  914.     return (tp->fbase && tp->fbase->kind == MK_VARIANT);
  915. }
  916.  
  917.  
  918. void outfieldlist(mp)
  919. Meaning *mp;
  920. {
  921.     Meaning *mp0;
  922.     int num, only_union, empty, saveindent, saveindent2;
  923.     Strlist *fnames, *fn;
  924.  
  925.     if (!mp) {
  926.     output("int empty_struct;   /* Pascal record was empty */\n");
  927.     return;
  928.     }
  929.     only_union = (mp && mp->kind == MK_VARIANT);
  930.     fnames = NULL;
  931.     while (mp && mp->kind == MK_FIELD) {
  932.     flushcomments(&mp->comments, CMT_PRE, -1);
  933.     output(storageclassname(varstorageclass(mp) & 0x10));
  934.         outbasetype(mp->type, 0);
  935.         output(" \005");
  936.     for (;;) {
  937.         outdeclarator(mp->type, mp->name, 0);
  938.         if (mp->val.i && (mp->type != tp_abyte || mp->val.i != 8))
  939.         output(format_d(" : %d", mp->val.i));
  940.         if (isfiletype(mp->type)) {
  941.         fn = strlist_append(&fnames, mp->name);
  942.         fn->value = (long)mp;
  943.         }
  944.         mp->wasdeclared = 1;
  945.         if (!mp->cnext || mp->cnext->kind != MK_FIELD ||
  946.         varstorageclass(mp) != varstorageclass(mp->cnext) ||
  947.         !mixable(mp, mp->cnext, 0, 0))
  948.         break;
  949.             mp = mp->cnext;
  950.             output(",\001 ");
  951.         }
  952.         output(";");
  953.     outtrailcomment(mp->comments, -1, declcommentindent);
  954.     flushcomments(&mp->comments, -1, -1);
  955.         mp = mp->cnext;
  956.     }
  957.     declarefiles(fnames);
  958.     if (mp) {
  959.     saveindent = outindent;
  960.     empty = 1;
  961.         if (!only_union) {
  962.             output("union {\n");
  963.         moreindent(tabsize);
  964.         moreindent(structindent);
  965.         }
  966.         while (mp) {
  967.             mp0 = mp->ctx;
  968.             num = ord_value(mp->val);
  969.             while (mp && mp->ctx == mp0)
  970.                 mp = mp->cnext;
  971.             if (mp0) {
  972.         empty = 0;
  973.                 if (!mp0->cnext && mp0->kind == MK_FIELD) {
  974.                     outfieldlist(mp0);
  975.                 } else {
  976.                     if (mp0->kind == MK_VARIANT)
  977.                         output("union {\n");
  978.                     else
  979.                         output("struct {\n");
  980.             saveindent2 = outindent;
  981.             moreindent(tabsize);
  982.             moreindent(structindent);
  983.                     outfieldlist(mp0);
  984.             outindent = saveindent2;
  985.                     output("} ");
  986.                     output(format_s(name_VARIANT, variantfieldname(num)));
  987.                     output(";\n");
  988.                 }
  989.         flushcomments(&mp0->comments, -1, -1);
  990.             }
  991.         }
  992.     if (empty)
  993.         output("int empty_union;   /* Pascal variant record was empty */\n");
  994.         if (!only_union) {
  995.             outindent = saveindent;
  996.             output("} ");
  997.             output(format_s(name_UNION, ""));
  998.             output(";\n");
  999.         }
  1000.     }
  1001. }
  1002.  
  1003.