home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 357_01 / cstar1.exe / DCL.C < prev    next >
C/C++ Source or Header  |  1991-06-18  |  60KB  |  2,313 lines

  1. /*
  2.     C* -- Parser Part II (declarations)
  3.  
  4.     Source:  dcl.c
  5.     Started: October 21, 1985
  6.     Version:
  7.         March 4, 1987;
  8.         February 25, 1989: New Sherlock macros added.
  9.  
  10.     PUBLIC DOMAIN SOFTWARE
  11.  
  12.     The CSTAR program was placed in    the public domain on June 15, 1991,
  13.     by its author and sole owner,
  14.  
  15.         Edward K. Ream
  16.         1617 Monroe Street
  17.         Madison, WI 53711
  18.         (608) 257-0802
  19.  
  20.     CSTAR may be used for any commercial or non-commercial purpose.
  21.  
  22.     See cstar.h or cstar.c for a DISCLAIMER OF WARRANTIES.
  23. */
  24. #include "cstar.h"
  25.  
  26. /*
  27.     WARNING: according to the C Journal, Winter 1987, p.58, const and
  28.     volatile don't stick to structure tags.  Our copy of the draft
  29.     standard is silent on this arcane point.  Use #define SC_STICKY 0
  30.     to implement them that way, and use 1 to implement them as pure
  31.     type adjectives which behave cumulatively.
  32.  
  33.     WARNING: pd_taeq and pd_teq: it is not clear whether structures
  34.     having the same tag (and which are therefore identical in all respects
  35.     except outer const and volatile) but differing as to outer
  36.     const or volatile should be regarded as being of the same type or as
  37.     of different types.  At present, as with const and nonconst int,
  38.     they are regarded as if they are the same type, for most purposes.
  39. */
  40. extern int reg_size[];
  41.  
  42. /*
  43.     Externally visible routines:
  44. */
  45. void    pd_tcopy    (struct type_node *s,  struct type_node *d);
  46. bool    pd_teq        (struct type_node *t1, struct type_node *t2);
  47. bool    pd_t1eq        (struct type_node *t1, struct type_node *t2);
  48. bool    pd_taeq        (struct type_node *t1, struct type_node *t2);
  49. void    reg_check    (struct type_node *type, int regtype, char *symbol);
  50. unsigned long    m_size    (int m);
  51. bool    pd_is1func    (struct type_node *t);
  52. void    pd_orphan    (struct type_node *t);
  53. struct type_node *
  54.     pd_cast        (void);
  55. struct type_node *
  56.     pd_stmt    (int kind, int plural, struct type_node **head_x);
  57.  
  58.  
  59. /*
  60.     Internal routines:
  61. */
  62. static struct type_node *
  63.     pd_head    (int kind, int * sclass);
  64. static struct type_node *
  65.     pd_tail    (int kind, struct type_node *head_type,
  66.             char ** dsymbol, int * regtype, int headclass);
  67. static struct type_node *
  68.     pd_t1        (int kind, struct type_node * head_type,
  69.             char ** dsymbol, int * regtype, int headclass);
  70. static int
  71.     pd_post    (register struct type_node *t);
  72. static struct type_node *
  73.     pd_p1        (register struct type_node *t, register int mods);
  74. static struct st_node *
  75.     pd_var    (int sclass, struct type_node *type, char * symbol);
  76. static char *    pd_name    (void);
  77. static void    pd_iniz    (struct st_node *id);
  78. static struct iblock *
  79.     pd_par        (register struct type_node *t, unsigned long size);
  80.  
  81.  
  82. /*
  83.     NOTE about const and volatile
  84.  
  85.     Handling of CONST_MOD and VOLATILE_MOD is peculiar.  See this
  86.     entire note.
  87.  
  88.     const and volatile are peculiar entities, not really storage classes,
  89.     and not really types.  Like static, volatile will typically be
  90.     a statement about the properties of a location.  However, 
  91.     syntactically and logically to a certain extent, it is treated
  92.     as a type.  One does not distinguish pointer to static int from
  93.     pointer to some other int, but one does distinguish pointer
  94.     to volatile int from pointer to int from volatile pointer to int.
  95.     (Actually, one might want to distinguish pointer to auto int
  96.     from pointer to static int, and disallow returning the former it
  97.     from a function, but let that slide.)
  98.  
  99.     In addition, const and volatile have implications for expression
  100.     checking and code generation and act in that context rather like
  101.     types, in they disallow certain operations in rather the
  102.     same manner that inappropriate types would disallow them.  With
  103.     the sole exception of address-of a register, storage classes
  104.     don't do that.
  105.  
  106.     Furthermore, const and volatile (?) propagate within aggregates,
  107.     so that if an array is const, so are its elements.  This is also
  108.     implicitly true of all other storage classes, but it has no
  109.     consequences to speak of, because those storage classes attach
  110.     to the declared object rather than to its type specification.
  111.  
  112.     Because of the other-worldly syntax of declarations, which
  113.     can't be blamed on the standards committee, a number of
  114.     bizarre facts need to be noted:
  115.  
  116.         1. a declaration like
  117.            const int ** const * x;
  118.            is possible, as is the corresponding cast.  Blame the
  119.            original syntax for suggesting this form, and the
  120.            committee for accepting the suggestion.
  121.  
  122.         2. in the declaration
  123.            const static unsigned int *x;
  124.            register describes the location where the pointer-to-integer
  125.            x is stored, but const (implicitly) describes the location
  126.            which x points to (i.e., it is to be treated like ROM),
  127.            while unsigned describes how said location (be it static,
  128.            ROM, or both) is to be regarded when used as an arithmetic
  129.            entity.  That is, one must remember which of the twenty-odd
  130.            possible descriptors gets attached to the pointer, and
  131.            which to the item pointed to, in such declarations.
  132.  
  133.         3. in full C, the useless declaration
  134.            const register x;
  135.            is syntactically possible.  Its uselessness stems from
  136.            the lack of any means to specify, either in the C code,
  137.            or through the linker, which particular register is
  138.            intended.
  139.  
  140.         4. in the declaration
  141.            const a[5];
  142.            the const attribute attaches both to a, regarded as
  143.            "the array" and to *(a+3), the latter being an array
  144.            element, since the attribute propagates to the elements
  145.            of an aggregate.
  146.            In
  147.            const *a;
  148.            the const attribute attaches to *(a+3), but not to
  149.            "the pointer" a.
  150.            Finally, in the formal
  151.            const a[];
  152.            your guess is as good as ours.  Ours is to treat it
  153.            exactly as if
  154.            const *a;
  155.            had been written.
  156.  
  157.     Within the C-Star compiler, there are a number of complex
  158.     implications.
  159.  
  160.         1. Normal storage classes get attached directly to
  161.            the symbol table entry, since they have nothing
  162.            to do with its type, although some classes are not
  163.            allowed for some types.
  164.  
  165.         2. Normal type specifiers are divided into two classes,
  166.            roughly types and modifiers.  The mutually exclusive
  167.            set int, pointer, array, struct, union, float are
  168.            treated as type, and entered as the primary node type.
  169.            The rest, including char, are treated as modifiers,
  170.            some of which may disallow others.
  171.  
  172.         3. const and volatile are treated as special modifiers
  173.            (SC_MODS).    Their storage-class-like properties
  174.            require them to propagate, however, and the kludge
  175.            which handles this is located partly in pd_stmt
  176.            and partly in pd_alloc.  
  177.  
  178.     const and volatile are handled in pd_stmt, pd_head, pd_tail,
  179.     and pd_alloc, and in some non-obvious ways that must not be
  180.     tampered with lightly.  (other analogous modifying declarators
  181.     are handled fully by pd_head.)  pd_head parses them in the 
  182.     obvious way.  pd_tail parses them after the pointer-to
  183.     asterisk, and attaches them to the proper pointer-to nodes,
  184.     according to an extension of the usual inside-out syntax.
  185.     pd_stmt propagates them from STRUCT_TYPE and UNION_TYPE heads
  186.     to SELEMENT and UELEMENT nodes (only).  This simplifies pd_alloc,
  187.     which does the remaining propagation.
  188. */
  189.  
  190. /* ---------- VISIBLE FUNCTIONS ----------- */
  191. /*
  192.     Copy one existing type_node into another existing type_node.
  193.     This is a kludge to allow for the redeclaration of formals.
  194. */
  195. void
  196. pd_tcopy(register struct type_node *s, struct type_node *d)
  197. {
  198.     register int i;
  199.  
  200.     TRACEPB("pd_tcopy", printf("(%p, %p)\n", s, d));
  201.  
  202.     if (s == NULL || d == NULL) {
  203.         RETURN_VOID("pd_tcopy");
  204.     }
  205.     i = sizeof(struct type_node)/sizeof(int);
  206.     while (i--) {
  207.         *((int *)d)++ = *((int *)s)++;
  208.     }
  209.  
  210.     TICKX("pd_tcopy");
  211. }
  212.  
  213. /*
  214.     Check for fairly rigorous type equality.
  215.     SC_MODS (e.g. CONST_MOD) are not checked here; the appropriate
  216.     branch of setype checks those (e.g. assignments check CONST_MOD).
  217. */
  218. bool
  219. pd_teq(struct type_node *t1, struct type_node *t2)
  220. {
  221.     bool result;
  222.  
  223.     TRACEPB("pd_teq",
  224.         printf("(%p, %p)\n", t1, t2);
  225.         pr_type(t1); pr_type(t2));
  226.  
  227.     while (t1 && t2) {
  228.         if (t1 == t2) {
  229.             RETURN_BOOL("pd_teq", TRUE);
  230.         }
  231.         if ( t1 -> t_typtok != t2 -> t_typtok) {
  232.             RETURN_BOOL("pd_teq", FALSE);
  233.         }
  234.  
  235.         switch (t1 -> t_typtok) {
  236.         case STRUCT_TYPE:
  237.         case UNION_TYPE:
  238.             /* structs same if t1 == t2 or if same tag */
  239.             if(t1 -> t_parent && t1 -> t_parent == t2 -> t_parent){
  240.                 RETURN_BOOL("pd_teq", TRUE);
  241.             }
  242.             else {
  243.                 RETURN_BOOL("pd_teq", FALSE);
  244.             }
  245.  
  246.         case POINTER_TYPE:
  247.             /* pointer to void matches pointer to anything else */
  248.             t1 = t1 -> t_link;
  249.             t2 = t2 -> t_link;
  250.             if (t1 && t2 && (t1 -> t_typtok == VOID_TYPE ||
  251.                         t2 -> t_typtok == VOID_TYPE)) {
  252.                 RETURN_BOOL("pd_teq", TRUE);
  253.             }
  254.             break;
  255.  
  256.         case ARRAY_TYPE:
  257.             if (t1 -> t_tdim != t2 -> t_tdim ||
  258.                     t1 -> t_tsize  != t2 -> t_tsize) {
  259.                 RETURN_BOOL("pd_teq", FALSE);
  260.             }
  261.             goto linkit;
  262.  
  263.         case INT_TYPE:
  264.             if ( (t1->t_mclass & ~SC_MODS) !=
  265.                      (t2->t_mclass & ~SC_MODS) ) {
  266.                 RETURN_BOOL("pd_teq", FALSE);
  267.             }
  268.             /* FALLTHROUGH */    
  269.  
  270.         linkit:
  271.         default:
  272.             t1 = t1 -> t_link;
  273.             t2 = t2 -> t_link;
  274.         }
  275.     }
  276.     RETURN_BOOL("pd_teq", t1 == t2);
  277. }
  278.  
  279. /*
  280.     Check for slightly less rigorous type equality; array top-level
  281.     need not match.
  282. */
  283. bool
  284. pd_t1eq(register struct type_node *t1, register struct type_node *t2)
  285. {
  286.     TRACEPB("pd_t1eq",
  287.         printf("(%p, %p)\n", t1, t2);
  288.         pr_type(t1); pr_type(t2));
  289.  
  290.     if (t1 && t1 -> t_typtok == ARRAY_TYPE &&
  291.         t2 && t2 -> t_typtok == ARRAY_TYPE) {
  292.         RETURN_BOOL("pd_t1eq", pd_teq(t1 -> t_link, t2 -> t_link));
  293.     }
  294.     else {
  295.         RETURN_BOOL("pd_t1eq", pd_teq(t1, t2));
  296.     }
  297. }
  298.  
  299. /*
  300.     As pd_teq, except that POINTER_TYPE matches any ARRAY_TYPE at each
  301.     [linear-] tree level.
  302.  
  303.     Arrays of different dimensionality still cause a mismatch.
  304.     This is based on the notion that if someone writes array of 10
  305.     and pointer to same, that is what one wants; pointer to pointer
  306.     or maybe pointer to void would more usually be written.
  307. */
  308. bool
  309. pd_taeq(register struct type_node *t1, register struct type_node *t2)
  310. {
  311.     TRACEPB("pd_taeq",
  312.         printf("(%p, %p)\n", t1, t2);
  313.         pr_type(t1); pr_type(t2));
  314.  
  315.     while (t1 && t2) {
  316.         TRACE("pd_taeq", printf("pd_taeq loop: %p, %p\n", t1, t2));
  317.         if (t1 == t2) {
  318.             RETURN_BOOL("pd_taeq", TRUE);
  319.         }
  320.         if (t1 -> t_typtok != t2 -> t_typtok) {
  321.             if ( (t1 -> t_typtok == POINTER_TYPE &&
  322.                   t2 -> t_typtok == ARRAY_TYPE) ||
  323.                  (t2 -> t_typtok == POINTER_TYPE &&
  324.                   t1 -> t_typtok == ARRAY_TYPE) ) {
  325.                 /* allow mixed case */
  326.                 t1 = t1 -> t_link;
  327.                 t2 = t2 -> t_link;
  328.                 TRACEP("pd_taeq", printf("mixed p/a\n"));
  329.                 continue;
  330.             }
  331.             else {
  332.                 TRACEP("pd_taeq", printf("typtok mismatch\n"));
  333.                 RETURN_BOOL("pd_taeq", FALSE);
  334.             }
  335.         }
  336.  
  337.         /* in the mixed pointer/array case, it never gets here */
  338.         switch (t1 -> t_typtok) {
  339.         case STRUCT_TYPE:
  340.         case UNION_TYPE:
  341.             /* structs same if t1 == t2 or if same tag */
  342.             if(t1 -> t_parent && t1 -> t_parent == t2 -> t_parent){
  343.                 RETURN_BOOL("pd_taeq", TRUE);
  344.             }
  345.             else {
  346.                 RETURN_BOOL("pd_taeq", FALSE);
  347.             }
  348.  
  349.         case POINTER_TYPE:
  350.             /* pointer to void matches pointer to anything else */
  351.             t1 = t1 -> t_link;
  352.             t2 = t2 -> t_link;
  353.             if (t1 && t2 && (t1 -> t_typtok == VOID_TYPE ||
  354.                         t2 -> t_typtok == VOID_TYPE)) {
  355.                 RETURN_BOOL("pd_taeq", TRUE);
  356.             }
  357.             break;
  358.  
  359.         case ARRAY_TYPE:
  360.             if (t1 -> t_tdim != t2 -> t_tdim ||
  361.                     t1 -> t_tsize  != t2 -> t_tsize) {
  362.                 RETURN_BOOL("pd_taeq", FALSE);
  363.             }
  364.             goto tanext;
  365.  
  366.         case INT_TYPE:
  367.             if ( (t1->t_mclass & ~SC_MODS) !=
  368.                      (t2->t_mclass & ~SC_MODS) ) {
  369.                 TRACE("pd_taeq", printf("pd_taeq mclass FALSE: %d, %d\n",
  370.                     t1 -> t_mclass & ~SC_MODS,
  371.                         t2 -> t_mclass & ~SC_MODS));
  372.                 RETURN_BOOL("pd_taeq", FALSE);
  373.             }
  374.             /* FALLTHROUGH */    
  375.  
  376.         tanext:
  377.         default:
  378.             t1 = t1 -> t_link;
  379.             t2 = t2 -> t_link;
  380.         }
  381.     }
  382.     RETURN_BOOL("pd_taeq", (t1 == t2));
  383. }
  384.  
  385. /*
  386.     Check the type of a register, for aggregates, wrong length, etc.
  387.     Do t_error() if it is bad; but do not attempt any patch or fix.
  388.     Reg_type must not be zero.
  389. */
  390. void
  391. reg_check(struct type_node *type, int regtype, char *symbol)
  392. {
  393.     TRACEPB("reg_check", printf("(%p, %d, %s)\n", type, regtype, symbol));
  394.  
  395.     switch(type -> t_typtok) {
  396.     case INT_TYPE:
  397.     case POINTER_TYPE:
  398.         if ((unsigned long)(unsigned)
  399.             reg_size[regtype] != type -> t_tsize) {
  400.             t_2error("type is of inappropriate length for: ",
  401.                 symbol);
  402.         }
  403.         break;
  404.     default:
  405.         t_2error("register not pointer or integer: ",symbol);
  406.         break;
  407.     }
  408.  
  409.     TICKX("reg_check");
  410. }
  411.  
  412. /*
  413.     Return the size of an mclass
  414. */
  415. unsigned long
  416. m_size(int m)
  417. {
  418.     TICK("m_size");
  419.  
  420.     if (m & LONG_MOD) {
  421.         return (long)LONG_SIZE;
  422.     }
  423.     else if (m & CHAR_MOD) {
  424.         return (long)CHAR_SIZE;
  425.     }
  426.     else if (m & SHORT_MOD) {
  427.         return (long)SHORT_SIZE;
  428.     }
  429.     else {
  430.         return (long)INT_SIZE;
  431.     }
  432. }
  433.  
  434. /*
  435.     Test a DELEMENT type_node to see if it is a declaration of exactly one
  436.     function.
  437. */
  438. bool
  439. pd_is1func(struct type_node *t)
  440. {
  441.     TRACEPB("pd_is1func", printf("(%p)\n", t));
  442.  
  443.     if (t -> t_list != NULL || t -> t_link == NULL) {
  444.         RETURN_BOOL("pd_is1func", FALSE);
  445.     }
  446.     if (t -> t_link -> t_typtok != FUNCTION_TYPE) {
  447.         RETURN_BOOL("pd_is1func", FALSE);
  448.     }
  449.     RETURN_BOOL("pd_is1func", TRUE);
  450. }
  451.  
  452. /*
  453.     Given a DELEMENT, go through the list and null out all the
  454.     parent nodes.  This is for removing names of formals from a function
  455.     argument list once the names go out of scope.  It is meant
  456.     to ensure that there aren't any dangling pointers left around.
  457. */
  458. void
  459. pd_orphan(register struct type_node *t)
  460. {
  461.     TRACEPB("pd_orphan", printf("(%p)\n", t));
  462.  
  463.     while (t != NULL) {
  464.         if (t -> t_typtok != DELEMENT_TYPE) {
  465.             t_error("pd_orphan: internal: not a D_ELEMENT");
  466.             break;
  467.         }
  468.         t -> t_parent = NULL;
  469.         t = t -> t_list;
  470.     }
  471.  
  472.     TICKX("pd_orphan");
  473. }
  474.         
  475. /*
  476.     Handle the innards of a cast.  Return NULL if not cast.
  477.     The decision as to whether "not a cast" is an error
  478.     IS TO BE MADE BY THE CALLER.
  479.  
  480.     The opening parenthesis has already been read.
  481.     This form is also called by do_sizeof()
  482. */
  483. struct type_node *
  484. pd_cast(void)
  485. {
  486.     register struct type_node * t;
  487.     register struct st_node * id;
  488.     int class;
  489.  
  490.     TICKB("pd_cast");
  491.  
  492.     if (is_kdecl(t_type) ||
  493.         ( t_type == ID_TOK && (id = ast_lookup(t_symbol)) != NULL &&
  494.             id -> st_sclass == TYPEDEF_CLASS) ) {
  495.         /* note that pd_head ALWAYS returns something */
  496.         t = pd_head(CAST_TYPE, &class);
  497.         t = pd_tail(CAST_TYPE, t, NULL, NULL, NULL_CLASS);
  498.         RETURN_PTR("pd_cast", t);
  499.     }
  500.     RETURN_PTR("pd_cast", NULL);
  501. }
  502.  
  503.  
  504. /*
  505.     Parse a list of declarations.
  506.  
  507.     Each declaration consists of:
  508.         exactly one pd_head
  509.     followed by:
  510.         repeated pd_tails separated by commas
  511.     and terminating
  512.         with a comma, if there is more
  513.         with a type keyword, if formal decls follow
  514.         with a left brace, if function defn and no decls
  515.         with a non-comma, otherwise
  516.  
  517.     a function definition causes a fatal error if it is not
  518.     in FILE_SCOPE.
  519.  
  520.     kind:    NULL_TYPE:    build no list
  521.         UELEMENT_TYPE:    build a union element list
  522.         SELEMENT_TYPE:    build a structure element list
  523.         DELEMENT_TYPE:    build a declaration list
  524.  
  525.     plural:
  526.         TRUE:    parse a series of decls into one list, taking up
  527.                 the last semicolon. it is assumed that
  528.                 the routine is called on a proper decl head.
  529.                 the storage class defaults to something 
  530.                 suitable to the scope.
  531.  
  532.         FALSE:    parse only as long as more commas are encountered, and
  533.                 leave the non-comma token. a proper decl head
  534.                 is not required; the first item may be an
  535.                 identifier, which will be defaulted to an
  536.                 int of storage class suitable to the scope
  537.  
  538.     head_x:
  539.  
  540.         NULL:    nothing happens
  541.  
  542.         ADDRESS:    address of head-type node is returned here.
  543.                 this is senseless if plural is enabled.
  544.  
  545.     return:    kind == NULL_TYPE:
  546.                 NULL
  547.         kind != NULL_TYPE:
  548.                 a list of typenodes of type kind, threaded
  549.                 via t_list, with each of these nodes 
  550.                 attached to a typenode string threaded via
  551.                 t_link.  see above for the sensible values
  552.                 of kind.  NOTE: you only get the chain of
  553.                 element nodes, not the enclosing STRUCT,
  554.                 UNION, or DECL.  see list above.
  555.  
  556.     IN THE EVENT OF A DUPLICATE DECLARATION, SOMETHING REFLECTING THE
  557.     OLD TYPE, NOT THE CURRENT PARSE, IS HOOKED INTO THE LIST!!!
  558.  
  559.     This keeps symbol table nodes and parent nodes linked properly,
  560.     but it may lead to amusing structure definitions.
  561.  
  562.     It also makes it easier to handle the redeclaration of formals,
  563.     which is really why it was done.
  564.  
  565.     In this event, t_error is raised, so no code should be generated
  566.     anyhow.
  567. */
  568. struct type_node *
  569. pd_stmt(int kind, int plural, struct type_node **head_x)
  570. {
  571.     register struct type_node *d_type, *type, *head_type;
  572.     int head_class;
  573.     struct st_node *id;
  574.     struct type_node root_node;
  575.     register struct type_node *ltail, *lp;
  576.     
  577.     char *symbol;
  578.     int regtype;
  579.  
  580.     /*
  581.         First parse the head.
  582.         See notes on pd_head to know what a head is!
  583.     */
  584.  
  585.     TRACEPB("pd_stmt", printf("(%d, %d, %p)\n", kind, plural, head_x));
  586.  
  587.     root_node.t_list = NULL;
  588.     ltail = &root_node;
  589.  
  590.     for (;;) {
  591.         head_type = pd_head(kind, &head_class);
  592.  
  593.         /* parse a list of tails, until a non-comma */
  594.         for(;;) {
  595.             symbol = NULL;
  596.             id = NULL;
  597.             d_type = type =
  598.                 pd_tail(kind, head_type,
  599.                     &symbol, ®type, head_class);
  600.             
  601.             if (kind) {
  602.                 lp = new_tnode();
  603.                 lp -> t_typtok = kind;
  604.                 lp -> t_link = type;
  605.  
  606.                 ltail -> t_list = lp;
  607.                 ltail = lp;
  608.  
  609.                 switch(kind) {
  610.                 case UELEMENT_TYPE:
  611.                     d_type = lp;
  612.                     if ((type -> t_typtok == STRUCT_TYPE ||
  613.                         type -> t_typtok == UNION_TYPE) &&
  614.                         type -> t_list == NULL) {
  615.                         t_error("undefined struct/union");
  616.                     }
  617.                     break;
  618.  
  619.                 case SELEMENT_TYPE:
  620.                     d_type = lp;    /* so that variable, as 
  621.                             entered in symbol table,
  622.                             shows up as element type */
  623.                     if ((type -> t_typtok == STRUCT_TYPE ||
  624.                         type -> t_typtok == UNION_TYPE) &&
  625.                         type -> t_list == NULL) {
  626.                         t_error("undefined struct/union");
  627.                     }
  628.                     break;
  629.  
  630.                 case DELEMENT_TYPE:
  631.                     break;
  632.  
  633.                 default:
  634.                     t_error("pd_stmt: shouldn't happen");
  635.                 }
  636.             }
  637.             /* end of the element */
  638.  
  639.             /*
  640.                 note: certain declarations of formals are
  641.                 disallowed by pd_var and need not concern
  642.                 us here.
  643.             */
  644.             if (symbol != NULL) {
  645.                 /* then something is declared */
  646.                 if (regtype) {
  647.                     reg_check(d_type, regtype, symbol);
  648.                     switch(head_class) {
  649.                     case REGISTER_CLASS:
  650.                     case AUTO_CLASS:
  651.                         id = pd_var(REGISTER_CLASS,
  652.                              d_type, symbol);
  653.                         id -> st_misc |= regtype;
  654. #ifdef SCRATCH
  655.                         if (regtype && reg_idx(regtype) <= SCRATCH) {
  656. #else
  657.                         if (regtype && reg_idx(regtype) == 0) {
  658. #endif
  659.                             t_2warning("register may be clobbered by function calls: ", arp_tab[regtype]);
  660.                             t_warning("that includes implicit function calls such as lmul");
  661.                         }
  662.                         break;
  663.                     default:
  664.                         id = pd_var(head_class, d_type, symbol);
  665.                         t_error("inappropriate use of register name keyword");
  666.                     }
  667.                 }
  668.                 else {
  669.                     id = pd_var(head_class, d_type, symbol);
  670.                 }
  671.                 d_type = type = id -> st_type;
  672.                 if (kind) {
  673.                     TRACEP("pd_stmt",
  674.                       printf("assign parent %p\n", id));
  675.                     lp -> t_parent = id;
  676.                 }
  677.             }
  678.             else if (head_type -> t_typtok != STRUCT_TYPE &&
  679.                  head_type -> t_typtok != UNION_TYPE) {
  680.                 t_warning("empty declaration");
  681.             }
  682.  
  683.             /* check for initializer */
  684.             if (kind == DELEMENT_TYPE && t_type == ASSN_TOK) {
  685.                 get_token();
  686.                 pd_iniz(id);
  687.             }
  688.  
  689.             /* Is there another element? */
  690.             if (t_type == COMMA_TOK) {
  691.                 get_token();
  692.             }
  693.             else {
  694.                 break;
  695.             }
  696.  
  697.         } /* end tails loop */
  698.  
  699.         /* check for end of declaration */
  700.         if (!plural) {
  701.             break; /* out of statement-list loop */
  702.         }
  703.         if (t_type == SEMICOLON_TOK) {
  704.             get_token();
  705.         }
  706.         else {
  707.             need(SEMICOLON_TOK);
  708.             if (is_kdecl(t_type) || t_type == LCURLY_TOK) {
  709.                 if (type != NULL &&
  710.                      type -> t_typtok == FUNCTION_TYPE) {
  711.                     t_warning("check brace structure");
  712.                     fatal("function definition in code");
  713.                 }
  714.             }
  715.         }
  716.         /* now continue along if it's another type keyword */
  717.         if (is_kdecl(t_type)) {
  718.             continue;
  719.         }
  720.         else if (t_type == ID_TOK) {
  721.             id = ast_lookup(t_symbol);
  722.             if (id == NULL) {
  723.                 break;
  724.             }
  725.             else if (id -> st_sclass == TYPEDEF_CLASS) {
  726.                 continue;
  727.             }
  728.             else {
  729.                 break;
  730.             }
  731.         }
  732.         else {
  733.             break;
  734.         }
  735.     }
  736.  
  737.     /* Drop root node. */
  738.     TRACEP("pd_stmt",
  739.         printf("return type %p:\n",root_node.t_list);
  740.         pr_type(root_node.t_list); printf("\n");
  741.     );
  742.  
  743.     if (head_x) {
  744. #ifdef DEBUG
  745.         if (plural) {
  746.             t_error("pd_stmt: internal: senseless use of head_x");
  747.         }
  748. #endif /* DEBUG */
  749.         *head_x = head_type;
  750.     }
  751.     RETURN_PTR("pd_stmt", (root_node.t_list));
  752. }
  753.  
  754. /*
  755.     Parse the head of a declaration/function definition.
  756.     Also see the notes under decl.
  757.     Produce a type tree, and a storage-class word.
  758.  
  759.     A head contains:
  760.         An optional sc-specifier
  761.     and then
  762.         Optional modifiers from the K&R list 
  763.     and then
  764.         An optional noun, which may be
  765.             A typedef tag
  766.         or else
  767.             A noun from the K&R list (e.g. int)
  768.         or else struct or union followed by:
  769.             either a structure tag
  770.             or a struct/union definition (in braces)
  771.             or both
  772.  
  773.  
  774.     A head does not contain:
  775.         Parentheses
  776.         Asterisks
  777.         Brackets
  778.         Identifiers except for typedef tags
  779.     or anything else, so it is deemed to end when such is found
  780.  
  781.     The node tree returned is supposed to always have a base
  782.     type at the end of the typelink-string, that is, a noun keyword or
  783.     a structure tag.
  784.  
  785.     The sequence:
  786.         typedef unsigned tag;
  787.         tag char xyz;
  788.     shall lead to an error, the gist of which is that xyz cannot 
  789.     be both a char and an int.  The distinction made herein
  790.     between modifiers and nouns is muddled in the standard; 
  791.     although it seems not, it could be that it "really" is that
  792.     allowed and disallowed keyword combinations are    described
  793.     by an arbitrary matrix.
  794.  
  795.     Every typelink-string must eventually end with a node
  796.         whose t_typtok is one of:
  797.             INT_TYPE
  798.             STRUCT_TYPE
  799.             UNION_TYPE
  800.             VOID_TYPE
  801.  
  802.         and, in particular, is not one of:
  803.             ARRAY_TYPE
  804.             FUNCTION_TYPE
  805.             POINTER_TYPE
  806.             SELEMENT_TYPE
  807.             UELEMENT_TYPE
  808.  
  809.     The STRUCT_TYPE and UNION_TYPE nodes have a second pointer
  810.         which is the list of element nodes.
  811.         
  812.     kind:      CAST_TYPE:        declaration is inside a cast
  813.          SELEMENT_TYPE:    declaration is inside a struct
  814.          UELEMENT_TYPE:    declaration is inside a union
  815.  
  816.     sclass:            address-of the storage class, which
  817.                 is no longer part of the type node
  818.  
  819.     return:            a type_node which reflects the contents
  820.                 of the "header"
  821.                 SOMETHING IS ALWAYS RETURNED; RESULT IS NEVER
  822.                 EVER NULL.  the default is a 2-byte int.
  823. */
  824. static struct type_node *
  825. pd_head(int kind, int * sclass)
  826. {
  827.     register struct st_node *id, *id1;
  828.     register struct type_node *t, *t1;
  829.     register int sc_count, m;
  830.     int s_f, u_f;
  831.     long ssize;
  832.     char *symbol;
  833.  
  834.     /* Set up as a default to auto int. */
  835.  
  836.     TRACEPB("pd_head", printf("(%d, %p)\n", kind, sclass));
  837.  
  838.     t = new_tnode();
  839.     TRACEP("pd_head", printf("new_tnode %p\n", t));
  840.  
  841.     switch(scope.s_scope) {
  842.     case PROTO_SCOPE:
  843.     case FNDEF_SCOPE:
  844.         *sclass = FORMAL_CLASS;
  845.         break;
  846.  
  847.     case BLOCK_SCOPE:
  848.         *sclass = AUTO_CLASS;
  849.         break;
  850.  
  851.     case FILE_SCOPE:
  852.         *sclass = GLOBAL_CLASS;
  853.         break;
  854.     default:
  855.         fatal("pd_head: internal: unknown scope");
  856.     }
  857.  
  858.     /* Storage-class specifiers. */
  859.     sc_count = 0;
  860.     for(;;) { 
  861.         switch(t_type) {
  862.  
  863.         case K_TYPEDEF:
  864.             switch(scope.s_scope) {
  865.             case PROTO_SCOPE:
  866.             case FNDEF_SCOPE:
  867.                 t_error("typedef keyword in formal");
  868.                 break;
  869.             default:
  870.                 *sclass = TYPEDEF_CLASS;
  871.             }
  872.             sc_count++;
  873.             get_token();
  874.             continue;
  875.  
  876.         case K_EXTERN:
  877.             switch(scope.s_scope) {
  878.             case PROTO_SCOPE:
  879.             case FNDEF_SCOPE:
  880.                 t_error("extern declaration of formal");
  881.                 break;
  882.             default:
  883.                 *sclass = EXTERN_CLASS;
  884.             }
  885.             sc_count++;
  886.             get_token();
  887.             continue;
  888.  
  889.         case K_AUTO:
  890.             if (scope.s_scope == BLOCK_SCOPE) {
  891.                 *sclass = AUTO_CLASS;
  892.             }
  893.             else {
  894.                 t_error("auto declaration--not a local variable");
  895.             }
  896.             sc_count++;
  897.             get_token();
  898.             continue;
  899.  
  900.         case K_REGISTER:
  901.             TRACEP("pd_head", printf("K_REGISTER, scope %d\n", 
  902.                             scope.s_scope));
  903.             switch(scope.s_scope) {
  904.             case PROTO_SCOPE:
  905.             case FNDEF_SCOPE:
  906.                 *sclass = FORMREG_CLASS;
  907.                 break;
  908.             case BLOCK_SCOPE:
  909.                 *sclass = REGISTER_CLASS;
  910.                 break;
  911.             default:
  912.                 t_error("global declared as register type");
  913.             }
  914.             sc_count++;
  915.             get_token();
  916.             continue;
  917.  
  918.         case K_STATIC:
  919.             switch(scope.s_scope) {
  920.             case PROTO_SCOPE:
  921.             case FNDEF_SCOPE:
  922.                 t_error("static declaration of formal");
  923.                 break;
  924.             case BLOCK_SCOPE:
  925.                 *sclass = STATICL_CLASS;
  926.                 break;
  927.             default:
  928.                 *sclass = STATICG_CLASS;
  929.                 break;
  930.             }
  931.             sc_count++;
  932.             get_token();
  933.             continue;
  934.         }
  935.         break;
  936.     }
  937.     if (sc_count > 1) {
  938.         t_error("more than one sc-specifier in declaration");
  939.     }
  940.  
  941.     if (sc_count) {
  942.         switch (kind) {
  943.         case CAST_TYPE:
  944.             t_error("sc-specifier within cast");
  945.  
  946.             break;
  947.         case UELEMENT_TYPE:
  948.         case SELEMENT_TYPE:
  949.             t_error("sc-specifier inside structure or union");
  950.         }
  951.     }
  952.  
  953.     /* Modifiers of the base type. */
  954.     s_f = u_f = 0;
  955.     for(;;) { 
  956.         TRACEP("pd_head", printf("modifier\n"));
  957.         switch(t_type) {
  958.  
  959.         case K_CONST:
  960.             t -> t_mclass |= CONST_MOD;
  961.             get_token();
  962.             continue;
  963.  
  964.         case K_VOLATILE:
  965.             t -> t_mclass |= VOLATILE_MOD;
  966.             get_token();
  967.             continue;
  968.  
  969.         case K_UNSIGNED:
  970.             u_f = 1;
  971.             if (s_f) {
  972.                 t_error("signed unsigned??");
  973.             }
  974.             get_token();
  975.             continue;
  976.  
  977.         case K_SIGNED:
  978.             s_f = 1;
  979.             if (u_f) {
  980.                 t_error("unsigned signed??");
  981.             }
  982.             get_token();
  983.             continue;
  984.  
  985.         case K_CHAR:
  986.             if (t -> t_mclass & (LONG_MOD | SHORT_MOD)) {
  987.                 t_error("long/short char??");
  988.             }
  989.             else {
  990.                 t -> t_mclass |= CHAR_MOD;
  991.                 t -> t_tsize = CHAR_SIZE;
  992.             }
  993.             get_token();
  994.             continue;
  995.  
  996.         case K_SHORT:
  997.             if (t -> t_mclass & (LONG_MOD | CHAR_MOD)) {
  998.                 t_error("long/char short??");
  999.             }
  1000.             else {
  1001.                 t -> t_mclass |= SHORT_MOD;
  1002.                 t -> t_tsize = SHORT_SIZE;
  1003.             }
  1004.             get_token();
  1005.             continue;
  1006.  
  1007.         case K_LONG:
  1008.             if (t -> t_mclass & (SHORT_MOD | CHAR_MOD)) {
  1009.                 t_error("char/short long??");
  1010.             }
  1011.             else {
  1012.                 t -> t_mclass |= LONG_MOD;
  1013.                 t -> t_tsize = LONG_SIZE;
  1014.             }
  1015.             get_token();
  1016.             continue;
  1017.  
  1018.         }
  1019.         break;
  1020.     }
  1021.     if (s_f) {
  1022.         t -> t_mclass &= ~UNSIGNED_MOD;
  1023.     }
  1024.     else if (u_f) {
  1025.         t -> t_mclass |= UNSIGNED_MOD;
  1026.     }
  1027.  
  1028.     /* Pick up the base type. */
  1029.     TRACEP("pd_head", printf("base type\n"));
  1030.     switch(t_type) {
  1031.     case K_INT:
  1032.         get_token();
  1033.         break;
  1034.  
  1035.     case K_VOID:
  1036.         t -> t_typtok = VOID_TYPE;
  1037.         t -> t_tsize = 0;
  1038.         if (t -> t_mclass & ARITH_MODS) {
  1039.             t_error("long, short, etc. do not apply to void");
  1040.             t -> t_mclass &= ~ARITH_MODS;
  1041.         }
  1042.         get_token();
  1043.         break;
  1044.  
  1045.     case K_UNION:
  1046.     case K_STRUCT:
  1047.         if (t_type == K_STRUCT) {
  1048.             kind = SELEMENT_TYPE;
  1049.             t -> t_typtok = STRUCT_TYPE;
  1050.         }
  1051.         else {
  1052.             kind = UELEMENT_TYPE;
  1053.             t -> t_typtok = UNION_TYPE;
  1054.         }
  1055.         t -> t_tsize = 0;
  1056.  
  1057.         if (t -> t_mclass & ARITH_MODS) {
  1058.             t_error("long, short, etc. do not apply to struct/union");
  1059.             t -> t_mclass &= ~ARITH_MODS;
  1060.         }
  1061.         get_token();
  1062.  
  1063.         /* 
  1064.             Deal with tag if there is one
  1065.         */
  1066.  
  1067.         /*
  1068.            WARNING: this code cannot check for undefined tags.
  1069.            That must be done by some sort of post-pass, or
  1070.            else by the operators that use structure elements
  1071.            An undefined tag is one that doesn't have a t_list
  1072.            (list of elements) by the time it is used in code.
  1073.         */
  1074.         id = NULL;    /* Signify that there is no tag. */
  1075.         symbol = NULL;    /* Set up for possible later use. */
  1076.         if (t_type == ID_TOK) {
  1077.             /* Must be a tag. */
  1078.             symbol = str_salloc(t_symbol);
  1079.             id = ast_lookup(t_symbol);
  1080.             get_token();
  1081.  
  1082.             if (id == NULL) {
  1083.                 /* a possibly vacuous entry */
  1084.                 id = rst_enter(symbol, t, TAG_CLASS);
  1085.             }
  1086.             else if (id -> st_sclass != TAG_CLASS) {
  1087.                 /*
  1088.                     A symbol of this name exists.  If
  1089.                     it is not in the CURRENT scope,
  1090.                     re-enter it.  If it is in the current
  1091.                     scope, then it is no good.
  1092.                 */
  1093.                 id = rst_lookup(symbol);
  1094.                 if (id == NULL) {
  1095.                     id = rst_enter(symbol, t, TAG_CLASS);
  1096.                 }
  1097.             }
  1098.             else if (t_type == LCURLY_TOK) {
  1099.                 /*
  1100.                     Re-enter the symbol in the current scope
  1101.                     if and only if a definition follows
  1102.                 */
  1103.                 id = rst_lookup(symbol);
  1104.                 if (id == NULL) {
  1105.                     t_2warning("definition hides earlier one: ", symbol);
  1106.                     id = rst_enter(symbol, t, TAG_CLASS);
  1107.                 }
  1108.             }
  1109.             /* id is not null any more, ever, at this point  */
  1110.             /* however, id is not guaranteed to be valid yet */
  1111.  
  1112.             /* Now check the tag for certain kinds of validity. */
  1113.             if (id -> st_sclass != TAG_CLASS) {
  1114.                 t_2error("not a tag: ", symbol);
  1115.                 id = NULL;
  1116.             }
  1117.             else if (id -> st_type == NULL) {
  1118.                 t_2error("internal: untyped tag: ", symbol);
  1119.                 id -> st_type = t;
  1120.             }
  1121.             else if (id -> st_type -> t_typtok != t -> t_typtok) {
  1122.                 t_2error("conflicting struct/union use of tag: ", symbol);
  1123.                 TRACEP("pd_head1", 
  1124.                   pr_type(id -> st_type); printf("\n");
  1125.                   pr_type(t); printf("\n"));
  1126.                 id = NULL;
  1127.             }
  1128.         }
  1129.         /* id is null here, if no tag is in use */
  1130.  
  1131.         /* Perform a structure definition. */
  1132.         if (t_type == LCURLY_TOK) {
  1133.             if (kind == CAST_TYPE) {
  1134.                 fatal("{ inside cast");
  1135.             }
  1136.  
  1137.             /* Process the structure list. */ 
  1138.             TRACEP("pd_head", printf("structure list\n"));
  1139.             need(LCURLY_TOK);
  1140.             t -> t_list = pd_stmt(kind, TRUE, NULL);
  1141.             if (t -> t_list == NULL) {
  1142.                 t_error("empty structure definition");
  1143.             }
  1144.             t -> t_tsize = pd_alloc(t -> t_list, 
  1145.                     (kind == SELEMENT_TYPE)? 2 : 3);
  1146.             need(RCURLY_TOK);
  1147.             TRACEP("pd_head", printf("end structure list\n"));
  1148.  
  1149.             if (id != NULL && id -> st_type != t) {
  1150.                 /* place the results of the definition */
  1151.                 TRACEP("pd_head", printf("redefine tag\n"));
  1152.                 if (id -> st_type -> t_list == NULL) {
  1153.                     id -> st_type -> t_list = t -> t_list;
  1154.                     id -> st_type -> t_tsize =
  1155.                                  t -> t_tsize;
  1156.                     t = id -> st_type;
  1157.                 }
  1158.                 else {
  1159.                     t_2error("redefinition of tag: ",symbol);
  1160.                 }
  1161.             }
  1162. #if SC_STICKY == 0
  1163.             /* 
  1164.                 remove SC_MODS from the tag
  1165.                 pd_post has not been called at this level at
  1166.                 this time, so no recursion is required;
  1167.                 it would be impossible anyhow
  1168.             */
  1169.             if (t -> t_mclass && id) {
  1170.                 t1 = t;
  1171.                 t = node_dupl(
  1172.                     (byte *) t, sizeof(struct type_node));
  1173.                 t1 -> t_mclass &= ~SC_MODS;
  1174.             }
  1175.             TRACEP("pd_head", printf("detach tag from: ");
  1176.                                 pr_type(t));
  1177. #endif
  1178.         }
  1179.         else {
  1180.             /* it's not a definition, so use what got looked
  1181.                up, if it was valid */
  1182.             if (id != NULL) {
  1183.                 t -> t_list = id -> st_type -> t_list;
  1184.                 t -> t_tsize = id -> st_type -> t_tsize;
  1185. #if SC_STICKY != 0
  1186.                 t -> t_mclass |= id -> st_type -> t_mclass;
  1187. #endif
  1188.             }
  1189.         }
  1190.         /* attach tag name to structure node */
  1191.         t -> t_parent = id;
  1192.         break;
  1193.  
  1194.     case STAR_TOK:
  1195.     case LPAREN_TOK:
  1196.         /* Declarator may be imbedded. */
  1197.         break;
  1198.  
  1199.     case ID_TOK:
  1200.         /*
  1201.             Check to see whether ID is a typedef tag, or
  1202.             a variable or typedef identifier.
  1203.  
  1204.             Under error conditions we have some 
  1205.             semantics-dependent syntax here. Maybe.
  1206.  
  1207.             We assume that if it's not typedef'd, then
  1208.             it's a function declarator.
  1209.         */
  1210.         id = ast_lookup(t_symbol);
  1211.         if (id != NULL && id -> st_sclass == TYPEDEF_CLASS) {
  1212.             if (t -> t_mclass & ARITH_MODS) {
  1213.                 t_error("long, short, etc. do not apply to typedef tag");
  1214.                 t -> t_mclass &= ~ARITH_MODS;
  1215.             }
  1216.             if (id -> st_type != NULL) {
  1217.                 t = id -> st_type;
  1218.             }
  1219.             else {
  1220.                 t_2error("pd_head: internal: typedef tag has NO TYPE: ", t_symbol);
  1221.             }
  1222.             get_token();
  1223.         }
  1224.         break;
  1225.  
  1226.     default:
  1227.         if (kind != CAST_TYPE) {
  1228.             t_error("variable declarator expected");
  1229.             TRACEP("pd_head", printf("token = %d\n", t_type));
  1230.         }
  1231.     }
  1232.     TRACEP("pd_head", printf("returns %p\n", t));
  1233. #ifdef DEBUG
  1234.     if (t == NULL) {
  1235.         fatal("pd_head: internal: returns NULL");
  1236.     }
  1237. #endif
  1238.     RETURN_PTR("pd_head", t);
  1239. }
  1240.  
  1241. /*
  1242.     Parse one declaration tail--that is, one collection of asterisks,
  1243.     parentheses, and brackets, possibly with an imbedded identifier.
  1244.     (This code handles casts, so the identifier is not always required.)
  1245.     Call t_error if an identifier that should be imbedded isn't,
  1246.     or in case of a duplicate, etc.
  1247.  
  1248.     Enter imbedded identifier into symbol table, and return the
  1249.     entry if an address for it is given.
  1250.  
  1251.     Parse grouping parentheses by recursive descent.
  1252.  
  1253.     Assumptions:
  1254.         The operator * is a prefix operator.
  1255.         The operators () and [] are postfix operators.
  1256.         The operator [25] is a case of [].
  1257.         The new-standard version of the arg list is not (yet) handled.
  1258.  
  1259.     kind:
  1260.         CAST_TYPE:    declaration is inside a cast.
  1261.         SELEMENT_TYPE:    declaration is inside a struct.
  1262.         UELEMENT_TYPE:    declaration is inside a union.
  1263.  
  1264.     headclass:
  1265.         EXTERN_CLASS:    etc.; includes classes denoted by
  1266.                 keywords, and others
  1267.  
  1268.         Storage class to be attached to newly defined st_nodes.
  1269.  
  1270.     head_type:
  1271.         Whatever type the item is pointer-to, array-of, etc.;
  1272.         head_type is passed as NULL on descent!
  1273.  
  1274.     dsymbol:
  1275.         Address of a place to put a pointer to the symbol text,
  1276.         should one be found.  caller should set contents of that
  1277.         address to NULL, so as to be able to tell.
  1278.     regtype:
  1279.         Address of a place to put the register subtype at the
  1280.         time dsymbol is set, if dsymbol is set.
  1281.  
  1282.     return:
  1283.         Pointer to a type_node.
  1284.  
  1285.     fndef_ok:
  1286.         flag indicating that an identifier has been seen.
  1287.         Thus, function definition is possible.
  1288.  
  1289.     fnoverrun:
  1290.         Flag indicating that a '(' starting a function has been seen.
  1291. */
  1292. static struct type_node *
  1293. pd_tail    (int kind, struct type_node * head_type,
  1294.         char ** dsymbol, int * regtype, int headclass)
  1295. {
  1296.     register struct type_node *t;
  1297.  
  1298.     TRACEPB("pd_tail", printf("(%d, %p, %p, %p, %d)\n", 
  1299.         kind, head_type, dsymbol, regtype, headclass));
  1300.  
  1301.     if (dsymbol != NULL) {
  1302.         *dsymbol = NULL;
  1303.     }
  1304.     t = pd_t1(kind, head_type, dsymbol, regtype, headclass);
  1305.     if (t == NULL) {
  1306.         fatal("pd_tail: internal: returns NULL");
  1307.     }
  1308.     (void) pd_post(t);
  1309.     RETURN_PTR("pd_tail", t);
  1310. }
  1311.  
  1312. static struct type_node *
  1313. pd_t1(    int kind, struct type_node * head_type,
  1314.         char ** dsymbol, int * regtype, int headclass)
  1315. {
  1316.     register struct st_node *id;
  1317.     register struct node *p;
  1318.     int firstary;
  1319.     struct type_node root_node;
  1320.     struct type_node *star_node, *star_tail;
  1321.     register struct type_node *f_p, *t, *tail;
  1322.  
  1323.     bool fndef_ok, fnoverrun;
  1324.  
  1325.     TRACEPB("pd_t1", printf("(%d, %p, %p, %p, %d)\n", 
  1326.         kind, head_type, dsymbol, regtype, headclass));
  1327.  
  1328.     TRACEP("pd_t1",
  1329.         printf("head_type %p; current t_type %d\n",
  1330.             head_type, t_type));
  1331.  
  1332.     /*
  1333.         NOTE:
  1334.         root_node is a vacuous item which is always
  1335.         on the modifying-declarator list, so that we need
  1336.         not replicate list-setup code all over the place
  1337.     */
  1338.     root_node.t_link = NULL;
  1339.     tail = &root_node;
  1340.  
  1341.     star_node = NULL;
  1342.  
  1343.     id = NULL;
  1344.     fnoverrun = 0;
  1345.     firstary = TRUE;
  1346.  
  1347.     /* Note again: ONE tail */
  1348.  
  1349.     /*
  1350.         First count up asterisks--pointer to.
  1351.         This is PRIOR TO encountering the identifier.
  1352.         Stars get prepended.
  1353.     */
  1354.     if (t_type == STAR_TOK) {
  1355.         /* first prepending */
  1356.         t = new_tnode();
  1357.         t -> t_typtok = POINTER_TYPE;
  1358.         t -> t_tsize = POINTER_SIZE;
  1359.         star_node = star_tail = t;
  1360.         
  1361.         for(get_token(); ; get_token()) {
  1362.             switch(t_type) {
  1363.             case STAR_TOK:
  1364.                 /* subsequent prependings */
  1365.                 t = new_tnode();
  1366.                 t -> t_typtok = POINTER_TYPE;
  1367.                 t -> t_tsize = POINTER_SIZE;
  1368.                 t -> t_link = star_node;
  1369.                 star_node = t;
  1370.                 continue;
  1371.             case K_CONST:
  1372.                 t -> t_mclass |= CONST_MOD;
  1373.                 continue;
  1374.             case K_VOLATILE:
  1375.                 t -> t_mclass |= VOLATILE_MOD;
  1376.                 continue;
  1377.             }
  1378.             break;
  1379.         }
  1380.     }
  1381.  
  1382.     /* There can now be no more stars at this paren level. */
  1383.  
  1384.     /*
  1385.         Left parenthesis could be grouping parenthesis or it could
  1386.         be function-decl parenthesis.  Handle either case.
  1387.  
  1388.         If it is a function parenthesis, there can be no
  1389.         more left-parentheses for grouping, since the
  1390.         identifier or the missing identifier must be
  1391.         inside the innermost pair of grouping parentheses.
  1392.  
  1393.         Do the core, containing the (possibly implicit) identifier.
  1394.         A function () may be taken up as well.
  1395.     */
  1396.     if(t_type == LPAREN_TOK) {
  1397.         /*
  1398.             Since we have not seen an identifier yet, this branch
  1399.             can not lead to a function definition.
  1400.         */
  1401.         fndef_ok = FALSE;
  1402.         get_token();
  1403.         if (t_type == RPAREN_TOK) {
  1404.             /*
  1405.                 Eventually, test for type declarator.
  1406.                 We are in a cast for a function.
  1407.             */
  1408.             fnoverrun = TRUE;
  1409.         }
  1410.         else {
  1411.             /*
  1412.                 The initial '(' was a grouping parenthesis.
  1413.                 Parse the rest of the core recursively.
  1414.             */
  1415.             t = pd_t1(kind, NULL, dsymbol, regtype, headclass);
  1416.             if (t != NULL) {
  1417.                 /* append core item */
  1418.                 tail -> t_link = t;
  1419.                 tail = t;
  1420.  
  1421.                 /* reset tail */
  1422.                 while (tail -> t_link) {
  1423.                     tail = tail -> t_link;
  1424.                 }
  1425.             }
  1426.             need(RPAREN_TOK);
  1427.         }
  1428.     }
  1429.     else if (t_type == ID_TOK) {
  1430.         /*
  1431.             Now that we have seen an identifier, it is possible
  1432.             for a function definition to appear.
  1433.         */
  1434.         fndef_ok = TRUE;
  1435.         if (kind == CAST_TYPE) {
  1436.             t_warning("identifier within cast ignored");
  1437.         }
  1438.         else {
  1439.             if (dsymbol != NULL) {
  1440.                 *dsymbol = str_salloc(t_symbol);
  1441.                 *regtype = t_subtype;
  1442.                 if (is_aregw(t_subtype)) {
  1443.                     t_2help(t_symbol, " has bizarre properties");
  1444.                 }
  1445.             }
  1446.         }
  1447.         get_token();
  1448.     }
  1449.     else if (kind != CAST_TYPE &&
  1450.          head_type -> t_typtok != STRUCT_TYPE &&
  1451.          head_type -> t_typtok != UNION_TYPE) {
  1452.         fndef_ok = FALSE;
  1453.         t_error("missing object name in declaration");
  1454.     }
  1455.  
  1456.     /*
  1457.         GREAT DIVIDE.
  1458.  
  1459.         At this point, the core has been passed.
  1460.         We are ready to process function params or arrays.
  1461.         fnoverrun is a "virtual left paren" flag.
  1462.     */            
  1463.     while (t_type == LPAREN_TOK || fnoverrun) {
  1464.         /*
  1465.             Append a function-returning node.
  1466.             With the new standard, these will have type lists,
  1467.             just like struct/union.
  1468.         */
  1469.         t = new_tnode();
  1470.         t -> t_typtok = FUNCTION_TYPE;
  1471.         t -> t_tsize = 0L;
  1472.         tail -> t_link = t;
  1473.         tail = t;    /* t is never null */
  1474.  
  1475.         /* Take up left paren if it hasn't already been gobbled. */
  1476.         if (!fnoverrun) {
  1477.             get_token();
  1478.         }
  1479.         fnoverrun = FALSE;
  1480.  
  1481.         /* Process an argument list if there is one. */
  1482.         if (t_type == ID_TOK && fndef_ok) {
  1483.             if (scope.s_scope != FILE_SCOPE && t_type == ID_TOK) {
  1484.                 fatal("function definition in non-external context");
  1485.             }
  1486.             scope.s_scope = FNDEF_SCOPE;
  1487.             f_p = t;
  1488.             /*
  1489.                 Do an old-style K&R type arg list.
  1490.                 This is roughly an abbreviated pd_stmt.
  1491.  
  1492.                 WARNING:
  1493.                 This will have to change in the new standard.
  1494.             */
  1495.             for(;;) {
  1496.                 if (id = rst_lookup(t_symbol)) {
  1497.                     t_2error("duplicate formal parameter: ",
  1498.                                  t_symbol);
  1499.                 }
  1500.                 else {
  1501.                     f_p -> t_list = new_tnode();
  1502.                     f_p = f_p -> t_list;
  1503.                     f_p -> t_typtok = DELEMENT_TYPE;
  1504.                     f_p -> t_link = new_tnode();
  1505.                     id = rst_enter(t_symbol,
  1506.                         f_p -> t_link, FORMAL_CLASS);
  1507.                     f_p -> t_parent = id;
  1508.                 }
  1509.                 
  1510.                 get_token();
  1511.                 if (t_type != COMMA_TOK) {
  1512.                     break;
  1513.                 }
  1514.                 get_token();
  1515.                 if (t_type != ID_TOK) {
  1516.                     t_error("missing formal parameter");
  1517.                     break;
  1518.                 }
  1519.             }
  1520.             scope.s_scope = FILE_SCOPE;
  1521.         }
  1522.         need(RPAREN_TOK);
  1523.         fndef_ok = FALSE;
  1524.     }
  1525.     /* at this point, we have processed leading *, the core, and
  1526.         any function-returning which are present at this level */
  1527.  
  1528.     while (t_type == LBRACK_TOK) {
  1529.         /* append array node */
  1530.         t = new_tnode();
  1531.         t -> t_typtok = ARRAY_TYPE;
  1532.         tail -> t_link = t;
  1533.         tail = t;
  1534.  
  1535.         /* eat the [ */
  1536.         get_token();
  1537.         TRACEP("pd_t1", printf("after [: t_type = %d\n",
  1538.                 t_type));
  1539.  
  1540.         /* take the expression if there is one */
  1541.         switch(t_type) {
  1542.         case RCURLY_TOK:
  1543.         case LCURLY_TOK:
  1544.         case SEMICOLON_TOK:
  1545.         case EOF_TOK:
  1546.         case EOP_TOK:
  1547.             /* bad outcome */
  1548.             break;
  1549.  
  1550.         case RBRACK_TOK:
  1551.             if (firstary) {
  1552.                 switch(headclass) {
  1553.                 case FORMAL_CLASS:
  1554.                 case FORMREG_CLASS:
  1555.                     /* formal array of indefinite dim */
  1556.                     t -> t_typtok = POINTER_TYPE;
  1557.                     t -> t_tsize = POINTER_SIZE;
  1558.                     break;
  1559.  
  1560.                 case EXTERN_CLASS:
  1561.                     /* external array of indefinite dim */
  1562.                     break;
  1563.                 default:
  1564.                     /* allow pointer to / function rtng
  1565.                        array of indefinite dimension */
  1566.                     if (tail == &root_node) {
  1567.                         t_error("missing array dimension");
  1568.                     }
  1569.                 }
  1570.             }
  1571.             else {
  1572.                 t_error("missing array dimension");
  1573.             }
  1574.             break;
  1575.  
  1576.         default:        
  1577.             if (is_key(t_type)) {
  1578.                 break;
  1579.             }
  1580.             if (kind == CAST_TYPE) {
  1581.                 p = pe_expr1(TRUE);
  1582.             }
  1583.             else {
  1584.                 /* WARNING: used to be expr(TRUE); */
  1585.                 p = pe_expr();
  1586.             }
  1587.             if (!pe_number(p)) {
  1588.                 t_error("array dimension must be a constant");
  1589.             }
  1590.             else {
  1591.                 t_value = p -> n_const;
  1592.  
  1593.             }
  1594.             TRACEP("pd_t1", printf("dimension %ld\n", 
  1595.                 t_value));
  1596.             if (t_value >= 0) {
  1597.                 t -> t_tdim = t_value;
  1598.             }
  1599.             else {
  1600.                 t_error("negative array dimension");
  1601.             }
  1602.             break;
  1603.  
  1604.         }
  1605.         need(RBRACK_TOK);
  1606.         firstary = FALSE;
  1607.     }
  1608.     /* at this point, array dimensions at this level have been done */
  1609.  
  1610.     if (t_type == LPAREN_TOK) {
  1611.         t_error("unexpected (");
  1612.     }
  1613.  
  1614.     /* append stars, which may carry their consts and volatiles */
  1615.     if (star_node) {
  1616.         tail -> t_link = star_node;
  1617.         tail = star_tail;
  1618.     }
  1619.  
  1620.     /* append head_type node */
  1621.     tail -> t_link = head_type;
  1622.  
  1623.     /* drop root_node. */
  1624.  
  1625.     RETURN_PTR("pd_t1", (root_node.t_link));
  1626. }
  1627.  
  1628. /* ------------- INVISIBLE FUNCTIONS ------------ */
  1629.  
  1630.  
  1631. /*
  1632.     Go over the type (list of type_nodes) t1 and accomplish the following:
  1633.         assign array sizes
  1634.         complain about bad combinations, e.g. functions returning aggr.
  1635.         propagate const and volatile backwards across array-of
  1636.             and WARNING [forwards across structures]
  1637.     All of these involves interactions between two or more list elements,
  1638.     and the structure of this function reflects the fact that it does
  1639.     nothing if the list contains zero or one elements.
  1640.  
  1641.     CAUTION: it is assumed that t_mclass of non-int items only has
  1642.     SC_MODS raised.  If this becomes untrue, it will be necessary to
  1643.     do more masking.
  1644. */
  1645. static int
  1646. pd_post(register struct type_node *t)
  1647. {
  1648.     register struct type_node *t1, *t2;
  1649.  
  1650.     TRACEPB("pd_post", printf("(%p)\n", t));
  1651.  
  1652.     if (t1 = t) {
  1653.         while (t2 = t1 -> t_link) {
  1654.             TRACEP("pd_post",
  1655.                 printf("process %p: ", t1);
  1656.                 pr_type(t1);
  1657.             );
  1658.             switch(t1 -> t_typtok) {
  1659.             case ARRAY_TYPE:
  1660.                 if (t2 -> t_typtok == FUNCTION_TYPE) {
  1661.                     t_error("declared: array of functions");
  1662.                 }
  1663.                 else {
  1664.                     /* assign array size */
  1665.                     t1 -> t_tsize =
  1666.                         t1 -> t_tdim * t2 -> t_tsize;
  1667.  
  1668.                     /* NOTE: scmods might be mixed--
  1669.                        e.g. a volatile to propagate forward
  1670.                        and a const to propagate backward */
  1671.  
  1672.                     /* assign array scmods to element */
  1673.                     t2 -> t_mclass |= t1 -> t_mclass;
  1674.  
  1675.                     /* assign element scmods to array */
  1676.                     /* quasi SHORTCUT */
  1677.                     t1 -> t_mclass |= pd_post(t2);
  1678.  
  1679.                     /* avoid continuing on thru chain */
  1680.  
  1681.                     RETURN_INT("pd_post", t -> t_mclass & SC_MODS);
  1682.                 }
  1683.                 break;
  1684.  
  1685.             case FUNCTION_TYPE:
  1686.                 switch(t2 -> t_typtok) {
  1687.                 case STRUCT_TYPE:
  1688.                 case UNION_TYPE:
  1689.                 case ARRAY_TYPE:
  1690.                     if (t1 -> t_typtok == FUNCTION_TYPE) {
  1691.                         t_error("declared: function returning aggregate");
  1692.                     }
  1693.                     break;
  1694.                 case FUNCTION_TYPE:
  1695.                     t_error("declared: function returning function");
  1696.                     break;
  1697.                 }
  1698.             }
  1699.             t1 = t2;
  1700.         } /* end while */
  1701.  
  1702.         /* struct/union is terminal node, so check terminal */
  1703.         switch(t1 -> t_typtok) {
  1704.         case STRUCT_TYPE:
  1705.         case UNION_TYPE:
  1706.             TRACEP("pd_post", printf("structure: %p\n", t1));
  1707.             if (t1 -> t_mclass & SC_MODS) {
  1708.                 /* go through each element node */
  1709.                 t2 = t1; /* first t2 is the struct node;
  1710.                         then it is successive elt nodes */
  1711.                 while (t2 -> t_list) {
  1712.                     /* replace the s/u element node */
  1713. #if SC_STICKY == 0
  1714.                     t2 -> t_list = node_dupl(
  1715.                         (byte *) t2 -> t_list,
  1716.                         sizeof(struct type_node));
  1717. #endif
  1718.                     t2 = t2 -> t_list; /* look at elt */
  1719.  
  1720.                     /* replace part of elt list */
  1721.                     t2 -> t_link = pd_p1(t2 -> t_link,
  1722.                              t1 -> t_mclass);
  1723.                 }
  1724.             }
  1725.         }
  1726.         RETURN_INT("pd_post", (t -> t_mclass & SC_MODS));
  1727.     }
  1728.     else {
  1729.         RETURN_INT("pd_post", 0);
  1730.     }
  1731. }
  1732.  
  1733. /*
  1734.     This is the substructure version of pd_post
  1735.  
  1736.     It doesn't bother with checks, since they are done already;
  1737.     its only job is to propagate SC_MODS in the forward direction
  1738.     from a struct/union, and it only traverses to the extent
  1739.     necessary to do this.  This also prevents
  1740.     struct tag {
  1741.         struct tag *p;
  1742.     }
  1743.     from looping forever.
  1744. */
  1745. static struct type_node *
  1746. pd_p1(register struct type_node *t, register int mods)
  1747. {
  1748.     register struct type_node *t1, *t2, *t3;
  1749.  
  1750.     /* t is the attachment point */
  1751.  
  1752.     TRACEPB("pd_p1", printf("(%p, %d)\n", t, mods));
  1753.  
  1754.     if (t == NULL) {
  1755.         RETURN_PTR("pd_p1", t);
  1756.     }
  1757.     t1 = t;
  1758.  
  1759.     /* go through the list linkwise (only) */
  1760. #if SC_STICKY == 0
  1761.     /* new attachment point */
  1762.     t = t1 = node_dupl( (byte *) t1, sizeof(struct type_node));
  1763. #endif
  1764.     t1 -> t_mclass |= mods;
  1765.  
  1766.     while ((t2 = t1 -> t_link) && t1 -> t_typtok == ARRAY_TYPE) {
  1767.         /* assign scmods to array element */
  1768. #if SC_STICKY == 0
  1769.         t2 = t1 -> t_link = node_dupl( (byte *) t2,
  1770.                         sizeof(struct type_node));
  1771. #endif
  1772.         t2 -> t_mclass |= t1 -> t_mclass; 
  1773.         t1 = t2;
  1774.     } /* end while */
  1775.  
  1776.     switch(t1 -> t_typtok) {
  1777.     case STRUCT_TYPE:
  1778.     case UNION_TYPE:
  1779.         TRACEP("pd_p1", printf("structure: %p\n", t1));
  1780.         /* propagate const through element list */
  1781.         t2 = t1;
  1782.         while (t2 -> t_list) {
  1783.             /* replace the s/u element node */
  1784. #if SC_STICKY == 0
  1785.             t2 -> t_list = (void *)
  1786.                 node_dupl( (byte *) t2 -> t_list,
  1787.                        sizeof(struct type_node));
  1788. #endif
  1789.             t2 = t2 -> t_list;    /* now look at the node */
  1790.  
  1791.             /* replace what is linked to the s/u element node */
  1792.             t2 -> t_link = pd_p1(t2 -> t_link,
  1793.                              t1 -> t_mclass);
  1794.         }
  1795.     }
  1796.     RETURN_PTR("pd_p1", t);
  1797. }
  1798.  
  1799.  
  1800. /*
  1801.     Enter a symbol that has been fished out of a pd_tail onto
  1802.     some symbol table.  Context information is used to determine
  1803.     whether duplicate entries are OK, and so on.
  1804.  
  1805.     A symbol table entry, guaranteed non-NULL, is returned.
  1806.     In FNDEF_SCOPE only, it may be that id -> st_type differs
  1807.     from type, and should replace type; the caller must deal with this.
  1808.  
  1809.     For FNDEF_SCOPE, the type_nodes are made in global memory.  The
  1810.     st_nodes and symbols are made in local memory.  
  1811. */
  1812. static struct st_node *
  1813. pd_var(int sclass, struct type_node *type, char * symbol)
  1814. {
  1815.     register struct st_node *id, *id1;
  1816.     register struct type_node *t;
  1817.     register int ttok;
  1818.  
  1819.     TRACEPB("pd_var", printf("(%d, %p, %s)\n", sclass, type, symbol));
  1820.  
  1821.     TRACEP("pd_var",
  1822.         pr_type(type);
  1823.         printf("class: ");
  1824.         pr_sclass(sclass);
  1825.         printf("\n");
  1826.     );
  1827.  
  1828. #ifdef DEBUG
  1829.     if (type == NULL) {
  1830.         fatal("pd_var: internal: no type");
  1831.     }
  1832. #endif /* DEBUG */
  1833.  
  1834.     ttok = type -> t_typtok;
  1835.     if (ttok == FUNCTION_TYPE) {
  1836.         if (sclass == STATICG_CLASS) {
  1837.             sclass = SCODE_CLASS;
  1838.         }
  1839.         else {
  1840.             sclass = CODE_CLASS;
  1841.         }
  1842.         TRACEP("pd_var", printf("classify as code\n"));
  1843.     }
  1844.     else {
  1845.         if (ttok == VOID_TYPE) {
  1846.             t_2error(symbol, " declared void");
  1847.         }
  1848.         else if (is_element(ttok)) {
  1849.             sclass = SUE_CLASS;
  1850.             TRACEP("pd_var", printf("classify as element\n"));
  1851.         }
  1852.     }
  1853.  
  1854.     /*
  1855.         WARNING: undefined structure can't be checked until decls are
  1856.            all done.
  1857.     */
  1858.  
  1859.     /* Look it up and enter it but in the current scope only. */
  1860.     id = rst_lookup(symbol);
  1861.     if (id == NULL) {
  1862.         /*
  1863.             id is not a duplicate symbol; set it up
  1864.         */
  1865.         id = rst_enter(symbol, type, sclass);
  1866.         id -> st_misc |= EXPLICIT_SYM;
  1867.         if (scope.s_scope == FNDEF_SCOPE) {
  1868.             t_2error("not in formal list: ", symbol);
  1869.         }
  1870.  
  1871.         /* Fix id's alias if it is a static declarator */
  1872.         /* NOTE: functions declared static are already CODE_CLASS */
  1873.         if (sclass == STATICL_CLASS) {
  1874.             id -> st_alias = str_salloc(pd_name());
  1875.         }
  1876.     }
  1877.     else if (scope.s_scope == FNDEF_SCOPE) {
  1878.         /*
  1879.             Formal scope duplicate messages.
  1880.             Formal scope reentry.
  1881.         */
  1882.         if (id -> st_misc & EXPLICIT_SYM) {
  1883.             t_2error("duplicate type specification of formal: "
  1884.                                 , symbol);
  1885.         }
  1886.         else {
  1887.             TRACEP("pd_var",
  1888.                    printf("reenter formal %p\n", type));
  1889.             if (type != NULL) {
  1890.                 switch(ttok) {
  1891.                 case FUNCTION_TYPE:
  1892.                     t_2error("formal declared a function: "
  1893.                                 , symbol);
  1894.                     break;
  1895.  
  1896.                 case UNION_TYPE:
  1897.                 case ARRAY_TYPE:
  1898.                 case STRUCT_TYPE:
  1899.                     t_2error("formal declared an aggregate: "
  1900.                                 , symbol);
  1901.                     break;
  1902.                 }
  1903.             }
  1904.             /* Update the type inside the actual node. */
  1905.             pd_tcopy(type, id -> st_type); 
  1906.             id -> st_sclass = sclass;
  1907.             id -> st_misc |= EXPLICIT_SYM;
  1908.         }
  1909.     }
  1910.     else {
  1911.         /*
  1912.             Non-formal scope duplicate messages
  1913.         */
  1914.         switch(ttok) {
  1915.         case SELEMENT_TYPE:
  1916.         case UELEMENT_TYPE:
  1917.             if (!pd_teq(type, id -> st_type)) 
  1918.                 switch(id -> st_type -> t_typtok) {
  1919.             case SELEMENT_TYPE:
  1920.             case UELEMENT_TYPE:
  1921.               if (type -> t_tdim !=
  1922.                     id -> st_type -> t_tdim) {
  1923.                   t_2error("element offset conflict: ",
  1924.                             symbol);
  1925.               }
  1926.               else {
  1927.                 t_2error("element type conflict: ",
  1928.                             symbol);
  1929.               }
  1930.               break;
  1931.             default:
  1932.               t_2error("not an element: ", symbol);
  1933.             }
  1934.             break;
  1935.  
  1936.         case FUNCTION_TYPE:
  1937.             if (!pd_teq(type, id -> st_type)) {
  1938.                 t_2error("redeclaration of function: ",
  1939.                             symbol);
  1940.             }
  1941.             break;
  1942.  
  1943.         default:
  1944.             t_2error("duplicate symbol: ", symbol);
  1945.         }
  1946.     }
  1947.     RETURN_PTR("pd_var", id);
  1948. } /* end pd_var */
  1949.  
  1950. /*
  1951.     Return a unique symbolic name for a (static) variable.
  1952. */
  1953. static char *
  1954. pd_name(void)
  1955. {
  1956.     static char buf[LONG_DIGITS+5];
  1957.     static unsigned long ssn = 1;
  1958.  
  1959.     TICK("pd_name");
  1960.  
  1961.     buf[0] = 'V';
  1962.     conul2sc(ssn, buf+1, 2);
  1963.  
  1964.     TRACEP("pd_name", printf("%d  %s\n", str_len(buf), buf));
  1965.     ssn++;
  1966.     return &buf[0];
  1967. }
  1968.  
  1969. /*
  1970.     Parse initializers, and attach the initializer block(s) to
  1971.     the symbol id
  1972.  
  1973.     Initializer blocks come in several functions.  The enumeration 
  1974.     ..._DEC in enum.h lists these.  Type zero is the array list, which
  1975.     contains n slots each of which holds a pointer and a numerical 
  1976.     constant.  It may in the end be preferable to instead make each
  1977.     slot a polymorphic longword with its own type.  The pointer form
  1978.     will point to a loc_node that can hold a constant and a label, in
  1979.     order to accomodate initializers of the (label + offset) variety.
  1980.     According to K&R, that is the most complex form possible.  Some
  1981.     users of realtime rom-based systems might not mind being able to
  1982.     pass through any parse tree that the assembler can handle, in which
  1983.     case the pointer might point to a general parse node instead of just
  1984.     a loc_node.
  1985.  
  1986.     The IBSSZB type is used for filler blocks in incomplete 
  1987.     initializations.  It is essentially meant to finesse the situation
  1988.     where a user declares  int x[100000] = 0;  and avoid attempting
  1989.     to produce in the compiler an array of 100000 double-longword
  1990.     structures!  To keep things regular, this block is used for all 
  1991.     fillers.
  1992.  
  1993.     The ISTRA type is for string arrays, in the sense of an array of
  1994.     char declared as a string.  It is used for declarations like 
  1995.     char a[6] = "hello";  and for implicit declarations in code.
  1996.  
  1997.     String pointer arrays declared as arrays of strings are "under 
  1998.     development."  Implicit string declarations in code, i.e. char *p;
  1999.     p = "hello"; create internal labels for the strings.  These labels
  2000.     get entered into the symbol table, so that the loc_node can point
  2001.     back to a symbol in the customary fashion.  (Entry into the table is
  2002.     primarily the most expedient way to get the symbol node created; the
  2003.     symbols are not looked up in the table.)  The declaration 
  2004.     char *a[] = {"first", "second", "third};
  2005.     is a little different again, in that it sets up THREE objects; namely,
  2006.     the internal label, the string itself, and the pointer variable.  Each
  2007.     string declarator sets up two physical objects in storage, rather than
  2008.     the usual one.
  2009. */
  2010. static void
  2011. pd_iniz(struct st_node *id)
  2012. {
  2013.     TICK("pd_iniz");
  2014.     if (t_type == LCURLY_TOK) {
  2015.         get_token();
  2016.         id -> st_iniz = pd_par(id -> st_type, 1L);
  2017.         (void) needend(RCURLY_TOK);
  2018.     }
  2019.     else {
  2020.         id -> st_iniz = pd_par(id -> st_type, 1L);
  2021.     }
  2022.     /* supplementary error message */
  2023.     switch(t_type) {
  2024.     default:
  2025.         t_2error("declarator or semicolon expected at: ",
  2026.         ps_tok(t_type));
  2027.     case ID_TOK:
  2028.     case SEMICOLON_TOK:
  2029.     case STAR_TOK:
  2030.     case COMMA_TOK:
  2031.     case LPAREN_TOK:
  2032.         ;
  2033.     }
  2034. }
  2035.     
  2036. /*
  2037.     In effect we enter here from pd_iniz() with the outer braces
  2038.     stripped.
  2039. */
  2040. static struct iblock *
  2041. pd_par(register struct type_node *t, unsigned long size)
  2042. {
  2043.     register unsigned int j;
  2044.     register unsigned long i, c;
  2045.     register struct iblock *p, *q, *s;
  2046.     struct iblock base;
  2047.     struct st_node *id;
  2048.     int minus;
  2049.  
  2050.     TRACEPB("pd_par",
  2051.         printf("(%p, %lu)\n", t, size);
  2052.         pr_type(t));
  2053.  
  2054. #ifdef DEBUG
  2055.     if (t == NULL) {
  2056.         t_error("internal: pd_par: no type");
  2057.         RETURN_PTR("pd_par", NULL);
  2058.     }
  2059. #endif
  2060.  
  2061.     p = NULL;
  2062.  
  2063.     switch (t -> t_typtok) {
  2064.     case INT_TYPE:
  2065.     case POINTER_TYPE:
  2066.         /* get a decl block, which holds up to IDATA_SIZE long entries */
  2067.         p = q = new_iblock((size)? size : (unsigned long) IDATA_SIZE);
  2068.  
  2069.         q -> isize = (byte) t -> t_tsize;
  2070.         c = q -> idim;
  2071.  
  2072.         for (j = 0, i = 0; size == 0 || i < size; i++) {
  2073.  
  2074.             /* WARNING: must call pe_expr() if operators are found */
  2075.             /* probably should use character lookahead and call
  2076.                 pe_expr if next is not ,;{} */
  2077.  
  2078.             if (minus = (t_type == MINUS_TOK)) {
  2079.                 get_token();
  2080.             }
  2081.  
  2082.             /* this is forced to be an "if" statement since it
  2083.                 needs in one case to break out of the "for" loop */
  2084.             if (t_type == INT_TOK || t_type == LONG_TOK ||
  2085.                             t_type == STRING_TOK) {
  2086.                 if (j >= IDATA_SIZE) {
  2087.                     /* append another block */
  2088.                     /* request remaining size */
  2089.                     q -> ilink = new_iblock(
  2090.                       (size)? size - i: (unsigned long) IDATA_SIZE);
  2091.                     q = q -> ilink;
  2092.                     q -> isize = (byte) t -> t_tsize;
  2093.                     /* tot up actual initializers covered */
  2094.                     c += q -> idim;
  2095.                     j = 0;
  2096.                 }
  2097.                 if (t_type != STRING_TOK) {
  2098.                     if (minus) {
  2099.                         t_value = -t_value;
  2100.                     }
  2101.                     if (pe_oversize(t -> t_mclass, t_value) >= 2) {
  2102.                         t_error("oversized initializer");
  2103.                     }
  2104.                     q -> idata[j++] . icn = t_value;
  2105.                 }
  2106.                 else {
  2107.                     s = new_iblock(2L);
  2108.                     s -> itype = ISTRS_DEC;
  2109.                     s -> isize = 1;
  2110.                     s -> idata[0] . ipt = 
  2111.                         (void *) str_lalloc(t_symbol);
  2112.                     s -> idim = (unsigned long) 
  2113.                         str_val(s -> idata[0] . ipt);
  2114.                     s -> idata[1] . ipt =
  2115.                         (void *)str_lalloc(str_name());
  2116.                     q -> idata[j++] . ipt = (char *) s;
  2117.                     if (t -> t_tsize != 4) {
  2118.         t_error("string pointer truncated");
  2119.         TRACEP("pd_par", printf("t -> t_tsize = %ld\n", t -> t_tsize));
  2120.                     }
  2121.                 }
  2122.                 get_token();
  2123.             }
  2124.             /* temporary code to handle address-of */
  2125.             else if (t_type == AND_TOK) {
  2126.                 get_token();
  2127.                 if (j >= IDATA_SIZE) {
  2128.                     /* append another block */
  2129.                     /* request remaining size */
  2130.                     q -> ilink = new_iblock(
  2131.                       (size)? size - i: (unsigned long) IDATA_SIZE);
  2132.                     q = q -> ilink;
  2133.                     q -> isize = (byte) t -> t_tsize;
  2134.                     /* tot up actual initializers covered */
  2135.                     c += q -> idim;
  2136.                     j = 0;
  2137.                 }
  2138.                 if (t_type == ID_TOK) {
  2139.                     if (id = ast_lookup(t_symbol)) {
  2140.                         s = new_iblock(1L);
  2141.                         s -> itype = ITAG_DEC;
  2142.                         s -> idata[0].ipt =  
  2143.                               id -> st_alias;
  2144.                         q -> idata[j++] . ipt =
  2145.                             (char *) s;
  2146.                     }
  2147.                     else {
  2148.                         t_2error("undefined symbol: ",
  2149.                                     t_symbol);
  2150.                         j++;
  2151.                     }
  2152.                     get_token();
  2153.                 }
  2154.                 else {
  2155.                         t_2error("cannot handle declaration syntax at: ",
  2156.                         ps_tok(t_type));
  2157.                 }
  2158.             }
  2159.             else {
  2160.                 break;
  2161.             }
  2162.  
  2163.             if (t_type == COMMA_TOK) {
  2164.                 get_token();
  2165.             }
  2166.             else {
  2167.                 break;
  2168.             }
  2169.         }
  2170.         /* append a bsszb block to fill out size */
  2171.         if (size) {
  2172.             if (size > c) {
  2173.                 q -> ilink = new_iblock(0L);
  2174.                 q = q -> ilink;
  2175.                 q -> idim = (size - c) * t -> t_tsize;
  2176.                 q -> itype = IBSSZB_DEC;
  2177.             }
  2178.         }
  2179.         else {
  2180.             q -> idim = (unsigned long)j;
  2181.         }
  2182.  
  2183.         TRACEP("pd_par",
  2184.             q = p;
  2185.             while(q) {
  2186.                 pr_iblock(q);
  2187.                 q = q -> ilink;
  2188.             }
  2189.         );
  2190.         break;
  2191.  
  2192.     case ARRAY_TYPE:
  2193.         q = &base;
  2194.         base . ilink = NULL;
  2195.  
  2196.         /* get chain of blocks */
  2197.         TRACEP("pd_par", array: pr_type(t -> t_link));
  2198.         if (t_type == STRING_TOK && 
  2199.             t -> t_link -> t_typtok == INT_TYPE &&
  2200.                 t -> t_link -> t_tsize == 1) {
  2201.             /* generate special string block */
  2202.             p = new_iblock(1L);
  2203.             p -> itype = ISTRA_DEC;
  2204.             p -> isize = 1;
  2205.             p -> idata[0] . ipt = (void *) str_lalloc(t_symbol);
  2206.             i = (unsigned long) str_val(p->idata[0].ipt);
  2207.             if (t -> t_tdim && i > t -> t_tdim) {
  2208.                 i = t -> t_tdim;
  2209.                 ((char *) p -> idata [0] . ipt) [i] = 0;
  2210.                 t_warning("string initializer truncated");
  2211.             }
  2212.             p -> idim = i;
  2213.             TRACEP("pd_par", pr_iblock(p));
  2214.             if (i < t -> t_tdim) {
  2215.                 q = new_iblock(0L);
  2216.                 p -> ilink = q;
  2217.                 q -> itype = IBSSZB_DEC;
  2218.                 q -> idim = t -> t_tdim - i;
  2219.                 TRACEP("pd_par", pr_iblock(q));
  2220.             }
  2221.             get_token();
  2222.         }
  2223.         else if (t_type == LCURLY_TOK) {
  2224.             /* get a braced set of initializers */
  2225.             if (t -> t_tdim == 0) {
  2226.                 t_error("missing dimension, initialized array");
  2227.             }
  2228.             for (i = 0; i < t -> t_tdim; ) {
  2229.                 TRACEP("pd_par", printf("array: i = %lu\n", i));
  2230.                 get_token();
  2231.                 q -> ilink = pd_par(t -> t_link, 1L);
  2232.                 i++;
  2233.             
  2234.                 /* seek to end of chain */
  2235.                 while (q -> ilink) {
  2236.                     q = q -> ilink;
  2237.                 }
  2238.  
  2239.                 /* eat a right brace */
  2240.                 if (!needend(RCURLY_TOK)) {
  2241.                     break;
  2242.                 }
  2243.                 /* and a comma */
  2244.                 if (t_type != COMMA_TOK) {
  2245.                     break;
  2246.                 }
  2247.                 get_token();
  2248.                 if (t_type != LCURLY_TOK) {
  2249.                     break;
  2250.                 }
  2251.             }
  2252.             /* append a bsszb block to fill out size */
  2253.             if (i < t -> t_tdim) {
  2254.                 q -> ilink = new_iblock(0L);
  2255.                 q -> ilink -> itype = IBSSZB_DEC;
  2256.                 q = q -> ilink;
  2257.                 q -> idim = (t -> t_tdim - i) *
  2258.                             t -> t_link -> t_tsize;
  2259.                 TRACEP("pd_par", pr_iblock(q));
  2260.             }
  2261.             /* t is no good here */
  2262.             p = base.ilink;
  2263.         }
  2264.         else {
  2265.             /* get an open list of initializers */
  2266.             if (t -> t_tdim == 0) switch (t -> t_link -> t_typtok){
  2267.             case INT_TYPE: 
  2268.             case POINTER_TYPE:
  2269.                 break;
  2270.             default:
  2271.                 t_error("missing dimension, initialized array");
  2272.             }
  2273.             TRACEP("pd_par", printf("open list\n"));
  2274.             p = pd_par(t -> t_link, size * t -> t_tdim);
  2275.         }
  2276.         break;
  2277.  
  2278.     case STRUCT_TYPE:
  2279.         /* do this the simplest way */
  2280.         q = &base;
  2281.         base . ilink = NULL;
  2282.         while (t = t -> t_list) {
  2283.             switch(t -> t_link -> t_typtok) {
  2284.             case STRUCT_TYPE:
  2285.             case ARRAY_TYPE:
  2286.                 if (t_type == LCURLY_TOK) {
  2287.                     get_token();
  2288.                     q -> ilink = pd_par(t -> t_link, 1L);
  2289.                     q = q -> ilink;
  2290.                     (void) needend(RCURLY_TOK);
  2291.                     break;
  2292.                 }
  2293.                 /* FALLTHROUGH */
  2294.             default:
  2295.                 q -> ilink = pd_par(t -> t_link, 1L);
  2296.                 q = q -> ilink;
  2297.             }
  2298.         }
  2299.         p = base.ilink;
  2300.         break;
  2301.  
  2302.     case FUNCTION_TYPE:
  2303.         t_error("cannot initialize a function");
  2304.         break;
  2305.  
  2306.     default:
  2307.         t_error("cannot initialize object of this type");
  2308.         TRACEP("pd_par", pr_type(t); printf("\n"));
  2309.     }
  2310.     /* CAUTION: size and t are no good here */
  2311.     RETURN_PTR("pd_par", p);
  2312. }
  2313.