home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Harvest C 1.3 / Source Code / SymTable.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  10.3 KB  |  460 lines  |  [TEXT/ALFA]

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*
  30.  * Harvest C
  31.  * 
  32.  * Copyright 1991 Eric W. Sink   All rights reserved.
  33.  * 
  34.  * This file contains routines for management of symbol tables.  Symbol tables
  35.  * are used very heavily in Harvest C.  They manage everything from
  36.  * preprocessor symbols to string literals, and of course, the C identifiers.
  37.  * 
  38.  * 
  39.  * 
  40.  */
  41.  
  42. #include "conditcomp.h"
  43. #include <stdio.h>
  44. #include <string.h>
  45.  
  46. #include "structs.h"
  47.  
  48. #include "SymTable.h"
  49.  
  50. #pragma segment SymbolLists
  51.  
  52. SymListVia_t
  53. RawTable(int tablesize)
  54. /* Create an empty, unused Symbol Table. */
  55. {
  56.     register SymListVia_t           raw;
  57.     raw = Ealloc(sizeof(SymList_t));
  58.     if (tablesize) {
  59.         Via(raw)->hashtable = Ealloc(tablesize * sizeof(Ptr));
  60.         #ifdef OLDMEM
  61.         HLock((Handle) Via(raw)->hashtable);
  62.         #endif
  63.         memset(Via(Via(raw)->hashtable), 0L, (tablesize * sizeof(Ptr)));
  64.         #ifdef OLDMEM
  65.         HUnlock((Handle) Via(raw)->hashtable);
  66.         #endif
  67.     } else
  68.         Via(raw)->hashtable = NULL;
  69.     Via(raw)->count = 0;
  70.     Via(raw)->isShadow = 0;
  71.     Via(raw)->tablesize = tablesize;
  72.     return raw;
  73. }
  74.  
  75. #ifdef KILLTHIS
  76. unsigned long
  77. TableHash(char *name)
  78. /* This is the hash function for the symbol tables. */
  79. {
  80.     unsigned long                   h = 0;
  81.     unsigned long                   g;
  82.  
  83.     for (; *name; ++name) {
  84.     h = (h << 4) + *name;
  85.     if (g = h & 0xf0000000)
  86.         h = (h ^ (g >> 24)) & 0x0fffffff;
  87.     }
  88.     return h;
  89. }
  90.  
  91. #endif
  92.  
  93. unsigned long
  94. TableHash(char *name)
  95. /* This is the hash function for the symbol tables. */
  96. {
  97.     unsigned long                   h = 0;
  98.     unsigned long                   g;
  99.  
  100.     for (; *name; ++name) {
  101.     h = h * 65599 + *name;
  102.     }
  103.     if (!h)
  104.     h = 1;
  105.     return h;
  106. }
  107.  
  108. SYMVia_t
  109. TableAdd(SymListVia_t table, char *name)
  110. /*
  111.  * General routine for adding a symbol to a symbol table.  The symbol table
  112.  * data structures are used for many purposes.  Note that currently, a number
  113.  * of routines depend on these tables being kept in order.
  114.  */
  115. {
  116.     /*
  117.      * All the table manipulation routines may be modified later to make the
  118.      * tables vastly more efficient.
  119.      */
  120.     register SYMVia_t               tmp;
  121.     register SYMVia_t               tmp2, prev;
  122.     register unsigned long          hk;
  123.     tmp = RawSymbol(name);
  124.     hk = TableHash(name) % Via(table)->tablesize;
  125.     assert(table);
  126.     Via(tmp)->IndexInserted = ++Via(table)->count;
  127.     Via(tmp)->next = Via(Via(table)->hashtable)[hk];
  128.     Via(Via(table)->hashtable)[hk] = tmp;
  129.     return tmp;
  130. }
  131.  
  132. int
  133. TableSearchNum(SymListVia_t table, char *name)
  134. /*
  135.  * This routine searches a table for the given name, returning the index of
  136.  * the symbol record for that name if it was found, otherwise NULL.
  137.  */
  138. {
  139.     register SYMVia_t               tmp;
  140.     tmp = TableSearch(table, name);
  141.     if (tmp)
  142.     return Via(tmp)->IndexInserted;
  143.     else
  144.     return 0;
  145. }
  146.  
  147. SYMVia_t
  148. TableGetNum(SymListVia_t table, int num)
  149. /*
  150.  * This table returns symbol record # num from the given table.  If the table
  151.  * does not contains num records, then NULL.  The first record in a table is
  152.  * numbered 1.
  153.  */
  154. {
  155.     SYMVia_t                        tmp;
  156.     int                             ndx;
  157.     if (num > Via(table)->count)
  158.     return NULL;
  159.     ndx = 0;
  160.     while (ndx < Via(table)->tablesize) {
  161.     tmp = Via(Via(table)->hashtable)[ndx++];
  162.     while (tmp) {
  163.         if (Via(tmp)->IndexInserted == num)
  164.         return tmp;
  165.         tmp = Via(tmp)->next;
  166.     }
  167.     }
  168.     return NULL;
  169. }
  170.  
  171. SYMVia_t
  172. TableSearch(SymListVia_t table, char *name)
  173. /*
  174.  * This routine searches a table for the given name, returning the symbol
  175.  * record for that name if it was found, otherwise NULL.
  176.  */
  177. {
  178.     register SYMVia_t               tmp;
  179.     unsigned long                   hashval;
  180.     if (!Via(table)->count) return 0;
  181.     hashval = TableHash(name) % Via(table)->tablesize;
  182.     tmp = Via(Via(table)->hashtable)[hashval];
  183.     while (tmp) {
  184.     if (!strcmp(Via(tmp)->name, name)) {
  185.         return tmp;
  186.     } else
  187.         tmp = Via(tmp)->next;
  188.     }
  189.     return NULL;
  190. }
  191.  
  192. SYMVia_t
  193. TableRemove(SymListVia_t table, char *name)
  194. /* Removes a given symbol from the table. */
  195. {
  196.     register SYMVia_t               tmp;
  197.     tmp = TableSearch(table, name);
  198.     if (tmp) {
  199.     Via(tmp)->name[0] = 0;
  200.     }
  201.     return NULL;
  202. }
  203.  
  204. SymListVia_t
  205. CopySymTable(SymListVia_t table)
  206. {
  207.     SymListVia_t                    copy = NULL;
  208.     if (table) {
  209.     copy = RawTable(0);
  210.     Via(copy)->hashtable = Via(table)->hashtable;
  211.     Via(copy)->count = Via(table)->count;
  212.     Via(copy)->isShadow = 1;
  213.     }
  214.     return copy;
  215. }
  216.  
  217. int
  218. MaxSizes(SymListVia_t table)
  219. /* This is used for calculating the size of a union */
  220. {
  221.     int                             ndx;
  222.     SYMVia_t                        tmp;
  223.     unsigned long                   num = 0;
  224.     ndx = 0;
  225.     while (ndx < Via(table)->tablesize) {
  226.     tmp = Via(Via(table)->hashtable)[ndx++];
  227.     while (tmp) {
  228.         Via(tmp)->numbers.structoffset = 0;
  229.         if (Via(tmp)->TP) {
  230.         if (GetTPSize(Via(tmp)->TP) > num) {
  231.             num = GetTPSize(Via(tmp)->TP);
  232.         }
  233.         }
  234.         tmp = Via(tmp)->next;
  235.     }
  236.     }
  237.     return num;
  238. }
  239.  
  240. SYMVia_t
  241. FirstSym(SymListVia_t tbl)
  242. {
  243.     return TableGetNum(tbl, 1);
  244. }
  245.  
  246. int
  247. SameTable(SymListVia_t a, SymListVia_t b)
  248. {
  249.     /*
  250.      * This method assumes that there is ONLY one copy of the member list
  251.      * symbol table for a struct/union record, and we can simply compare the
  252.      * pointer.  Same goes for functions and enums.
  253.      */
  254.  
  255.     int                             ndx;
  256.     SYMVia_t                        a1;
  257.     SYMVia_t                        b1;
  258.  
  259.     if (a == b) {
  260.     return 1;
  261.     }
  262.     if (a && b) {
  263.     if (Via(a)->count != Via(b)->count) {
  264.         return 0;
  265.     }
  266.     ndx = 1;
  267.     while (ndx <= Via(a)->count) {
  268.         a1 = TableGetNum(a, ndx);
  269.         b1 = TableGetNum(b, ndx);
  270.         if (!SameType(Via(a1)->TP, Via(b1)->TP)) {
  271.         return 0;
  272.         }
  273.         ndx++;
  274.     }
  275.     return 1;
  276.     } else {
  277.     VeryBadParseError("NULL arg in SameTable...");
  278.     return 0;
  279.     }
  280. }
  281.  
  282. void
  283. FreeSyms(SYMVia_t cur, int dodef)
  284. {
  285.     if (cur) {
  286.     FreeSyms(Via(cur)->next, dodef);
  287.     if (dodef)
  288.         FreeTree(Via(cur)->Definition.FuncBody);
  289.     /* M68kDef ??? */
  290.     Efree(cur);
  291.     }
  292. }
  293.  
  294. void
  295. FreeSymbolList(SymListVia_t table, int dodef)
  296. {
  297.     SYMVia_t                        cur;
  298.     SYMVia_t                        next;
  299.     if (table) {
  300.     int                             ndx;
  301.     ndx = 0;
  302.     if (Via(table)->isShadow)
  303.         return;
  304.     while (ndx < Via(table)->tablesize) {
  305.         FreeSyms(Via(Via(table)->hashtable)[ndx++], dodef);
  306.     }
  307.     Efree(Via(table)->hashtable);
  308.     Efree(table);
  309.     }
  310. }
  311.  
  312. void
  313. CheckUsages(SymListVia_t table)
  314. {
  315.     int                             ndx;
  316.     SYMVia_t                        tmp;
  317.     ndx = 0;
  318.     while (ndx < Via(table)->tablesize) {
  319.     tmp = Via(Via(table)->hashtable)[ndx++];
  320.     while (tmp) {
  321.         if (!Via(tmp)->numbers.CountUses) {
  322.         #ifdef OLDMEM
  323.         HLock((Handle) tmp);
  324.         #endif
  325.         UserWarning2(WARN_unusedvariable, Via(tmp)->name);
  326.         #ifdef OLDMEM
  327.         HUnlock((Handle) tmp);
  328.         #endif
  329.         }
  330.         tmp = Via(tmp)->next;
  331.     }
  332.     }
  333. }
  334.  
  335. int
  336. GenGlobal(SymListVia_t table, InstListVia_t Codes, int Flush)
  337. {
  338.     int                             ndx;
  339.     SYMVia_t                        tmp;
  340.     /*
  341.      * Given a symbol table, generate code for each symbol into the table.
  342.      */
  343.     if (!table) return 0;
  344.     if (!Via(table)->count) return 0;
  345.     FreeAllRegs();        /* Is this necessary ? */
  346.     /* Then, we generate code for everything. */
  347.     ndx = 0;
  348.     while (ndx < Via(table)->tablesize) {
  349.     tmp = Via(Via(table)->hashtable)[ndx++];
  350.     while (tmp) {
  351.         if (Flush) {
  352.         GenSymbol(tmp, Codes);
  353.         } else {
  354.         if (Via(tmp)->storage_class != SCC_extern) {
  355.             GenSymbol(tmp, Codes);
  356.         }
  357.         }
  358.         tmp = Via(tmp)->next;
  359.     }
  360.     }
  361.     GenSegments(Codes);
  362.     GenStringLits(Codes);
  363.     GenFloatLits(Codes);
  364.     GenStatics(Codes);
  365.  
  366.     return Via(table)->count;
  367. }
  368.  
  369. void
  370. GenStringLits(InstListVia_t Codes)
  371. {
  372.     int                             ndx;
  373.     SYMVia_t                        tmp;
  374.     ndx = 0;
  375.     if (Via(StringLits)->count) {
  376.         while (ndx < Via(StringLits)->tablesize) {
  377.         tmp = Via(Via(StringLits)->hashtable)[ndx++];
  378.             while (tmp) {
  379.                 GenOneLit(tmp, Codes);
  380.                 tmp = Via(tmp)->next;
  381.             }
  382.         }
  383.     }
  384. }
  385.  
  386. void
  387. GenStatics(InstListVia_t Codes)
  388. /* Loop to generate all the static variables. */
  389. {
  390.     int                             ndx;
  391.     SYMVia_t                        tmp;
  392.     ndx = 0;
  393.     if (Via(StaticTable)->count) {
  394.         while (ndx < Via(StaticTable)->tablesize) {
  395.         tmp = Via(Via(StaticTable)->hashtable)[ndx++];
  396.         while (tmp) {
  397.             if (!(Via(tmp)->SymbolFlags & CODEOUTPUT)) {
  398.                 GenInst(M68op_DSEG, M68sz_none, NULL, NULL, Codes);
  399.                 Via(tmp)->SymbolFlags |= CODEOUTPUT;
  400.                 GenDataLabel(GetLocLabel(Via(tmp)->M68kDef.Loc), Codes);
  401.                 GenInst(M68op_DS, M68sz_byte,
  402.                     BuildAbsolute(GetTPSize(Via(tmp)->TP)), NULL, Codes);
  403.             }
  404.             tmp = Via(tmp)->next;
  405.         }
  406.         }
  407.     }
  408. }
  409.  
  410. void
  411. Free2Locals(SymListVia_t list, InstListVia_t Codes)
  412. {
  413.     int                             ndx;
  414.     SYMVia_t                        tmp;
  415.     ndx = 0;
  416.     while (ndx < Via(list)->tablesize) {
  417.     tmp = Via(Via(list)->hashtable)[ndx++];
  418.     while (tmp) {
  419.         FreeIt(Via(tmp)->M68kDef.Loc);
  420.         tmp = Via(tmp)->next;
  421.     }
  422.     }
  423. }
  424.  
  425. TypeRecordVia_t
  426. GetSymTP(SYMVia_t s)
  427. {
  428.     assert(s);
  429.     return Via(s)->TP;
  430. }
  431.  
  432. void
  433. SetSymTP(SYMVia_t s, TypeRecordVia_t TP)
  434. {
  435.     assert(s);
  436.     Via(s)->TP = TP;
  437. }
  438.  
  439. void
  440. GetSymName(SYMVia_t s, char *nm)
  441. {
  442.     assert(s);
  443.     assert(nm);
  444.     strcpy(nm, Via(s)->name);
  445. }
  446.  
  447. void
  448. SetSymFlags(SYMVia_t s, unsigned short f)
  449. {
  450.     assert(s);
  451.     Via(s)->SymbolFlags = f;
  452. }
  453.  
  454. unsigned short
  455. GetSymFlags(SYMVia_t s)
  456. {
  457.     assert(s);
  458.     return Via(s)->SymbolFlags;
  459. }
  460.