home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / DOS / Programa / CCDL122.ZIP / SOURCE / DECL.NEW < prev    next >
Encoding:
Text File  |  1996-08-05  |  45.1 KB  |  1,417 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1996, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and sources are distributed along with any executables derived from them.
  11.  *
  12.  * The author is not responsible for damages, either direct or consequential,
  13.  * that may arise from use of this software.
  14.  *
  15.  * v1.5 August 1996
  16.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  17.  *
  18.  * Credits to Mathew Brandt for original K&R C compiler
  19.  *
  20.  */
  21. #include        <stdio.h>
  22. #include        "expr.h"
  23. #include        "c.h"
  24. #include        "gen.h"
  25. #include        "cglbdec.h"
  26.  
  27. extern    SNODE *cbautoinithead;
  28. extern int prm_bss;
  29. extern int prm_packing;
  30. extern int prm_revbits;
  31. extern int prm_68020;
  32. extern HASHREC **globalhash;
  33. extern SYM *currentfunc;
  34. extern int prm_cplusplus;
  35. extern char * tn_unnamed;
  36. exter TYP stdint;
  37.  
  38. char *Cstr = "C";
  39.  
  40. int mangleflag;
  41. int skm_declopenpa[] = { semicolon, comma,openpa, eq,0 };
  42. int skm_declclosepa[] = { semicolon, comma,closepa, eq,0 };
  43. int skm_declclosebr[] = { semicolon, comma,closebr, eq,0 };
  44. int skm_declend[] = { semicolon, comma, end, eq,0 };
  45. int skm_decl[] = {semicolon,kw_int, kw_long, kw_short, kw_char, kw_float,
  46.         kw_double, kw_struct, kw_union, kw_enum, kw_unsigned, kw_signed, kw_auto,
  47.         kw_extern, kw_static, kw_register, kw_typedef, id, kw_void, 0 };
  48. int inclass = 0;
  49.  
  50. TYP             *head = 0;
  51. TYP             *tail = 0;
  52. char            declid[100];
  53. TABLE           tagtable = {0,0};
  54. TYP             stdconst = { bt_long, 1, 0, 0, 0, -1, -1, 4, {0, 0}, 0, "stdconst",0};
  55.  
  56. static                    SYM *lastdecl;
  57. static                     int pcount=0;
  58. static int bittype = -1;
  59. static int curbit = 0;
  60. static int curofs = 0;
  61. static int manglelevel;
  62. static char newclass[100],inherited[100],declclass[200],*lastclass,*lastdeclclass;
  63. static SYM *classdecltab;
  64.  
  65. void declini(void)
  66. {
  67.     inclass = 0;
  68.     bittype = -1;
  69.     head = tail = 0;
  70.     declid[0] = 0;
  71.     tagtable.head = tagtable.tail = 0;
  72.     pcount = 0;
  73.     mangleflag = TRUE;
  74.     lastclass = newclass;
  75. }
  76. int     imax(int i,int j)
  77. {       return (i > j) ? i : j;
  78. }
  79.  
  80. char    *litlate(char *s)
  81. {       char    *p;
  82.         p = xalloc(strlen(s) + 1);
  83.         strcpy(p,s);
  84.         return p;
  85. }
  86.  
  87. TYP     *maketype(int bt,int siz)
  88. {       TYP     *tp;
  89.                 
  90.         tp = xalloc(sizeof(TYP));
  91.         tp->val_flag = 0;
  92.                 tp->bits = tp->startbit = -1;
  93.         tp->size = siz;
  94.         tp->type = bt;
  95.         tp->sname = 0;
  96.                 tp->cflags = 0;
  97.                 tp->uflags = 0;
  98.         tp->lst.head = tp->lst.tail = 0;
  99.                 tp->tdef = 0;
  100.         return tp;
  101. }
  102. TYP *cponetype(TYP *t)
  103. {                TYP *tp;
  104.     tp = xalloc(sizeof(TYP));
  105.     tp->type = t->type;
  106.     tp->val_flag = t->val_flag;
  107.     tp->cflags = t->cflags;
  108.     tp->bits = t->bits;
  109.     tp->startbit = t->startbit;
  110.     tp->size = t->size;
  111.     tp->lst = t->lst;
  112.     tp->btp = t->btp;
  113.     tp->sname = t->sname;
  114.     tp->uflags = t->uflags;
  115.     tp->tdef = t->tdef;
  116.     return tp;
  117. }
  118. TYP *copytype(TYP *itp, int flags)
  119. {
  120.     TYP *head, *tail;
  121.     head = tail = cponetype(itp);
  122.     while (itp->type == bt_pointer) {
  123.         tail = tail->btp = cponetype(itp->btp);
  124.         itp = itp->btp;
  125.     }
  126.     if (itp->type == bt_func || itp->type == bt_ptrfunc || itp->type == bt_ifunc) {
  127.             tail->btp = cponetype(itp);
  128.     }
  129.     else {
  130.         tail->cflags |= flags;
  131.     }
  132.     return head;
  133. }
  134. void     decl(TABLE *table,int flags)
  135. {
  136.                 SYM *sp;
  137.         switch (lastst) {
  138.                                 case kw_void:
  139.                         head = tail = maketype(bt_void,0);
  140.                                                 getsym();
  141.                                                 break;
  142.                 case kw_char:
  143.                         head = tail = maketype(bt_char,1);
  144.                         getsym();
  145.                         break;
  146.                 case kw_short:
  147.                         head = tail = maketype(bt_short,2);
  148.                         getsym();
  149.                         break;
  150.                 case kw_int: 
  151.                         head = tail = maketype(bt_long,4);
  152.                         getsym();
  153.                         break;
  154.                 case kw_unsigned:
  155.                                                 getsym();
  156.                                                 switch (lastst) {
  157.                                                     case kw_char:
  158.                                                         getsym();
  159.                                 head = tail = maketype(bt_unsignedchar,1);
  160.                                                         break;
  161.                                                     case kw_short:
  162.                                                         getsym();
  163.                                 head = tail = maketype(bt_unsignedshort,2);
  164.                                                         break;
  165.                                                     case kw_int:
  166.                                                     case kw_long:
  167.                                                         getsym();
  168.                                                     default:
  169.                                 head = tail = maketype(bt_unsigned,4);
  170.                                                         break;
  171.                                                 }
  172.                         break;
  173.                 case kw_signed:
  174.                                                 getsym();
  175.                                                 switch (lastst) {
  176.                                                     case kw_char:
  177.                                                         getsym();
  178.                                 head = tail = maketype(bt_char,1);
  179.                                                         break;
  180.                                                     case kw_short:
  181.                                                         getsym();
  182.                                 head = tail = maketype(bt_short,2);
  183.                                                         break;
  184.                                                     case kw_int:
  185.                                                     case kw_long:
  186.                                                         getsym();
  187.                                                     default:
  188.                                 head = tail = maketype(bt_long,4);
  189.                                                         break;
  190.                                                 }
  191.                         break;
  192.                                 case not:
  193.                                                 if (prm_cplusplus && (inclass & PF_CLASSDEF)) {
  194.                                                     getsym();
  195.                                                     if (lastst != id || !strcmp(lastid,lastclass+1))
  196.                                                         gensymerror(ERR_BADESTRUCT,0,0);
  197.                                                     else {
  198.                                                         memmove(lastid+2,lastid+1,strlen(lastid))
  199.                                                         lastid[1] = '~';
  200.                                                     }
  201.                                                     if (head)
  202.                                                         generror(ERR_TYPECONSTRUCT,0,0);
  203.                                                     head = tail = maketype(bt_untyped,4);
  204.                                                 }
  205.                                                 break;
  206.                 case id:                /* no type declarator */
  207.                                                 if ((sp = gsearch(lastid)) != 0 && sp->storage_class == sc_type || sp->storage_class == sc_iclass)
  208.                                                         head = tail = copytype(sp->tp,flags);
  209.                                                     else if (sp->storage_class == sc_class) 
  210.                                                         if (sp->tp->type == bt_class) {
  211.                                                             generror(ERR_UNDEFINED);
  212.                                                             head = tail = maketype(bt_pointer,4);
  213.                                                         }
  214.                                                     getsym();
  215.                                                 }
  216.                                                 else
  217.                                                     if ((inclass & PF_CLASSDEF) && !strcmp(lastid,lastclass))
  218.                                    head = tail = maketype(bt_untyped,4);
  219.                                                     else
  220.                                    head = tail = maketype(bt_long,4);
  221.                         break;
  222.                 case kw_float:
  223.                         head = tail = maketype(bt_float,4);
  224.                         getsym();
  225.                         break;
  226.                                 case kw_long:
  227.                                                 getsym();
  228.                                                 if (lastst!=kw_double) {
  229.                             head = tail = maketype(bt_long,4);
  230.                                                     break;
  231.                                                 }
  232.                         head = tail = maketype(bt_longdouble,12);
  233.                         getsym();
  234.                         break;
  235.                 case kw_double:
  236.                         head = tail = maketype(bt_double,8);
  237.                         getsym();
  238.                         break;
  239.                 case kw_enum:
  240.                         getsym();
  241.                         declenum(table);
  242.                         break;
  243.                 case kw_struct:
  244.                         getsym();
  245.                         declstruct(bt_struct,flags);
  246.                         break;
  247.                 case kw_union:
  248.                         getsym();
  249.                         declstruct(bt_union,flags);
  250.                         break;
  251.                                 case kw_class:
  252.                                                 getsym();
  253.                                                 declclass(flags);
  254.                                                 break;
  255.                 }
  256.     head->cflags |= flags;
  257.     head->uflags |= UF_CANASSIGN;
  258. }
  259.  
  260. void decl1(void)
  261. {       TYP     *temp1, *temp2, *temp3, *temp4;
  262.                 SYM *sp;
  263.                 int oldinclass;
  264. lp:
  265.         switch (lastst) {
  266.                                 case kw_const:
  267.                                     head->cflags |= DF_CONST;
  268.                                     getsym();
  269.                                     goto lp;
  270.                                 case kw_volatile:
  271.                                     head->cflags |= DF_VOL;
  272.                                     getsym();
  273.                                     goto lp;
  274.                 case id:
  275.                                                 oldinclass = inclass;
  276.                                                 strcpy(declid,lastid);
  277.                         getsym();
  278.                                                 if (prm_cplusplus && lastst == classsel) {
  279.                                                     inclass |= PF_CLASSFUNC | PF_CLASSHEAD;
  280.                                                     if (!(oldinclass & PF_CLASSFUNC)) {
  281.                                                         lastdeclclass = declclass;
  282.                                                         strcpy(declclass,declid);
  283.                                                     }
  284.                                                     sp = gsearch(declid);
  285.                                                     if (!(oldinclass & PF_CLASSFUNC)) {
  286.                                                         classdecltab = sp;
  287.                                                     }
  288.                                                     getsym();
  289.                                                     do {
  290.                                                         strcat(declclass,"@");
  291.                                   if (!sp)
  292.                                                             generror(ERR_SYMUNDEF);
  293.                                                         else
  294.                                                             if (sp->tp->type != bt_iclass && sp->tp->type != bt_struct)
  295.                                                                 generror(ERR_CLASSEXPECT,0,0);
  296.                                                             else
  297.                                                                 if (lastst == not) {
  298.                                                                     getsym();
  299.                                                                     memmove(lastid+1,lastid,strlen(lastid)+1)
  300.                                                                     lastid[0] = '~';
  301.                                                                     break;
  302.                                                                 }
  303.                                                                 if (lastst != id)
  304.                                                                     generror(ERR_IDEXPECT,0,0);
  305.                                                                 else {
  306.                                                                     strcat(declid,lastid);
  307.                                                                     getsym();
  308.                                                                     if (lastst == classsel) {
  309.                                                                         sp = search(declid,&sp->tp->lst);
  310.                                                                         if (!(oldinclass & PF_CLASSFUNC)) {
  311.                                                                             classdecltab = sp;
  312.                                                                             lastdeclclass = declclass+strlen(declclass);
  313.                                                                             strcat(declclass,declid);
  314.                                                                         }
  315.                                                                     }
  316.                                                                 }
  317.                                                     } while(lastst == classsel);
  318.                                                     if (oldinclass & PF_CLASSFUNC)    
  319.                                                         gensymerror(ERR_NOTYPEQUAL,declid);
  320.                                                     else
  321.                                                         if (!checktype(sp->tp,head))
  322.                                                             gennmismatcherror(sp->tp,head);
  323.                                                 }
  324.                         decl2();
  325.                         break;
  326.                                 case and:
  327.                                                 getsym();
  328.                                                 if (prm_cplusplus) {
  329.                                                     decl1();
  330.                                                     if (head->type == bt_ref || head->type == bt_pointer)
  331.                                                         generror(ERR_CANTREF,0,0);
  332.                                                     else {
  333.                                                         temp1 = maketype(bt_ref,4);
  334.                                                         temp1->btp = head;
  335.                                                         head = temp1;
  336.                                                         if (tail == NULL)
  337.                                                             tail = head;
  338.                                                     }
  339.                                                 }
  340.                                                 else generror(ERR_NOREF,0,0);
  341.                                                 break;
  342.                 case star:
  343.                                                 head->uflags &= ~UF_CANASSIGN;
  344.                         temp1 = maketype(bt_pointer,4);
  345.                         temp1->btp = head;
  346.                         head = temp1;
  347.                                                 head->uflags |= UF_CANASSIGN;
  348.                         if(tail == NULL)
  349.                                 tail = head;
  350.                         getsym();
  351.                         decl1();
  352.                         break;
  353.                 case openpa:
  354.                         getsym();
  355.                           temp1 = head;
  356.                           temp2 = tail;
  357.                                                 if (lastst == star) {
  358.                                                     getsym();
  359.                                                      if (lastst != id && lastst != closepa)
  360.                                                         generror(ERR_IDEXPECT,0,skm_declclosepa);
  361.                                                     else {
  362.                                                         temp2 = head;
  363.                                   head = tail = maketype(bt_ptrfunc,4);
  364.                                   head->btp = temp2;
  365.                                                         if (lastst == id) {
  366.                                                             strcpy(declid,lastid);
  367.                                                             head->sname = declid;
  368.                                                             getsym();
  369.                                                             decl2();
  370.                                                         }
  371.                                                         if (needpunc(closepa,skm_declclosepa)) {
  372.                                                             char temp[40];
  373.                                                             strcpy(temp,declid);
  374.                                                             if (head->type == bt_func) {
  375.                                                                 declid[0] = 0;
  376.                                                                 temp1 = head;
  377.                                                                 head = head->btp;
  378.                                                             }
  379.                                                             else
  380.                                                                 temp1 = 0;
  381.                                                           if (needpunc(openpa,skm_declopenpa)) {
  382.                                                                 declfuncarg();
  383.                                                             }
  384.                                                             if (temp1) {
  385.                                                                 strcpy(declid,temp);
  386.                                                                 temp1->btp = head;
  387.                                                                 head = temp1;
  388.                                                             }
  389.                                                             if (lastst == begin) {
  390.                                                                 temp1->type = bt_ifunc;
  391.                                                                 break;
  392.                                                             }
  393.                                                         }
  394.                                                         else getsym();
  395.                                                     }
  396.                                                     
  397.                                                 }
  398.                                                 else {
  399.                               head = tail = NULL;
  400.                             decl1();
  401.                             needpunc(closepa,0);
  402.                             temp3 = head;
  403.                             temp4 = tail;
  404.                             head = temp1;
  405.                             tail = temp2;
  406.                             decl2();
  407.                             temp4->btp = head;
  408.                             if(temp4->type == bt_pointer &&
  409.                                     temp4->val_flag != 0 && head != NULL)
  410.                                     temp4->size *= head->size;
  411.                             head = temp3;
  412.                                                 }
  413.                         break;
  414.                 default:
  415.                         decl2();
  416.                         break;
  417.                 }
  418. }
  419.  
  420. void decl2(void)
  421. {       TYP     *temp1;
  422. lp:
  423.         switch (lastst) {
  424.                                 case kw_const:
  425.                                     head->cflags |= DF_CONST;
  426.                                     getsym();
  427.                                     goto lp;
  428.                                 case kw_volatile:
  429.                                     head->cflags |= DF_VOL;
  430.                                     getsym();
  431.                                     goto lp;
  432.                 case openbr:
  433.                                                 decl3();
  434.                                                 decl2();
  435.                         break;
  436.                 case openpa:
  437.                         getsym();
  438.                                                 if (head->type == bt_iclass) {
  439.                                                     break;
  440.                                                 }
  441.                                                 else {
  442.                             temp1 = maketype(bt_func,0);
  443.                                                     head->uflags |= UF_DEFINED;
  444.                             temp1->val_flag = 1;
  445.                             temp1->btp = head;
  446.                             head = temp1;
  447.                                                     head->uflags |= UF_DEFINED;
  448.                                                     declfuncarg();
  449.                                                     if (lastst == begin) {
  450.                                                         temp1->type = bt_ifunc;
  451.                                                         break;
  452.                                                     }
  453.                                                 }
  454.                         break;
  455.                                 case colon:
  456.                                         getsym();
  457.                                         if (head->type != bt_long && head->type != bt_unsigned
  458.                                                 && head->type != bt_short && head->type != bt_unsignedshort
  459.                                                 && head->type != bt_char && head->type != bt_unsignedchar)
  460.                                             generror(ERR_BFTYPE,0,0);
  461.                                         head->bits = intexpr(0);
  462.                                         break;
  463.                 }
  464. }
  465.  
  466. void decl3(void)
  467. {
  468.   TYP *temp1, *list[40];
  469.     int count = 0,i;
  470.     head->uflags |= UF_DEFINED;
  471.     head->uflags &= ~UF_CANASSIGN;
  472.     while(lastst == openbr) {
  473.                         getsym();
  474.                         temp1 = maketype(bt_pointer,0);  
  475.                         temp1->val_flag = 1;
  476.                                                 temp1->cflags = head->cflags &~DF_AUTOREG;
  477.                         if(lastst == closebr) {
  478.                                 temp1->size = 0;
  479.                                 getsym();
  480.                                 }
  481.                         else {
  482.                                 temp1->size = intexpr(0);
  483.                                 needpunc(closebr,skm_declclosebr);
  484.                                 }
  485.                                                 list[count++] = temp1;
  486.     }
  487.     if (head != NULL) {
  488.         list[count-1]->size *= head->size;
  489.         if (tail == NULL)
  490.             tail = head;
  491.     }
  492.     for (i=count-1; i>0; i--) {
  493.         list[i-1]->size *= list[i]->size;
  494.         list[count-1]->uflags |= UF_DEFINED;
  495.     }
  496.  
  497.     for (i=0; i < count-1; i++)
  498.         list[i]->btp = list[i+1];
  499.     list[count-1]->btp = head;
  500.  
  501.     head = list[0];
  502.     if (tail == NULL)
  503.         tail = list[count-1];
  504. }
  505. int     alignment(TYP *tp)
  506. {       switch(tp->type) {
  507.                 case bt_char: case bt_unsignedchar:  return AL_CHAR;
  508.                 case bt_short: case bt_unsignedshort: return AL_SHORT;
  509.                 case bt_long: case bt_unsigned: return AL_LONG;
  510.                 case bt_enum:           return AL_SHORT;
  511.                 case bt_pointer:
  512.                                 case bt_matchall:
  513.                         if(tp->val_flag)
  514.                                 return alignment(tp->btp);
  515.                         else
  516.                                 return AL_POINTER;
  517.                 case bt_float:          return AL_FLOAT;
  518.                 case bt_double:         return AL_DOUBLE;
  519.                                 case bt_longdouble:                return AL_LONGDOUBLE;
  520.                 case bt_struct:
  521.                 case bt_union:          return AL_STRUCT;
  522.                 default:                return AL_CHAR;
  523.                 }
  524. }
  525. int bitsize(int type)
  526. {
  527.     switch (type) {
  528.         case bt_char:
  529.         case bt_unsignedchar:
  530.             return 8;
  531.         case bt_short:
  532.         case bt_unsignedshort:
  533.             return 16;
  534.         case bt_long:
  535.         case bt_unsigned:
  536.             return 32;
  537.     }
  538.     return 0;
  539. }
  540. int     basedeclare(TABLE *table,int al,long ilc,int ztype, int flags)
  541. /*
  542.  *      process declarations of the form:
  543.  *
  544.  *              <type>  <decl>, <decl>...;
  545.  *
  546.  *      leaves the declarations in the symbol table pointed to by
  547.  *      table and returns the number of bytes declared. al is the
  548.  *      allocation type to assign, ilc is the initial location
  549.  *      counter. if al is sc_member then no initialization will
  550.  *      be processed. ztype should be bt_struct for normal and in
  551.  *      structure declarations and sc_union for in union declarations.
  552.  */
  553. {       SYM     *sp=0, *sp1;
  554.                 long *ilcp;
  555.         TYP     *dhead;
  556.         int     nbytes,*nbp,bssbytes,ufsave,isclass;
  557.         nbytes = 0;
  558.         dhead = head;
  559.                 ufsave = head->uflags;
  560.                 bssbytes = 0;
  561.         for(;;) {
  562. #ifdef i386
  563.                                 if (al == sc_abs)
  564.                                     al = sc_global;
  565. #endif
  566.                                 isclass = 0;
  567.                                 sp1 = 0;
  568.                 declid[0] = 0;
  569.                 decl1();
  570.                                 if (declid[0] == 0) {
  571.                                     if ((flags & DF_FUNCPARMS)) {
  572.                                         sprintf(declid,"**ARG%d**",pcount++);
  573.                                     }
  574.                                 }
  575.                 if( declid[0] != 0) {      /* otherwise just struct tag... */
  576.                     sp = xalloc(sizeof(SYM));
  577.                                         if (head->type == bt_func || head->type == bt_ifunc)
  578.                                             if (prm_cplusplus)
  579.                                                 if (!strcmp(declid,"main")) {
  580.                                                     SYM *sp1;
  581.                                                     head->sname = sp->name = litlate(declid);
  582.                                                     sp1 = search(sp->name,&gsyms);
  583.                                                     if (sp1 && sp1->tp->type == bt_ifunc)
  584.                                                         generror(ERR_NOOVERMAIN,0,0);
  585.                                                 }
  586.                                                 else if (mangleflag)
  587.                                                     head->sname = sp->name = cppmangle(declid,lastclass,head);
  588.                                                 else
  589.                                                     head->sname = sp->name = litlate(declid);
  590.                                             else 
  591.                                                 head->sname = sp->name = litlate(declid);
  592.                                         else
  593.                                             sp->name = litlate(declid);
  594.                                         sp->defalt = 0;
  595.                     sp->storage_class = al;
  596.                     sp->tp = head;
  597.                                         sp->extflag = FALSE;
  598.                                         sp->absflag = (al == sc_abs);
  599.                                         sp->intflag = flags &DF_INT;
  600.                                         if (al == sc_autoreg) {
  601.                                             if (head->size > 4) {
  602.                                                 sp->storage_class = sc_auto;
  603.                                                 gensymerror(ERR_ILLREGISTER,sp->name);
  604.                                             }
  605.                                             head->sname = sp->name;
  606.                                         }    
  607.                                         if (al != sc_type) {
  608.                                             if (!(flags & DF_GLOBAL) || sp->tp->type == bt_func || sp->tp->type == bt_ifunc) {
  609.                                                 nbp = &nbytes;
  610.                                                 ilcp = &ilc;
  611.                                             }
  612.                                             else {
  613.                                                 if (lastst != assign && prm_bss) {
  614.                                                     nbp = &bssbytes;
  615.                                                     ilcp = &lc_bss;
  616.                                                     bssseg();
  617.                                                 }
  618.                                                 else {
  619.                                                     nbp = &nbytes;
  620.                                                     ilcp = &ilc;
  621.                                                     dseg();
  622.                                                 }
  623.                                                 nl();
  624.                                             }
  625.                                             sp->addr = *ilcp;
  626.                                             if (al != sc_member || head->bits == -1 || bittype != head->type || head->bits +curbit > bitsize(head->type)) {
  627.                                                 int align=alignment(head);
  628.                                                 if (al != sc_auto) {
  629. #ifdef i386
  630.                                                     if (prm_packing)
  631.                                                         align = 1;
  632. #else
  633.                                                     if (prm_packing) 
  634.                                                         if (!prm_68020)
  635.                                                             align = 1;
  636.                                                         else
  637.                                                             if (align > 2) align = 2;
  638. #endif
  639.                                                 }
  640.                                                 bittype = head->type;
  641.                                                 curbit = 0;
  642.                            while( (*ilcp + *nbp) % align) {
  643.                                 if( al != sc_member &&
  644.                                         al != sc_external &&
  645.                                         al != sc_auto && al != sc_autoreg 
  646.                                                                                 && al != sc_memberreg && al != sc_abs) {
  647.                                         genbyte(0);
  648.                                                                                 nl();
  649.                                         }
  650.                                 ++(*nbp);
  651.                                 }
  652.                                                 curofs = *ilcp+*nbp;
  653.                         if( al != sc_static)
  654.                             if( ztype == bt_union)
  655.                                 sp->value.i = *ilcp;
  656.                             else if( al != sc_auto && al != sc_autoreg)
  657.                                 sp->value.i = *ilcp + *nbp;
  658.                             else
  659.                                 sp->value.i = -(*ilcp + *nbp + head->size);
  660.                         if(ztype == bt_union)
  661.                               *nbp = imax(*nbp,sp->tp->size);
  662.                         else if(al != sc_external)
  663.                               *nbp += sp->tp->size;
  664.                                             }
  665.                                             if (head->bits != -1) {
  666.                                                 if (al != sc_member || head->bits +curbit > bitsize(head->type)) {
  667.                                                     generror(ERR_BFILLEGAL,0,0);
  668.                                                     head->bits = -1;
  669.                                                 }
  670.                                                 else {
  671.                                                     sp->value.i = curofs;
  672.                                                     if (prm_revbits)
  673.                                                         head->startbit = head->size*8-curbit-head->bits;
  674.                                                     else
  675.                                                         head->startbit = curbit;
  676.                                                     curbit+=head->bits;
  677.                                                 }
  678.                                             }
  679.                                             if (sp->absflag &&( sp->tp->type == bt_func || sp->tp->type == bt_ifunc))
  680.                                                 gensymerror(ERR_ILLCLASS,lastid);
  681.                                             if (sp->intflag &&( sp->tp->type != bt_func && sp->tp->type != bt_ifunc))
  682.                                                 gensymerror(ERR_ILLCLASS,lastid);
  683.                       if( sp->tp->type == bt_func && 
  684.                             sp->storage_class == sc_global || sp->storage_class == sc_member)
  685. #ifndef i386          
  686.                             sp->storage_class = sc_external;
  687. #else                 
  688.                             sp->storage_class = sc_externalfunc;
  689. #endif
  690.                                             
  691.                                             if (inclass & PF_CLASSDEF) {
  692.                                                 if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc) [
  693.                                                     if (currentfunc) {
  694.                                                         generror(ERR_LOCALCLASS,0,0);
  695.                                                     }
  696.                                                     if (inclass & PF_VIRTUAL)
  697.                                                         sp->defalt = litlate(lastclass);
  698.                                                 }
  699.                                             }
  700.                                             if (inclass & PF_CLASSHEAD) {
  701.                                                 inclass = 1;
  702.                                                 sp1 = search(sp->name,classdecltab);
  703.                                                 if (al == sc_static)
  704.                                                     generror(ERR_ILLCLASS,0,0);
  705.                                                 if (sp1->pflags & PF_STATIC)
  706.                                                     al = sc_static;
  707.                                                 else
  708.                                                     al = sc_global;
  709.                                                 goto join;
  710.                                             }
  711.                                             else {
  712.                                               sp1 = search(sp->name,table);
  713.                                                 if (sp->name[0] == '@' && !sp1)
  714.                                                     funcrefinsert(declid,sp->name,head,table);
  715.                                             }
  716.                          if (!sp1 || (sp1->tp->type != bt_func && sp1->tp->type != bt_ifunc && sp1->tp->type != bt_class && sp1->tp->type != bt_iclass)) {
  717.                                                 if (!sp1 || (al != sc_external && sp1->storage_class != sc_externalfunc&& sp1->storage_class != sc_external) 
  718.                                                     || ((al==sc_external || sp1->storage_class == sc_externalfunc || sp1->storage_class == sc_external) && !checktype(sp->tp,sp1->tp)))
  719.                              insert(sp,table);                                                                       
  720.                                                 else
  721.                                                     if (sp1->storage_class == sc_external || sp1->storage_class == sc_externalfunc) {
  722.                                                         sp1->storage_class = sp->storage_class;
  723.                                                         sp1->tp = sp->tp;
  724.                                                         sp1->value.i = sp->value.i;
  725.                                                     }
  726.                                             }
  727.                                             else 
  728. join:
  729.                                             if (sp1->tp->type == bt_func && sp->tp->type == bt_ifunc){
  730.                                                 if (sp1->storage_class == sc_external || sp1->storage_class == sc_externalfunc)
  731.                                                     sp1->storage_class = sc_global;
  732.                                             }
  733.                                             else if (sp1->tp->type == bt_class && sp1->tp->type == bt_iclass) {
  734.                                                 if (sp1->storage_class == sc_external || sp1->storage_class == sc_externalfunc)
  735.                                                     sp1->storage_class = sc_global;
  736.                                                 sp1->tp = sp->tp;
  737.                                             }    
  738.                          if( sp->tp->type == bt_ifunc) { /* function body follows */
  739.                                                          sp1->tp->type = bt_ifunc;
  740.                              funcbody(sp);
  741.                                                          lc_bss += bssbytes;
  742.                                                          lastdecl = sp1;
  743.                              return nbytes;
  744.                              }
  745.                          if( (al == sc_global || al == sc_static) &&
  746.                                sp->tp->type != bt_func && sp->tp->type != bt_ifunc
  747.                                                         && !(flags & DF_FUNCPARMS)) {
  748.                                                     if (sp->tp->type == bt_ref && lastst != assign)
  749.                                                         gensymerror(ERR_REFMUSTINIT,lastid);
  750.                           doinit(sp);
  751.                                             }
  752.                                             else 
  753.                                                 if (al == sc_auto || al == sc_autoreg) {
  754.                                                     if (prm_cplusplus &&(flags & DF_FUNCPARMS)) {
  755.                                                         dodefaultinit(sp);
  756.                                                     }
  757.                                                     else{
  758.                                                         if (sp->tp->type == bt_ref && lastst != assign)
  759.                                                             gensymerror(ERR_REFMUSTINIT,lastid);
  760.                                                     }
  761.                                                      doautoinit(sp);
  762.                                                 }
  763.                                         }
  764.                                         else if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc) {
  765.                                                         gensymerror(ERR_ILLTYPE,declid);
  766.                                                         expskim(skm_declclosepa);
  767.                                                     }
  768.                                                     else {
  769.                                                         sp->tp = copytype(sp->tp,0);
  770.                                                         sp->tp->sname = sp->name;
  771.                             insert(sp,table);
  772.                                                     }
  773.                 }
  774.                                 if (!(flags & DF_FUNCPARMS)) {
  775.                                     if (inclass &(PF_VIRTUAL | PF_CLASSDEF) == (PF_VIRTUAL | PF_CLASSDEF))
  776.                                         if (lastst == assign) {
  777.                                             inclass |= PF_PURE;
  778.                                             getsym();
  779.                                             if (lastst != iconst || lastint != 0)
  780.                                                 gensymerror(ERR_PUREDECL,sp->name);
  781.                                             }
  782.                                         }
  783.                     if(lastst == semicolon)
  784.                         break;
  785.                                     dhead = copytype(dhead,0);
  786.                     needpunc(comma,0);
  787.                                 }
  788.                                 else {
  789.                     if(lastst == comma)
  790.                                         break;
  791.                                     lc_bss += bssbytes;
  792.                                     if (sp1)
  793.                                         lastdecl = sp1;
  794.                                     else
  795.                                         lastdecl = sp;
  796.                   return(nbytes);
  797.                                 }
  798.                 if(declbegin(lastst) == 0)
  799.                         break;
  800.                 head = dhead;
  801.                                 head->uflags = ufsave;
  802.                 }
  803.         getsym();
  804.                 lc_bss += bssbytes;
  805.                 if (sp1)
  806.                     lastdecl = sp1;
  807.                 else
  808.                     lastdecl = sp;
  809.         return nbytes;
  810. }
  811. int     declare(TABLE *table,int al,long ilc,int ztype, int flags)
  812. /*
  813.  *      process declarations of the form:
  814.  *
  815.  *              <type>  <decl>, <decl>...;
  816.  *
  817.  *      leaves the declarations in the symbol table pointed to by
  818.  *      table and returns the number of bytes declared. al is the
  819.  *      allocation type to assign, ilc is the initial location
  820.  *      counter. if al is sc_member then no initialization will
  821.  *      be processed. ztype should be bt_struct for normal and in
  822.  *      structure declarations and sc_union for in union declarations.
  823.  */
  824. {
  825.         decl(table,flags);
  826.                 return(basedeclare(table,al,ilc,ztype,flags));
  827. }
  828. int     declare2(SYM *sp, TABLE *table,int al,long ilc,int ztype, int flags)
  829. /*
  830.  *      process declarations of the form:
  831.  *
  832.  *              <type>  <decl>, <decl>...;
  833.  *
  834.  *      leaves the declarations in the symbol table pointed to by
  835.  *      table and returns the number of bytes declared. al is the
  836.  *      allocation type to assign, ilc is the initial location
  837.  *      counter. if al is sc_member then no initialization will
  838.  *      be processed. ztype should be bt_struct for normal and in
  839.  *      structure declarations and sc_union for in union declarations.
  840.  */
  841. {
  842.                 tail = head = sp->tp;
  843.                 if (tail)
  844.                     while (tail->btp)
  845.                         tail = tail->btp;
  846.                 getsym();
  847.                 return(basedeclare(table,al,ilc,ztype,flags));
  848. }
  849.  
  850. int     declbegin(int st)
  851. {       return st == star || st == id || st == openpa ||
  852.                 st == openbr;
  853. }
  854.  
  855. void declenum(TABLE *table)
  856. {       SYM     *sp;
  857.         TYP     *tp;
  858.                 char *nm;
  859.         if( lastst == id) {
  860.                 if((sp = search(nm = litlate(lastid),&tagtable)) == 0) {
  861.                         sp = xalloc(sizeof(SYM));
  862.                         sp->tp = xalloc(sizeof(TYP));
  863.                         sp->tp->type = bt_enum;
  864.                         sp->tp->size = 2;
  865.                         sp->tp->lst.head = sp->tp->btp = 0;
  866.                         sp->storage_class = sc_type;
  867.                         sp->name = nm;
  868.                         sp->tp->sname = sp->name;
  869.                                                 sp->tp->bits = sp->tp->startbit = -1;
  870.                         getsym();
  871.                         if( lastst != begin)
  872.                                 generror(ERR_PUNCT,begin,skm_declend);
  873.                         else    {
  874.                                 insert(sp,&tagtable);
  875.                                 getsym();
  876.                                 enumbody(table);
  877.                                 }
  878.                         }
  879.                 else
  880.                         getsym();
  881.                 head = sp->tp;
  882.                 }
  883.         else    {
  884.                 tp = xalloc(sizeof(TYP));
  885.                 tp->type = bt_enum;
  886.                 tp->lst.head = tp->btp = 0;
  887.                                 tp->size = 2;
  888.                                 tp->bits = tp->startbit = -1;
  889.                                 tp->sname = 0;
  890.                 if( lastst != begin)
  891.                         generror(ERR_PUNCT,begin,skm_declend);
  892.                 else    {
  893.                         getsym();
  894.                         enumbody(table);
  895.                         }
  896.                 head = tp;
  897.                 }
  898. }
  899.  
  900. void enumbody(TABLE *table)
  901. {       int     evalue;
  902.         SYM     *sp;
  903.         evalue = 0;
  904.         while(lastst == id) {
  905.                 sp = xalloc(sizeof(SYM));
  906.                 sp->value.i = evalue++;
  907.                 sp->name = litlate(lastid);
  908.                 sp->storage_class = sc_const;
  909.                 sp->tp = &stdconst;
  910.                 insert(sp,table);
  911.                 getsym();
  912.                                 if (lastst == assign) {
  913.                                         getsym();
  914.                                         evalue = sp->value.i = intexpr(0);
  915.                                         evalue++;
  916.                                 }
  917.                 if( lastst == comma)
  918.                         getsym();
  919.                 else if(lastst != end)
  920.                         break;
  921.                 }
  922.         needpunc(end,skm_declend);
  923. }
  924.  
  925. void declstruct(int ztype, int flags)
  926. /*
  927.  *      declare a structure or union type. ztype should be either
  928.  *      bt_struct or bt_union.
  929.  */
  930. {       SYM     *sp;
  931.         TYP     *tp;
  932.                 char *nm = litlate(lastid);
  933.         if(lastst == id) {
  934.                 if((sp = search(nm,&tagtable)) == 0) {
  935.                         sp = xalloc(sizeof(SYM));
  936.                         sp->name = nm;
  937.                         sp->tp = xalloc(sizeof(TYP));
  938.                         sp->tp->type = ztype;
  939.                         sp->tp->lst.head = 0;
  940.                         sp->storage_class = sc_type;
  941.                         sp->tp->sname = sp->name;
  942.                                                 sp->tp->cflags = flags;
  943.                                                 sp->tp->uflags = UF_DEFINED;
  944.                         getsym();
  945.                         if(lastst != begin)
  946.                                         generror(ERR_PUNCT,begin,skm_declend);
  947.                         else    {
  948.                                 insert(sp,&tagtable);
  949.                                 getsym();
  950.                                 structbody(sp->tp,sp->name,ztype);
  951.                                 }
  952.                         }
  953.                 else
  954.                         getsym();
  955.                                 if (flags & (DF_CONST | DF_VOL))
  956.                                     head = copytype(sp->tp,flags);
  957.                                 else
  958.                     head = sp->tp;
  959.                                 head->bits = head->startbit = -1;
  960.                 }
  961.         else    {
  962.                 tp = xalloc(sizeof(TYP));
  963.                 tp->type = ztype;
  964.                                 tp->cflags = flags;
  965.                                 tp->uflags = UF_DEFINED;
  966.                 tp->sname = 0;
  967.                 tp->lst.head = 0;
  968.                                 tp->bits = tp->startbit =-1;
  969.                 if( lastst != begin)
  970.                            generror(ERR_PUNCT,begin,skm_declend);
  971.                 else    {
  972.                         getsym();
  973.                         structbody(tp,tn_unnamed,ztype);
  974.                         }
  975.                 head = tp;
  976.                 }
  977. }
  978.  
  979. void structbody(TYP *tp,char  *name,int ztype)
  980. {       int     slc;
  981.                 char **sp;
  982.         slc = 0;
  983.         tp->val_flag = 1;
  984.                 head->uflags &= ~UF_CANASSIGN;
  985.         while( lastst != end) {
  986.                                 int flags=0;
  987.                                 while (lastst == kw_const || lastst == kw_volatile) {
  988.                                     if (lastst == kw_const)
  989.                                         flags |= DF_CONST;
  990.                                     else
  991.                                         flags |= DF_VOL;
  992.                                     getsym();
  993.                                 }
  994.                                 if (tp->tbl.head)
  995.                                     sp = &tp->tbl.tail->next;
  996.                                 else
  997.                                     sp = &tp->tbl.tail;
  998.                 if(ztype == bt_struct)
  999.                         slc += declare(&tp->lst,sc_member,slc,ztype,flags);
  1000.                 else
  1001.                         slc = imax(slc,declare(&tp->lst,sc_member,0,ztype,flags));
  1002.                                 (*sp)->pflags = PF_PUBLIC;
  1003.                                 if (tp->lst.tail->tp->type == bt_ref)
  1004.                                     genclasserror(ERR_REFNOCONS,name,tp->lst.tail->name);
  1005.                                 tp->lst.tail->tp->uflags |= UF_DEFINED;
  1006.                 }
  1007.                 if (!prm_packing)
  1008.             tp->size = (slc+3)&0xfffffffcL;
  1009.                 else
  1010.                     tp->size = slc;
  1011.         getsym();
  1012. }
  1013. int declclass(int flags)
  1014. {
  1015.     int mode = PF_PRIVATE,ctype=bt_class;
  1016.     int oldinclass;
  1017.     TYP *tp;
  1018.     inherited[0] = 0
  1019.     char *oldlast;
  1020.     if (lastst != id) {
  1021.         generror(ERR_IDEXPECT,0,declend);
  1022.         declstruct(bt_struct,flags);
  1023.     }
  1024.     else {
  1025.         oldlast = lastclass;
  1026.         if (inclass & PF_CLASSDEF) {
  1027.             lastclass = newclass + strlen(newclass);
  1028.             strcat(newclass,"@");
  1029.             strcat(newclass,lastid);
  1030.         }
  1031.         else {
  1032.             strcpy(newclass,lastid);
  1033.             lastclass = newclass;
  1034.         }
  1035.         getsym();
  1036.         if (lastst == colon) {
  1037.             getsym();
  1038.             switch(lastst) {
  1039.                 case kw_public;
  1040.                     mtype = 1;
  1041.                     getsym();
  1042.                     break;
  1043.                 case kw_private;
  1044.                     mode = PF_PRIVATE;
  1045.                     getsym();
  1046.                     break;
  1047.                 case kw_protected;
  1048.                     mode = PF_PROTECTED;
  1049.                     getsym();
  1050.                     break;
  1051.             }
  1052.             if (lastst != id) 
  1053.                 generror(ERR_IDEXPECT,0,declend);
  1054.             else  {
  1055.                 strcpy(inherited,lastid);
  1056.                 getsym();
  1057.             }
  1058.         }
  1059.     tp = xalloc(sizeof(TYP));
  1060.     tp->type = bt_class;
  1061.         tp->cflags = flags;
  1062.         tp->uflags = UF_DEFINED;
  1063.     tp->sname = litlate(newclass);
  1064.     tp->lst.head = 0;
  1065.         tp->bits = tp->startbit =-1;
  1066.         oldinclass = inclass;
  1067.         inclass |= DF_CLASSDEF;
  1068.         classbody(tp,mode,inherited);
  1069.         iclass = oldinclass;
  1070.         lastclass = oldlastclass;
  1071.         lastclass[0] = 0;
  1072.         head = tp;
  1073.     }
  1074. }
  1075. void classbody(TYP *tp,int mode,char *inherited)
  1076. {       int     slc=0,vlc=0;
  1077.         tp->val_flag = 1;
  1078.                 char vname[100];
  1079.                 sprintf(vname,"@$vt$%s",newclass);
  1080.                 SYM *sp,*sp2;
  1081.                 head->uflags &= ~UF_CANASSIGN;
  1082.                 if (inherited[0]) {
  1083.                     if ((sp = search(inherited,&gsyms)) == 0 || (sp->tp != bt_struct && sp->tp != bt_iclass)) {
  1084.                         gensymerror(ERR_PREDEFSTRUCT,inherited);
  1085.                     }
  1086.                     else {
  1087.                         slc = sp->tp->size;
  1088.                         sp = sp->lst.head;
  1089.                         while (sp) {
  1090.                             sp2 = xalloc(sizeof(SYM));
  1091.                             memcpy(sp2,sp,sizeof(SYM));
  1092.                             insert(sp2,&tp->lst);
  1093.                             if (sp->pflags & PF_VIRTUAL)
  1094.                                 if (vlc == 0) {
  1095.                                     gen_virtual(vname);
  1096.                                     gen_strlab(vname);
  1097.                                 }
  1098.                                 genpcref(sp2,0);
  1099.                                 vlc = sp->v.i+4;
  1100.                             sp->pflags |= (sp->pflags & 3) > mode ? mode : sp->pflags & 3;
  1101.                             sp = sp->next;
  1102.                         }
  1103.                     }
  1104.                     tp->type = bt_iclass;
  1105.                 }
  1106.                 if (lastst == semicolon) {
  1107.                     getsym();
  1108.                     return;
  1109.                 }
  1110.                 inclass = PF_PRIVATE;
  1111.                 needpunc(begin,0);
  1112.                 inclass |= PF_CLASSDEF;
  1113.         while( lastst != end) {
  1114.                                 int flags=0;
  1115. swt:
  1116.                                 switch (lastst) {
  1117.                                     case kw_public:
  1118.                                         inclass = PF_PUBLIC;
  1119.                                         getsym();
  1120.                                         needpunc(colon,0);
  1121.                                         goto swt;
  1122.                                     case kw_private:
  1123.                                         inclass = PF_PRIVATE;
  1124.                                         getsym();
  1125.                                         needpunc(colon,0);
  1126.                                         goto swt;
  1127.                                     case kw_protected:
  1128.                                         inclass = PF_PROTECTED;
  1129.                                         getsym();
  1130.                                         needpunc(colon,0);
  1131.                                         goto swt;
  1132.                                 }
  1133. swt2:
  1134.                                 switch(lastst)
  1135.                                     case kw_inline:
  1136.                                         getsym();
  1137.                                         inclass |= PF_INLINE;
  1138.                                         goto swt2;
  1139.                                     case kw_virtual:
  1140.                                         inclass |= PF_VIRTUAL;
  1141.                                         getsym();
  1142.                                         goto swt2;
  1143.                                     case kw_static:
  1144.                                         inclass |= PF_STATIC;
  1145.                                         getsym();
  1146.                                         goto swt2;
  1147.                                 }
  1148.                                 while (lastst == kw_const || lastst == kw_volatile) {
  1149.                                     if (lastst == kw_const)
  1150.                                         flags |= DF_CONST;
  1151.                                     else
  1152.                                         flags |= DF_VOL;
  1153.                                     getsym();
  1154.                                 }
  1155.                                 if (inclass & PF_STATIC) {
  1156.                                     if ((inclass & PF_INLINE) || (inclass & PF_VIRTUAL)) {
  1157.                                         generror(ERR_ILLCLASS,0,0);
  1158.                                         inclass &= ~(PF_INLINE | PF_VIRTUAL)
  1159.                                     }
  1160.                                     lc_static +=
  1161.                                          declare(&tp->lst,sc_static,lc_static,bt_struct,flags | DF_GLOBAL);
  1162.                                 }
  1163.                                 else if (inclass & PF_VIRTUAL) {
  1164.                     declare(&tp->lst,sc_member,vlc,bt_struct,flags);
  1165.                                     if (tp->lst.tail == lastdecl) {
  1166.                                         if (vlc == 0) {
  1167.                                             gen_virtual(vname);
  1168.                                             gen_strlab(vname);
  1169.                                         }
  1170.                                         genpcref(tp->lst.tail,0);
  1171.                                         vlc +=4;
  1172.                                     }
  1173.                                 }
  1174.                                 else
  1175.                     slc += declare(&tp->lst,sc_member,slc,bt_struct,flags);
  1176.                                 if ((inclass & PF_VIRTUAL) || (inclass & PF_INLINE)) {
  1177.                                     if (lastdecl->tp->type != bt_func && lastdecl->tp->type != bt_ifunc) {
  1178.                                         generror(ERR_ILLCLASS,0,0);
  1179.                                         inclass &= ~(PF_INLINE | PF_VIRTUAL)
  1180.                                     }
  1181.                                 }
  1182.                                 if (lastdec->tp->type == bt_ifunc)
  1183.                                     inclass |= PF_INLINE;
  1184.                                 lastdecl->pflags |= inclass;
  1185.                                 inclass &= 3 | PF_INCLASS | PF_INCLASSFUNC;
  1186.                                 lastdecl->tp->uflags |= UF_DEFINED;
  1187.                 }
  1188.                 if (!prm_packing)
  1189.             tp->size = (slc+3)&0xfffffffcL;
  1190.                 else
  1191.                     tp->size = slc;
  1192.         getsym();
  1193.                 if (vlc)
  1194.                     gen_endvirtual(vname);
  1195. }
  1196. void check_used(void)
  1197. {
  1198.                 int i;
  1199.                 SYM *sp;
  1200.                     for (i=0; i < HASHTABLESIZE; i++) {
  1201.                         if ((sp=(SYM *) globalhash[i]) != 0) {
  1202.                             while (sp) {
  1203.                                 if (sp->storage_class == sc_static)
  1204.                                     if (sp->tp->type == bt_func)
  1205.                                         gensymerror(ERR_NOSTATICFUNC,sp->name);
  1206.                                     else
  1207.                                         if (!(sp->tp->uflags & UF_USED))
  1208.                                             if (sp->tp->type == bt_ifunc || sp->tp->type == bt_func)
  1209.                                                 gensymerror(ERR_FUNCUNUSED,sp->name);
  1210.                                             else
  1211.                                                 gensymerror(ERR_STATICSYMUNUSED,sp->name);
  1212.                                 sp = sp->next;
  1213.                             }
  1214.                         }
  1215.                     }
  1216. }
  1217. void compile(void)
  1218. /*
  1219.  *      main compiler routine. this routine parses all of the
  1220.  *      declarations using declare which will call funcbody as
  1221.  *      functions are encountered.
  1222.  */
  1223. {       while(lastst != eof) {
  1224.                 dodecl(sc_global);
  1225.                                 if (lastst != eof) {
  1226.                                     generror(ERR_DECLEXPECT,0,0);
  1227.                                     getsym();
  1228.                                 }
  1229.         }
  1230.                 check_used();
  1231.         dumplits();
  1232. }
  1233.  
  1234. void dodecl(int defclass)
  1235. {
  1236.                 SYM *sp;
  1237.                 int flags = 0;
  1238.                 long val;
  1239.                 char *nm;
  1240.                 cbautoinithead = 0;
  1241.     
  1242.         for(;;) {
  1243.             switch(lastst) {
  1244.                                 case kw_typedef:
  1245.                                                 getsym();
  1246.                                                 if (defclass == sc_global)
  1247.                                                     declare(&gsyms,sc_type,0,bt_struct, 0);
  1248.                                                 else
  1249.                                                     declare(&lsyms,sc_type,0,bt_struct, 0);
  1250.                                                 break;
  1251.                 case kw_register:
  1252.                         if( defclass != sc_auto || flags & DF_VOL) {
  1253.                           gensymerror(ERR_ILLCLASS,lastid);
  1254.                             getsym();
  1255.                                                 }
  1256.                                                 else  {
  1257.                             getsym();
  1258.                                 lc_auto +=
  1259.                                 declare(&lsyms,sc_autoreg,lc_auto,bt_struct,flags | DF_AUTOREG);
  1260.                                                 };
  1261.                                         break;
  1262.                                 case kw_volatile:
  1263.                                         flags |= DF_VOL;
  1264.                                         getsym();
  1265.                                         continue;
  1266.                                 case kw_const:
  1267.                                         flags |= DF_CONST;
  1268.                                         getsym();
  1269.                                         continue;
  1270.                 case id:
  1271.                                         if (defclass == sc_auto)
  1272.                                                 if (!(((sp = search(nm = litlate(lastid),&gsyms)) != 0 && sp->storage_class == sc_type)
  1273.                                                      || ((sp = search(nm,&lsyms)) != 0 && sp->storage_class == sc_type)))
  1274.                                                     return;
  1275.                 case kw_char: case kw_int: case kw_short: case kw_unsigned:
  1276.                 case kw_long: case kw_struct: case kw_union: case kw_signed:
  1277.                 case kw_enum: case kw_void:
  1278.                 case kw_float: case kw_double:
  1279.                     if( defclass == sc_global)
  1280.                         lc_static +=
  1281.                             declare(&gsyms,sc_global,lc_static,bt_struct,flags | DF_GLOBAL);
  1282.                     else if( defclass == sc_auto)
  1283.                         lc_auto +=
  1284.                             declare(&lsyms,sc_auto,lc_auto,bt_struct,flags);
  1285.                     else
  1286.                         declare(&lsyms,sc_auto,0,bt_struct,flags);
  1287.                     break;
  1288.                 case kw_static:
  1289.                         if( defclass == sc_member) {
  1290.                            gensymerror(ERR_ILLCLASS,lastid);
  1291.                                                         getsym();
  1292.                                                         break;
  1293.                                                 }
  1294.                                                 getsym();
  1295.                                                 if( defclass == sc_auto)
  1296.                                                     lc_static += 
  1297.                                                         declare(&lsyms,sc_static,lc_static,bt_struct,flags | DF_GLOBAL);
  1298.                                                 else
  1299.                                                     lc_static +=
  1300.                                                         declare(&gsyms,sc_static,lc_static,bt_struct,flags | DF_GLOBAL);
  1301.                         break;
  1302.                 case kw_extern: {
  1303.                                                 int thismangle = FALSE;
  1304.                         getsym();
  1305.                                                 if (prm_cplusplus && lastst == sconst) {
  1306.                                                     if (!strcmp(laststr,Cstr)) {
  1307.                                                         mangleflag = FALSE;
  1308.                                                         manglelevel++;
  1309.                                                         getsym();
  1310.                                                         if (lastst == begin) {
  1311.                                                             getsym();
  1312.                                                           thismangle = FALSE;
  1313.                                                         }
  1314.                                                         else thismangle = TRUE;
  1315.                                                     }
  1316.                                                 }
  1317.                         if( defclass == sc_member) {
  1318.                             gensymerror(ERR_ILLCLASS,lastid);
  1319.                                                         break;
  1320.                                                 }
  1321.                         ++global_flag;
  1322.                         declare(&gsyms,sc_external,0,bt_struct,flags);
  1323.                         --global_flag;
  1324.                                                 if (thismangle && !--manglelevel)
  1325.                                                     mangleflag = TRUE;
  1326.                                                 }
  1327.                         break;
  1328.                                 case end:
  1329.                                                 if (prm_cplusplus && manglelevel) {
  1330.                                                     mangleflag = (!--manglelevel);
  1331.                                                     getsym();
  1332.                                                     continue;
  1333.                                                 }
  1334.                                                 return;
  1335.                                 case kw__interrupt:
  1336.                                                 flags |= DF_INT;
  1337.                                                 getsym();
  1338.                                                 continue;
  1339.                                 case kw__abs:
  1340.                                                 ++global_flag;
  1341.                                                 getsym();
  1342.                                                 if (lastst != openpa) {
  1343.                                                     generror(ERR_PUNCT,openpa,0);
  1344.                                                 }
  1345.                                                 else {
  1346.                                                     getsym();
  1347.                                                     val = intexpr(0);
  1348.                                                     if (lastst != closepa)
  1349.                                                         generror(ERR_PUNCT,closepa,skm_declclosepa);
  1350.                                                 }
  1351.                                                 getsym();
  1352.                                                 declare(&gsyms,sc_abs,val,bt_struct,flags);
  1353.                                                 --global_flag;
  1354.                                                 break;
  1355.                 default:
  1356.                         return;
  1357.                 }
  1358.                         flags = 0;
  1359.             }
  1360. }
  1361. void doargdecl(int defclass, char *names[], int *nparms, TABLE *table, int inline)
  1362. {
  1363.                 SYM *sp;
  1364.                 int flags = inline ? DF_FUNCPARMS : 0;
  1365.         for(;;) {
  1366.             switch(lastst) {
  1367.                                 case kw_const:
  1368.                                     flags |= DF_CONST;
  1369.                                     getsym();
  1370.                                     continue;
  1371.                                 case ellipse: {
  1372.                                     sprintf(declid,"**ELLIPSE%d**",pcount++);
  1373.                                     sp = xalloc(sizeof(SYM));
  1374.                                     sp->name = litlate(declid);
  1375.                   sp->storage_class = sc_auto;
  1376.                                     sp->tp = maketype(bt_ellipse,0);
  1377.                                     sp->tp->uflags |= UF_DEFINED | UF_USED;
  1378.                                     insert(sp,table);
  1379.                                     getsym();
  1380.                                     goto exit;
  1381.                                 }
  1382.                                 case id:
  1383.                 case kw_char: case kw_int: case kw_short: case kw_unsigned:
  1384.                 case kw_long: case kw_struct: case kw_union: case kw_signed:
  1385.                 case kw_enum: case kw_void:
  1386.                 case kw_float: case kw_double:
  1387.                     declare(table,sc_auto,0,bt_struct,flags);
  1388.                     break;
  1389.                 case kw_static:
  1390.                                 case kw_auto:
  1391.                                 case kw_register:
  1392.                         gensymerror(ERR_ILLCLASS,lastid);
  1393.                         getsym();
  1394.                                                 continue;
  1395.                 default:
  1396.                                                 goto exit;
  1397.                 }
  1398.                             if (inline) {
  1399.                                 names[(*nparms)++] = litlate(declid);
  1400.                             }
  1401.                         
  1402.                 flags &= ~DF_CONST;
  1403.                 }
  1404. exit:
  1405.         if (prm_cplusplus) {
  1406.             SYM *sp = table->head;
  1407.             int found = FALSE;
  1408.             while (sp) {
  1409.                 if (sp->defalt)
  1410.                     found = TRUE;
  1411.                 else 
  1412.                     if (found)
  1413.                         gensymerror(ERR_MISSINGDEFAULT,sp->name);
  1414.                 sp = sp->next;
  1415.             }
  1416.         }
  1417. }