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