home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / icon / dos / src / rtt / rttsym.c < prev   
C/C++ Source or Header  |  1992-02-10  |  22KB  |  765 lines

  1. /*
  2.  * rttsym.c contains symbol table routines.
  3.  */
  4. #include "rtt.h"
  5.  
  6. #define HashSize 149
  7.  
  8. /*
  9.  * Prototype for static function.
  10.  */
  11. hidden novalue add_def    Params((struct node *dcltor));
  12. hidden novalue add_s_prm  Params((struct token *ident, int param_num,
  13.                             int flags));
  14. hidden novalue dcl_typ    Params((struct node *dcl));
  15. hidden novalue dcltor_typ Params((struct node *dcltor, struct node *tqual));
  16.  
  17. word lbl_num = 0;                   /* next unused label number */
  18. struct lvl_entry *dcl_stk;          /* stack of declaration contexts */
  19.  
  20. char *str_rslt;                     /* string "result" in string table */
  21. struct init_tend *tend_lst = NULL;  /* list of tended descriptors */
  22. struct sym_entry *decl_lst = NULL;  /* declarations from "declare {...}" */
  23. struct sym_entry *v_len = NULL;     /* entry for length of varargs */
  24. int il_indx = 0;                    /* data base symbol table index */
  25.  
  26. /*
  27.  * Free lists for various structures.
  28.  */
  29. static struct sym_entry *sym_free = NULL;
  30. static struct lvl_entry *lvl_entry_free = NULL;
  31. static struct init_tend *init_tend_free = NULL;
  32.  
  33. static struct sym_entry *sym_tbl[HashSize]; /* symbol table */
  34.  
  35. /*
  36.  * The following strings are put in the string table and used for
  37.  *  reconginizing valid tended declarations.
  38.  */
  39. static char *block = "block";
  40. static char *descrip = "descrip";
  41. static char *blk_lst[] =  {"b_real",   "b_cset",  "b_file",   "b_proc",
  42.    "b_list",   "b_lelem",  "b_table",  "b_telem", "b_set",    "b_selem",
  43.    "b_record", "b_tvkywd", "b_tvsubs", "b_tvtbl", "b_coexpr", "b_refresh",
  44.    "b_slots", NULL};
  45.  
  46. /*
  47.  * init_sym - initialize  symbol table.
  48.  */
  49. novalue init_sym()
  50.    {
  51.    static int first_time = 1;
  52.    int hash_val;
  53.    register struct sym_entry *sym;
  54.    int i;
  55.    char **s;
  56.  
  57.    /*
  58.     * Initialize the symbol table and declaration stack. When called for
  59.     *  the first time, put strings in string table.
  60.     */
  61.    if (first_time) {
  62.       first_time = 0;
  63.       for (i = 0; i < HashSize; ++i)
  64.          sym_tbl[i] = NULL;
  65.       dcl_stk = NewStruct(lvl_entry);
  66.       dcl_stk->nest_lvl = 1;
  67.       dcl_stk->next = NULL;
  68.       block = spec_str(block);
  69.       descrip = spec_str(descrip);
  70.       for (s = blk_lst; *s != NULL; ++s)
  71.          *s = spec_str(*s);
  72.       }
  73.    else {
  74.       for (hash_val = 0; hash_val < HashSize; ++ hash_val) {
  75.          for (sym = sym_tbl[hash_val]; sym != NULL &&
  76.            sym->nest_lvl > 0; sym = sym_tbl[hash_val]) {
  77.             sym_tbl[hash_val] = sym->next;
  78.             sym->next = sym_free;
  79.             sym_free = sym;
  80.             }
  81.          }
  82.       }
  83.    dcl_stk->kind_dcl = OtherDcl;
  84.    dcl_stk->parms_done = 0;
  85.    }
  86.  
  87. /*
  88.  * sym_lkup - look up a string in the symbol table. Return NULL If it is not
  89.  *  there.
  90.  */
  91. struct sym_entry *sym_lkup(image)
  92. char *image;
  93.    {
  94.    register struct sym_entry *sym;
  95.  
  96.    for (sym = sym_tbl[(unsigned int)image % HashSize]; sym != NULL;
  97.         sym = sym->next)
  98.       if (sym->image == image)
  99.          return sym;
  100.    return NULL;
  101.    }
  102.  
  103. /*
  104.  * sym_add - add a symbol to the symbol table. For some types of entries
  105.  *  it is illegal to redefine them. In that case, NULL is returned otherwise
  106.  *  the entry is returned.
  107.  */
  108. struct sym_entry *sym_add(tok_id, image, id_type, nest_lvl)
  109. int tok_id;
  110. char *image;
  111. int id_type;
  112. int nest_lvl;
  113.    {
  114.    register struct sym_entry **symp;
  115.    register struct sym_entry *sym;
  116.  
  117.    symp = &sym_tbl[(unsigned int)image % HashSize];
  118.    while (*symp != NULL && (*symp)->nest_lvl > nest_lvl)
  119.       symp = &((*symp)->next);
  120.    while (*symp != NULL && (*symp)->nest_lvl == nest_lvl) {
  121.       if ((*symp)->image == image) {
  122.          /*
  123.           * Redeclaration:
  124.           *
  125.           * An explicit typedef may be given for a built-in typedef
  126.           * name. A label appears in multiply gotos and as a label
  127.           * on a statement. Assume a global redeclaration is for an
  128.           * extern. Return the entry for these situations but don't
  129.           * try too hard to detect errors. If actual errors are not
  130.           * caught here, the C compiler will find them.
  131.           */
  132.          if (tok_id == TypeDefName && ((*symp)->tok_id == C_Integer ||
  133.             (*symp)->tok_id == TypeDefName))
  134.             return *symp;
  135.          if (id_type == Label && (*symp)->id_type == Label)
  136.             return *symp;
  137.          if ((*symp)->nest_lvl == 1)
  138.             return *symp;
  139.          return NULL;    /* illegal redeclarations */
  140.          }
  141.       symp = &((*symp)->next);
  142.       }
  143.  
  144.    /*
  145.     * No entry exists for the symbol, create one, fill in its fields, and add
  146.     *  it to the table.
  147.     */
  148.    if ((sym = sym_free) == NULL)
  149.       sym = NewStruct(sym_entry);
  150.    else
  151.       sym_free = sym_free->next;
  152.  
  153.    sym->tok_id = tok_id;
  154.    sym->image = image;
  155.    sym->id_type =  id_type;
  156.    sym->nest_lvl = nest_lvl;
  157.    sym->ref_cnt = 1;
  158.    sym->il_indx = -1;
  159.    sym->may_mod = 0;
  160.    if (id_type == Label)
  161.       sym->u.lbl_num = lbl_num++;
  162.    sym->next = *symp;
  163.    *symp = sym;
  164.  
  165.    return sym;     /* success */
  166.    }
  167.  
  168. /*
  169.  * lbl - make sure the label is in the symbol table and return a node
  170.  *  referencing the symbol table entry.
  171.  */
  172. struct node *lbl(t)
  173. struct token *t;
  174.    {
  175.    struct sym_entry *sym;
  176.    struct node *n;
  177.  
  178.    sym = sym_add(Identifier, t->image, Label, 2);
  179.    if (sym == NULL)
  180.       errt2(t, "conflicting definitions for ", t->image);
  181.    n = var_node(t);
  182.    if (n->u[0].sym != sym)
  183.       errt2(t, "conflicting definitions for ", t->image);
  184.    return n;
  185.    }
  186.  
  187. /*
  188.  * push_cntxt - push a level of declaration context (this may or may not
  189.  *  be level of declaration nesting).
  190.  */
  191. novalue push_cntxt(lvl_incr)
  192. int lvl_incr;
  193.    {
  194.    struct lvl_entry *entry;
  195.  
  196.    if ((entry = lvl_entry_free) == NULL)
  197.       entry = NewStruct(lvl_entry);
  198.    else
  199.       lvl_entry_free = lvl_entry_free->next;
  200.  
  201.    entry->nest_lvl = dcl_stk->nest_lvl + lvl_incr;
  202.    entry->kind_dcl = OtherDcl;
  203.    entry->parms_done = 0;
  204.    entry->tended = NULL;
  205.    entry->next = dcl_stk;
  206.    dcl_stk = entry;
  207.    }
  208.  
  209. /*
  210.  * pop_cntxt - end a level of declaration context
  211.  */
  212. novalue pop_cntxt()
  213.    {
  214.    int hash_val;
  215.    int old_lvl;
  216.    int new_lvl;
  217.    register struct sym_entry *sym;
  218.    struct lvl_entry *entry;
  219.  
  220.    /*
  221.     * Move the top entry of the stack to the free list.
  222.     */
  223.    old_lvl = dcl_stk->nest_lvl;
  224.    entry = dcl_stk;
  225.    dcl_stk = dcl_stk->next;
  226.    entry->next = lvl_entry_free;
  227.    lvl_entry_free = entry;
  228.  
  229.    /*
  230.     * If this pop reduced the declaration nesting level, remove obsolete
  231.     *  entries from the symbol table.
  232.     */
  233.    new_lvl = dcl_stk->nest_lvl;
  234.    if (old_lvl > new_lvl) {
  235.       for (hash_val = 0; hash_val < HashSize; ++ hash_val) {
  236.          for (sym = sym_tbl[hash_val]; sym != NULL &&
  237.            sym->nest_lvl > new_lvl; sym = sym_tbl[hash_val]) {
  238.             sym_tbl[hash_val] = sym->next;
  239.             free_sym(sym);
  240.             }
  241.          }
  242.       unuse(tend_lst, old_lvl);
  243.       }
  244.    }
  245.  
  246. /*
  247.  * unuse - mark tended slots in at the given level of declarations nesting
  248.  *  as being no longer in use, and leave the slots available for reuse
  249.  *  for declarations that occur in pararallel compound statements.
  250.  */
  251. novalue unuse(t_lst, lvl)
  252. struct init_tend *t_lst;
  253. int lvl;
  254.    {
  255.    while (t_lst != NULL) {
  256.       if (t_lst->nest_lvl >= lvl)
  257.          t_lst->in_use = 0;
  258.       t_lst = t_lst->next;
  259.       }
  260.    }
  261.  
  262. /*
  263.  * free_sym - remove a reference to a symbol table entry and free storage
  264.  *  related to it if no references remain.
  265.  */
  266. novalue free_sym(sym)
  267. struct sym_entry *sym;
  268.    {
  269.    if (--sym->ref_cnt <= 0) {
  270.       switch (sym->id_type) {
  271.          case TndDesc:
  272.          case TndStr:
  273.          case TndBlk:
  274.             free_tree(sym->u.tnd_var.init); /* initializer expression */
  275.          }
  276.       sym->next = sym_free;
  277.       sym_free = sym;
  278.       }
  279.    }
  280.  
  281. /*
  282.  * alloc_tnd - allocated a slot in a tended array for a variable and return
  283.  *  its index.
  284.  */
  285. int alloc_tnd(typ, init, lvl)
  286. int typ;
  287. struct node *init;
  288. int lvl;
  289.    {
  290.    register struct init_tend *tnd;
  291.  
  292.    if (lvl > 2) {
  293.      /*
  294.       * This declaration occurs in an inner compound statement. There
  295.       *  may be slots created for parallel compound statement, but were
  296.       *  freed and can be reused here.
  297.       */
  298.      tnd = tend_lst;
  299.      while (tnd != NULL && (tnd->in_use || tnd->init_typ != typ))
  300.        tnd = tnd->next;
  301.      if (tnd != NULL) {
  302.          tnd->in_use = 1;
  303.          tnd->nest_lvl = lvl;
  304.          return tnd->t_indx;
  305.          }
  306.       }
  307.  
  308.    /*
  309.     * Allocate a new tended slot, compute its index in the array, and
  310.     *  set initialization and other information.
  311.     */
  312.    if ((tnd = init_tend_free) == NULL)
  313.       tnd = NewStruct(init_tend);
  314.    else
  315.       init_tend_free = init_tend_free->next;
  316.  
  317.    if (tend_lst == NULL)
  318.       tnd->t_indx = 0;
  319.    else
  320.       tnd->t_indx = tend_lst->t_indx + 1;
  321.    tnd->init_typ = typ;
  322.    /*
  323.     * The initalization from the declaration will only be used to 
  324.     *  set up the tended location if the declaration is in the outermost
  325.     *  "block". Otherwise a generic initialization will be done during
  326.     *  the set up and the one from the declaration will be put off until
  327.     *  the block is entered.
  328.     */
  329.    if (lvl == 2)
  330.       tnd->init = init;
  331.    else
  332.       tnd->init = NULL;
  333.    tnd->in_use = 1;
  334.    tnd->nest_lvl = lvl;
  335.    tnd->next = tend_lst;
  336.    tend_lst = tnd;
  337.    return tnd->t_indx;
  338.    }
  339.  
  340. /*
  341.  * free_tend - put the list of tended descriptors on the free list.
  342.  */
  343. novalue free_tend()
  344.    {
  345.    register struct init_tend *tnd;
  346.  
  347.    if (tend_lst == NULL)
  348.       return;
  349.    for (tnd = tend_lst; ; tnd = tnd->next) {
  350.       if (tnd->next == NULL) {
  351.           tnd->next = init_tend_free;
  352.           init_tend_free = tend_lst;
  353.           tend_lst = NULL;
  354.           return;
  355.           }
  356.       }
  357.    }
  358.  
  359. /*
  360.  * dst_alloc - the conversion of a parameter is encountered during
  361.  *  parsing; make sure a place is allocated to act as the destination.
  362.  */
  363. novalue dst_alloc(cnv_typ, var)
  364. struct node *cnv_typ;
  365. struct node *var;
  366.    {
  367.    struct sym_entry *sym;
  368.  
  369.    if (var->nd_id == SymNd) {
  370.       sym = var->u[0].sym;
  371.       if (sym->id_type & DrfPrm) {
  372.          switch (cnv_typ->tok->tok_id) {
  373.             case C_Integer:
  374.                sym->u.param_info.non_tend |= PrmInt;
  375.                break;
  376.             case C_Double:
  377.                sym->u.param_info.non_tend |= PrmDbl;
  378.                break;
  379.             }
  380.          }
  381.       }
  382.    }
  383.  
  384. /*
  385.  * strt_def - the start of an operation definition is encountered during
  386.  *  parsing; establish an new declaration context and make "result"
  387.  *  a special identifier.
  388.  */
  389. novalue strt_def()
  390.    {
  391.    struct sym_entry *sym;
  392.  
  393.    push_cntxt(1);
  394.    sym = sym_add(Identifier, str_rslt, RsltLoc, dcl_stk->nest_lvl);
  395.    sym->u.referenced = 0;
  396.    }
  397.  
  398. /*
  399.  * add_def - update the symbol table for the given declarator.
  400.  */
  401. static novalue add_def(dcltor)
  402. struct node *dcltor;
  403.    {
  404.    struct sym_entry *sym;
  405.    struct token *t;
  406.    int tok_id;
  407.  
  408.    /*
  409.     * find the identifier within the declarator.
  410.     */
  411.    for (;;) {
  412.       switch (dcltor->nd_id) { 
  413.          case BinryNd:
  414.             /* ')' or '[' */
  415.             dcltor = dcltor->u[0].child;
  416.             break;
  417.          case ConCatNd:
  418.             /* pointer direct-declarator */
  419.             dcltor = dcltor->u[1].child;
  420.             break;
  421.          case PrefxNd:
  422.             /* ( ... ) */
  423.             dcltor =  dcltor->u[0].child;
  424.             break;
  425.          case PrimryNd:
  426.             t = dcltor->tok;
  427.             if (t->tok_id == Identifier || t->tok_id == TypeDefName) {
  428.                /*
  429.                 * We have found the identifier, add an entry to the
  430.                 *  symbol table based on information in the declaration
  431.                 *  context.
  432.                 */
  433.                if (dcl_stk->kind_dcl == IsTypedef)
  434.                   tok_id = TypeDefName;
  435.                else
  436.                   tok_id = Identifier;
  437.                sym = sym_add(tok_id, t->image, OtherDcl, dcl_stk->nest_lvl);
  438.                if (sym == NULL)
  439.                   errt2(t, "redefinition of ", t->image);
  440.                }
  441.             return;
  442.          default:
  443.             return;
  444.          }
  445.       }
  446.    }
  447.  
  448. /*
  449.  * id_def - a declarator has been parsed. Determine what to do with it
  450.  *  based on information put in the declaration context while parsing
  451.  *  the "storage class type qualifier list".
  452.  */
  453. novalue id_def(dcltor, init)
  454. struct node *dcltor;
  455. struct node *init;
  456.    {
  457.    struct node *chld0, *chld1;
  458.    struct sym_entry *sym;
  459.  
  460.    if (dcl_stk->parms_done)
  461.       pop_cntxt();
  462.  
  463.    /*
  464.     * Look in the declaration context (the top of the declaration stack)
  465.     *  to see if this is a tended declaration.
  466.     */
  467.    switch (dcl_stk->kind_dcl) {
  468.       case TndDesc:
  469.       case TndStr:
  470.       case TndBlk:
  471.          /*
  472.           * Tended variables are either simple identifers or pointers to 
  473.           *  simple identifers.
  474.           */
  475.          chld0 = dcltor->u[0].child;
  476.          chld1 = dcltor->u[1].child;
  477.          if (chld1->nd_id != PrimryNd || (chld1->tok->tok_id != Identifier &&
  478.            chld1->tok->tok_id != TypeDefName))
  479.              errt1(chld1->tok, "unsupported tended declaration");
  480.          if (dcl_stk->kind_dcl == TndDesc) {
  481.             /*
  482.              * Declared as full tended descriptor - must not be a pointer.
  483.              */
  484.             if (chld0 != NULL)
  485.                errt1(chld1->tok, "unsupported tended declaration");
  486.             }
  487.          else {
  488.             /*
  489.              * Must be a tended pointer.
  490.              */
  491.             if (chld0 == NULL || chld0->nd_id != PrimryNd)
  492.                errt1(chld1->tok, "unsupported tended declaration");
  493.             }
  494.    
  495.          /*
  496.           * This is a legal tended declaration, make a symbol table entry
  497.           *  for it and allocated a tended slot. Add the symbol table
  498.           *  entry to the list of tended variables in this context.
  499.           */
  500.          sym = sym_add(Identifier, chld1->tok->image, dcl_stk->kind_dcl,
  501.             dcl_stk->nest_lvl);
  502.          if (sym == NULL)
  503.             errt2(chld1->tok, "redefinition of ", chld1->tok->image);
  504.          sym->u.tnd_var.blk_name = dcl_stk->blk_name;
  505.          sym->u.tnd_var.init = init;
  506.          sym->t_indx = alloc_tnd(dcl_stk->kind_dcl, init, dcl_stk->nest_lvl);
  507.          sym->u.tnd_var.next = dcl_stk->tended;
  508.          dcl_stk->tended = sym;
  509.          ++sym->ref_cnt;
  510.          return;
  511.       default:
  512.          add_def(dcltor); /* ordinary declaration */
  513.       }
  514.    }
  515.  
  516. /*
  517.  * func_def - a function header has been parsed. Add the identifer for
  518.  *  the function to the symbol table.
  519.  */
  520. novalue func_def(head)
  521. struct node *head;
  522.    {
  523.    /*
  524.     * If this is really a function header, the current declaration
  525.     *  context indicates that a parameter list has been completed.
  526.     *  Parameter lists at other than at nesting level 2 are part of
  527.     *  nested declaration information and do not show up here. The
  528.     *  function parameters must remain in the symbol table, so the
  529.     *  context is just updated, not popped.
  530.     */
  531.    if (!dcl_stk->parms_done)
  532.       yyerror("invalid declaration");
  533.    dcl_stk->parms_done = 0;
  534.    if (dcl_stk->next->kind_dcl == IsTypedef)
  535.       yyerror("a typedef may not be a function definition");
  536.    add_def(head->u[1].child);
  537.    }
  538.  
  539. /*
  540.  * s_prm_def - add symbol table entries for a parameter to an operation.
  541.  *  Undereferenced and/or dereferenced versions of the parameter may be
  542.  *  specified.
  543.  */
  544. novalue s_prm_def(u_ident, d_ident)
  545. struct token *u_ident;
  546. struct token *d_ident;
  547.    {
  548.    int param_num;
  549.  
  550.    if (params == NULL)
  551.       param_num = 0;
  552.    else
  553.       param_num = params->u.param_info.param_num + 1;
  554.    if (u_ident != NULL)
  555.       add_s_prm(u_ident, param_num, RtParm);
  556.    if (d_ident != NULL)
  557.       add_s_prm(d_ident, param_num, DrfPrm);
  558.    }
  559.  
  560. /*
  561.  * add_s_prm - add a symbol table entry for either a dereferenced or
  562.  *  undereferenced version of a parameter. Put it on the current
  563.  *  list of parameters.
  564.  */
  565. static novalue add_s_prm(ident, param_num, flags)
  566. struct token *ident;
  567. int param_num;
  568. int flags;
  569.    {
  570.    struct sym_entry *sym;
  571.  
  572.    sym = sym_add(Identifier, ident->image, flags, dcl_stk->nest_lvl);
  573.    if (sym == NULL)
  574.       errt2(ident, "redefinition of ", ident->image);
  575.    sym->u.param_info.param_num = param_num;
  576.    sym->u.param_info.non_tend = 0;
  577.    sym->u.param_info.cur_loc = PrmTend;
  578.    sym->u.param_info.next = params;
  579.    sym->il_indx = il_indx++;
  580.    params = sym;
  581.    ++sym->ref_cnt;
  582.    }
  583.  
  584. /*
  585.  * var_args - a variable length parameter list for an operation is parsed.
  586.  */
  587. novalue var_args(ident)
  588. struct token *ident;
  589.    {
  590.    struct sym_entry *sym;
  591.  
  592.    /*
  593.     * The last parameter processed represents the variable part of the list;
  594.     *  update the symbol table entry. It may be dereferenced or undereferenced
  595.     *  but not both.
  596.     */
  597.    sym = params->u.param_info.next;
  598.    if (sym != NULL && sym->u.param_info.param_num == 
  599.       params->u.param_info.param_num)
  600.          errt1(ident, "only one version of variable parameter list allowed");
  601.    params->id_type |= VarPrm;
  602.  
  603.    /*
  604.     * Add the identifier for the length of the variable part of the list
  605.     *  to the symbol table.
  606.     */
  607.    sym = sym_add(Identifier, ident->image, VArgLen, dcl_stk->nest_lvl);
  608.    if (sym == NULL)
  609.       errt2(ident, "redefinition of ", ident->image);
  610.    sym->il_indx = il_indx++;
  611.    v_len = sym;
  612.    ++v_len->ref_cnt;
  613.    }
  614.  
  615. /*
  616.  * d_lst_typ - the end of a "declare {...}" is encountered. Go through a
  617.  *   declaration list adding storage class, type qualifier, declarator
  618.  *   and initializer information to the symbol table entry for each
  619.  *   identifer. Add the entry onto the list associated with the "declare"
  620.  */
  621. novalue d_lst_typ(dcls)
  622. struct node *dcls;
  623.    {
  624.    if (dcls == NULL)
  625.       return;
  626.    for ( ; dcls != NULL && dcls->nd_id == LstNd; dcls = dcls->u[0].child)
  627.       dcl_typ(dcls->u[1].child);
  628.    dcl_typ(dcls);
  629.    }
  630.  
  631. /*
  632.  * dcl_typ - go through the declarators of a declaration adding the storage
  633.  *   class, type qualifier, declarator, and initializer information to the
  634.  *   symbol table entry of each identifier. Add the entry onto the list
  635.  *   associated with the current "declare {...}".
  636.  */
  637. static novalue dcl_typ(dcl)
  638. struct node *dcl;
  639.    {
  640.    struct node *tqual;
  641.    struct node *dcltors;
  642.  
  643.    if (dcl == NULL)
  644.       return;
  645.    tqual = dcl->u[0].child;
  646.    for (dcltors = dcl->u[1].child; dcltors->nd_id == CommaNd;
  647.       dcltors = dcltors->u[0].child)
  648.          dcltor_typ(dcltors->u[1].child, tqual);
  649.    dcltor_typ(dcltors, tqual);
  650.    }
  651.  
  652. /*
  653.  * dcltor_typ- find the identifier in the [initialized] declarator and add
  654.  *   the storage class, type qualifer, declarator, and initialization
  655.  *   information to its symbol table entry. Add the entry onto the list
  656.  *   associated with the current "declare {...}".
  657.  */
  658. static novalue dcltor_typ(dcltor, tqual)
  659. struct node *dcltor;
  660. struct node *tqual;
  661.    {
  662.    struct sym_entry *sym;
  663.    struct node *part_dcltor;
  664.    struct node *init = NULL;
  665.    struct token *t;
  666.  
  667.    if (dcltor->nd_id == BinryNd && dcltor->tok->tok_id == '=') {
  668.       init = dcltor->u[1].child;
  669.       dcltor = dcltor->u[0].child;
  670.       }
  671.    part_dcltor = dcltor;
  672.    for (;;) {
  673.       switch (part_dcltor->nd_id) { 
  674.          case BinryNd:
  675.             /* ')' or '[' */
  676.             part_dcltor = part_dcltor->u[0].child;
  677.             break;
  678.          case ConCatNd:
  679.             /* pointer direct-declarator */
  680.             part_dcltor = part_dcltor->u[1].child;
  681.             break;
  682.          case PrefxNd:
  683.             /* ( ... ) */
  684.             part_dcltor =  part_dcltor->u[0].child;
  685.             break;
  686.          case PrimryNd:
  687.             t = part_dcltor->tok;
  688.             if (t->tok_id == Identifier || t->tok_id == TypeDefName) {
  689.                /*
  690.                 * The identifier has been found, update its symbol table
  691.                 *  entry.
  692.                 */
  693.                sym = sym_lkup(t->image);
  694.                sym->u.declare_var.tqual = tqual;
  695.                sym->u.declare_var.dcltor = dcltor;
  696.                sym->u.declare_var.init = init;
  697.                ++sym->ref_cnt;
  698.                sym->u.declare_var.next = decl_lst;
  699.                decl_lst = sym;
  700.                }
  701.             return;
  702.          default:
  703.             return;
  704.          }
  705.       }
  706.    }
  707.  
  708. /*
  709.  * tnd_char - indicate in the current declaration context that a tended
  710.  *  character (pointer?) declaration has been found.
  711.  */
  712. novalue tnd_char()
  713.    {
  714.    dcl_stk->kind_dcl = TndStr;
  715.    dcl_stk->blk_name = NULL;
  716.    }
  717.  
  718. /*
  719.  * tnd_strct - indicate in the current declaration context that a tended
  720.  *  struct declaration has been found and indicate the struct type.
  721.  */
  722. novalue tnd_strct(t)
  723. struct token *t;
  724.    {
  725.    char *strct_nm;
  726.    char **s;
  727.  
  728.    strct_nm = t->image;
  729.    free_t(t);
  730.  
  731.    /*
  732.     * Make sure it is a struct type that may be tended.
  733.     */
  734.    if (strct_nm == descrip) {
  735.       dcl_stk->kind_dcl = TndDesc;
  736.       dcl_stk->blk_name = NULL;
  737.       return;
  738.       }
  739.    for (s = blk_lst; *s != NULL; ++s) {
  740.       if (*s == strct_nm) {
  741.          dcl_stk->kind_dcl = TndBlk;
  742.          dcl_stk->blk_name = strct_nm;
  743.          return;
  744.          }
  745.       }
  746.    yyerror("unsupported tended type");
  747.    }
  748.  
  749. /*
  750.  * tnd_strct - indicate in the current declaration context that a tended
  751.  *  union (pointer?) declaration has been found.
  752.  */
  753. novalue tnd_union(t)
  754. struct token *t;
  755.    {
  756.    /*
  757.     * Only union block pointers may be tended.
  758.     */
  759.    if (t->image != block)
  760.       yyerror("unsupported tended type");
  761.    free_t(t);
  762.    dcl_stk->kind_dcl = TndBlk;
  763.    dcl_stk->blk_name = NULL;
  764.    }
  765.