Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
w2cf_symtab.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 /* ====================================================================
00037  * ====================================================================
00038  *
00039  *
00040  * Revision history:
00041  *  07-Oct-95 - Original Version
00042  *
00043  * Description:
00044  *
00045  *   The primary aim of this module is to provide an interface through
00046  *   which we can maintain a stack of symbol-tables used to disambiguate
00047  *   names.  To ensure the same naming of the same symbol in two 
00048  *   independent sessions with this module, the sequence of names 
00049  *   entered prior to that symbol must be identical for the two
00050  *   sessions.
00051  *
00052  *   The central idea here is that symbols are disambiguated by adding
00053  *   a numerical suffix to them.  For this reason, numerical suffices
00054  *   must be removed from names before hashing into the symbol-table.
00055  *   This way we only need to search through the bucket into which we
00056  *   land to find an unambigeous name (with added numerical suffix) for
00057  *   a given symbol.  The names without their disambiguating numerical 
00058  *   suffices are termed "base_names" in all subsequent comments in
00059  *   this file.
00060  *
00061  *   The datastructure maintained here consists of a stack of hash-
00062  *   tables, each hash-table bucket contains exactly one element for
00063  *   each different base_name that hash to that bucket.  Each bucket
00064  *   entry is a list of entries for symbols with the same base_name,
00065  *   sorted on the disambiguating numerical suffix.  We impose a hard-
00066  *   coded limit to the number of characters that may occur in a 
00067  *   base-name, where this limit may be overridden by a smaller limit
00068  *   by a user of this module.
00069  *
00070  * ====================================================================
00071  * ====================================================================
00072  */
00073 #ifdef _KEEP_RCS_ID
00074 #endif /* _KEEP_RCS_ID */
00075 
00076 #include <ctype.h>
00077 #include <string.h>
00078 
00079 #include "common_include.h"
00080 
00081 #include "mempool.h"
00082 #include "unparse_target.h"
00083 #include "w2cf_symtab.h"
00084 
00085 /*------------ Typedefs for the symtab datastructure ------------------*
00086  *---------------------------------------------------------------------*/
00087 
00088 #define MAX_LABEL_NUMBER 99999U
00089 
00090 typedef UINT32 W2CF_STR_IDX;
00091 typedef struct W2CF_Stringbuf W2CF_STRINGBUF;
00092 struct W2CF_Stringbuf
00093 {
00094    W2CF_STR_IDX size;      /* The size of the allocated string buffer */
00095    W2CF_STR_IDX next_char; /* The next character available for allocation */
00096    char        *chars;     /* The allocated string buffer */
00097 }; /* W2CF_Stringbuf */
00098 #define W2CF_STRINGBUF_size(s) (s).size
00099 #define W2CF_STRINGBUF_next_char(s) (s).next_char
00100 #define W2CF_STRINGBUF_chars(s) (s).chars
00101 
00102 
00103 typedef struct W2CF_Symtab W2CF_SYMTAB;
00104 typedef struct W2CF_Symtab_Stack 
00105 {
00106    W2CF_SYMTAB *top;    /* The top of the stack (deepest nested symtab) */
00107    W2CF_SYMTAB *bot;    /* The outermost (global) symtab */
00108 } W2CF_SYMTAB_STACK;
00109 #define W2CF_SYMTAB_STACK_top(s) (s).top
00110 #define W2CF_SYMTAB_STACK_bot(s) (s).bot
00111 
00112 
00113 typedef struct W2CF_Symhdr W2CF_SYMHDR;
00114 struct W2CF_Symtab
00115 {
00116    UINT32         unique_label; /* Unique label number for this scope */
00117    INT32          size;     /* Number of elements in allocated hash_tbl */
00118    W2CF_SYMHDR  **hash_tbl; /* The allocated buckets of symbol headers */
00119    W2CF_STRINGBUF strbuf;   /* A string buffer for this symbol table */
00120    W2CF_SYMTAB   *up;       /* The symtab at an outer level of nesting */
00121    W2CF_SYMTAB   *down;     /* The symtab at a deeper level of nesting */
00122 }; /* W2CF_Symtab */
00123 #define W2CF_SYMTAB_unique_label(s) (s)->unique_label
00124 #define W2CF_SYMTAB_size(s) (s)->size
00125 #define W2CF_SYMTAB_hash_tbl(s) (s)->hash_tbl
00126 #define W2CF_SYMTAB_strbuf(s) (s)->strbuf
00127 #define W2CF_SYMTAB_up(s) (s)->up
00128 #define W2CF_SYMTAB_down(s) (s)->down
00129 #define W2CF_SYMTAB_next(s) (s)->down /* For free-list */
00130 
00131 
00132 typedef struct W2CF_Symbol W2CF_SYMBOL;
00133 struct W2CF_Symhdr
00134 {
00135    UINT64       hashval;       /* The hashvalue for the basename */
00136    INT32        next_symid;    /* The smallest available symid available */
00137    W2CF_STR_IDX basename;      /* The basename index */
00138    W2CF_SYMBOL *symbol;        /* A list of symbols with this "name" */
00139    W2CF_SYMHDR *next;          /* The next symbol header in this bucket */
00140 }; /* W2CF_Symhdr */
00141 #define W2CF_SYMHDR_hashval(s) (s)->hashval
00142 #define W2CF_SYMHDR_next_symid(s) (s)->next_symid
00143 #define W2CF_SYMHDR_basename(s) (s)->basename
00144 #define W2CF_SYMHDR_symbol(s) (s)->symbol
00145 #define W2CF_SYMHDR_next(s) (s)->next
00146 
00147 extern BOOL Run_w2f;     /* Defined in be.so */
00148 extern BOOL Run_w2c;     /* Defined in be.so */
00149 
00150 typedef enum W2CF_Symbol_Kind
00151 {
00152    SYMKIND_UNKNOWN,     
00153    SYMKIND_UNIQUE,
00154    SYMKIND_FLD,
00155    SYMKIND_FLD_POINTEE,
00156    SYMKIND_TY,
00157    SYMKIND_ST,
00158    SYMKIND_ST_POINTEE,
00159    SYMKIND_TEMPVAR,
00160    SYMKIND_PREG
00161 } W2CF_SYMBOL_KIND;
00162 
00163 
00164 struct W2CF_Symbol
00165 {
00166    W2CF_SYMBOL_KIND kind;  /* The kind of symbol */
00167    INT32            symid; /* A unique id number for this symbol */
00168    W2CF_STR_IDX     name;  /* The full symbol name, including symid suffix */
00169    W2CF_SYMBOL     *next;  /* The next symbol with the same basename */
00170    union
00171    {
00172       FLD_IDX    fld;        /* SYMKIND_FLD */
00173       FLD_IDX    fld_ptr;    /* SYMKIND_FLD_POINTEE */
00174       TY_IDX     ty;         /* SYMKIND_TY */
00175       const ST  *st;         /* SYMKIND_ST */
00176       const ST  *st_ptr;     /* SYMKIND_ST_POINTEE  */
00177       INT32      tempvar_id; /* SYMKIND_TEMPVAR */
00178       struct
00179       {
00180          TY_IDX   preg_ty;
00181 
00182          PREG_NUM preg_num;
00183       } preg;           /* SYMKIND_PREG */
00184    } attr;
00185 }; /* W2CF_Symbol */
00186 #define W2CF_SYMBOL_kind(s) (s)->kind
00187 #define W2CF_SYMBOL_symid(s) (s)->symid
00188 #define W2CF_SYMBOL_name(s) (s)->name
00189 #define W2CF_SYMBOL_next(s) (s)->next
00190 #define W2CF_SYMBOL_attr(s) (s)->attr
00191 #define W2CF_SYMBOL_fld(s) (s)->attr.fld
00192 #define W2CF_SYMBOL_fld_ptr(s) (s)->attr.fld_ptr
00193 #define W2CF_SYMBOL_ty(s) (s)->attr.ty
00194 #define W2CF_SYMBOL_st(s) (s)->attr.st
00195 #define W2CF_SYMBOL_st_ptr(s) (s)->attr.st_ptr
00196 #define W2CF_SYMBOL_tempvar_id(s) (s)->attr.tempvar_id
00197 
00198 
00199 #define W2CF_SYMBOL_preg_ty(s) (s)->attr.preg.preg_ty
00200 #define W2CF_SYMBOL_preg_num(s) (s)->attr.preg.preg_num
00201 
00202 /* Some macros used to interpret symbol symids
00203  */
00204 #define W2CF_INVALID_SYMID -2
00205 #define W2CF_FIRST_VALID_SYMID -1
00206 #define W2CF_NOSUFFIX_SYMID W2CF_FIRST_VALID_SYMID
00207 
00208 
00209 static void W2CF_Dump_Symbol(W2CF_SYMBOL *sym,W2CF_SYMTAB *symtab=NULL);
00210 static void W2CF_Dump_Symtab(W2CF_SYMTAB *symtab) ;
00211 static void W2CF_Dump_Symhdr(W2CF_SYMHDR *symhdr,W2CF_SYMTAB *symtab=NULL) ;
00212 
00213 /*---------- The symtab state and some generalized macros -------------*
00214  *---------------------------------------------------------------------*/
00215 
00216 
00217 /* Define some limits.
00218  */
00219 #define INITIAL_STRING_BUFFER_SIZE 1024
00220 #define INITIAL_SYMTAB_SIZE 1024
00221 
00222 
00223 /* Define some helper macros.
00224  */
00225 #define W2CF_SYMTAB_strbuf_size(s) \
00226    W2CF_STRINGBUF_size(W2CF_SYMTAB_strbuf(s))
00227 #define W2CF_SYMTAB_strbuf_next(s) \
00228    W2CF_STRINGBUF_next_char(W2CF_SYMTAB_strbuf(s))
00229 #define W2CF_SYMTAB_strbuf_chars(s) \
00230    W2CF_STRINGBUF_chars(W2CF_SYMTAB_strbuf(s))
00231 
00232 #define W2CF_SYMHDR_basename_string(symtab, symhdr) \
00233    &W2CF_SYMTAB_strbuf_chars(symtab)[W2CF_SYMHDR_basename(symhdr)]
00234 #define W2CF_SYMBOL_name_string(symtab, symbol) \
00235    &W2CF_SYMTAB_strbuf_chars(symtab)[W2CF_SYMBOL_name(symbol)]
00236 
00237 
00238 /* Define the local state.
00239  */
00240 static W2CF_SYMTAB_STACK  Symtab_Stack = {NULL, NULL};
00241 static W2CF_SYMTAB       *Symtab_Free_List = NULL;
00242 static W2CF_SYMHDR       *Symhdr_Free_List = NULL;
00243 static W2CF_SYMBOL       *Symbol_Free_List = NULL;
00244 
00245 static const char W2CF_Anonymous_Fld[] = "fld";
00246 static const char W2CF_Anonymous_Ty[] = "ty";
00247 static const char W2CF_Anonymous_St[] = "anon";
00248 static const char W2CF_Anonymous_Tempvar[] = "tmp";
00249 static const char W2CF_Anonymous_Preg[] = "reg";
00250 
00251 
00252 /*----------------- Character string manipulation ---------------------*
00253  *---------------------------------------------------------------------*/
00254 
00255 static W2CF_STR_IDX
00256 W2CF_Symtab_Alloc_Chars(W2CF_SYMTAB *symtab, UINT32 size)
00257 {
00258    /* Allocate a character string of the given size in the given
00259     * symbol table.  PRECONDITION: size > 0!
00260     */
00261    UINT32 new_bufsize = W2CF_SYMTAB_strbuf_size(symtab);
00262    UINT32 next_char = W2CF_SYMTAB_strbuf_next(symtab);
00263 
00264    /* First see if we overflow the string buffer, and if so (re)allocate
00265     * it such that a character string of desired size can be allocated.
00266     */
00267    while (new_bufsize < next_char + size)
00268       new_bufsize += new_bufsize/2 + INITIAL_STRING_BUFFER_SIZE;
00269 
00270    if (W2CF_SYMTAB_strbuf_size(symtab) == 0)
00271    {
00272       W2CF_SYMTAB_strbuf_chars(symtab) = TYPE_ALLOC_N(char, new_bufsize);
00273    }
00274    else if (new_bufsize > W2CF_SYMTAB_strbuf_size(symtab))
00275    {
00276       W2CF_SYMTAB_strbuf_chars(symtab) = 
00277          TYPE_REALLOC_N(char, 
00278                         W2CF_SYMTAB_strbuf_chars(symtab), 
00279                         W2CF_SYMTAB_strbuf_size(symtab), 
00280                         new_bufsize);
00281    }
00282    W2CF_SYMTAB_strbuf_size(symtab) = new_bufsize;
00283    W2CF_SYMTAB_strbuf_next(symtab) += size;
00284 
00285    return next_char;
00286 } /* W2CF_Symtab_Alloc_Chars */
00287 
00288 
00289 static void
00290 W2CF_Get_Basename(const char *original_name, char *basename, INT32 *sym_id)
00291 {
00292    /* This just cuts the original name down to size, removes any
00293     * numeric suffix, and puts the resultant name into the basename
00294     * and the numeric suffix into sym_id.  When there is no numeric 
00295     * suffix, sym_id is returned as W2CF_INVALID_SYMID.
00296     */
00297 #define MAX_NUMERIC_SUFFIX_SIZE 8 /* fits into a UINT32 */
00298 
00299    const char *valid_name = W2X_Unparse_Target->Make_Valid_Name(original_name,TRUE);
00300    INT32       name_size, suffix_size;
00301    UINT32      numeric_suffix = 0;
00302    UINT32      suffix_exponent;
00303    
00304    /* Copy the valid characters into the buffer */
00305    for (name_size = 0; valid_name[name_size] != '\0'; name_size++)
00306       basename[name_size] = valid_name[name_size];
00307 
00308    /* Remove the numeric suffix and record its value */
00309    for (suffix_size = 0, name_size--, suffix_exponent = 1; 
00310         (name_size >= 0                         && 
00311          suffix_size <= MAX_NUMERIC_SUFFIX_SIZE && 
00312          isdigit(basename[name_size]));
00313         suffix_size++, name_size--, suffix_exponent *= 10)
00314    {
00315       numeric_suffix += suffix_exponent*(basename[name_size] - '0');
00316    }
00317    while (name_size >= 0 && isdigit(basename[name_size]))
00318       name_size--; /* Remove redundant suffix digits */
00319    while (basename[name_size+1] == '0' && suffix_size > 0)
00320    {
00321       suffix_size--;
00322       name_size++; /* Append back in zeros preceeding the numeric suffix */
00323    }
00324    
00325    basename[name_size+1] = '\0';
00326    if (suffix_size > 0)
00327       *sym_id = numeric_suffix;
00328    else
00329       *sym_id = W2CF_INVALID_SYMID;
00330 } /* W2CF_Get_Basename */
00331 
00332 
00333 /*-------------- Hidden functions for symtab manipulation -------------*
00334  *---------------------------------------------------------------------*/
00335 
00336 
00337 static BOOL
00338 W2CF_Avoid_Suffix(W2CF_SYMBOL *symbol )
00339 {
00340 
00341   BOOL avoid = FALSE;
00342 
00343   if (W2X_Unparse_Target->Avoid_Common_Suffix ()) {
00344     if (W2CF_SYMBOL_kind(symbol) == SYMKIND_ST) {
00345       const ST * st = W2CF_SYMBOL_st(symbol);
00346       if (Stab_Is_Common_Block(st))
00347       avoid = TRUE;
00348     }
00349   }
00350 
00351   //WEI: shouldn't suffixs  be avoided for TY entries???
00352   if (Compile_Upc) {
00353     if (W2CF_SYMBOL_kind(symbol) == SYMKIND_TY) {
00354       avoid = TRUE;
00355     }
00356   }
00357 
00358   return avoid;
00359 }
00360 
00361 static BOOL
00362 W2CF_Identical_Symkinds(W2CF_SYMBOL *sym1, W2CF_SYMBOL *sym2)
00363 {
00364    BOOL identical = W2CF_SYMBOL_kind(sym1) == W2CF_SYMBOL_kind(sym2);
00365    
00366    if (identical/*kinds*/)
00367    {
00368       switch (W2CF_SYMBOL_kind(sym1))
00369       {
00370       case SYMKIND_UNIQUE:
00371          identical = FALSE;
00372          break;
00373       case SYMKIND_FLD:
00374          identical = W2CF_SYMBOL_fld(sym1) == W2CF_SYMBOL_fld(sym2);
00375          break;
00376       case SYMKIND_FLD_POINTEE:
00377          identical = W2CF_SYMBOL_fld_ptr(sym1) == W2CF_SYMBOL_fld_ptr(sym2);
00378          break;
00379       case SYMKIND_TY:
00380          identical = W2CF_SYMBOL_ty(sym1) == W2CF_SYMBOL_ty(sym2);
00381          break;
00382       case SYMKIND_ST:
00383          identical = W2CF_SYMBOL_st(sym1) == W2CF_SYMBOL_st(sym2);
00384          break;
00385       case SYMKIND_ST_POINTEE:
00386          identical = W2CF_SYMBOL_st_ptr(sym1) == W2CF_SYMBOL_st_ptr(sym2);
00387          break;
00388       case SYMKIND_TEMPVAR:
00389          identical = 
00390             W2CF_SYMBOL_tempvar_id(sym1) == W2CF_SYMBOL_tempvar_id(sym2);
00391          break;
00392       case SYMKIND_PREG:
00393          identical = 
00394             (W2CF_SYMBOL_preg_num(sym1) == W2CF_SYMBOL_preg_num(sym2) &&
00395              W2CF_SYMBOL_preg_ty(sym1) == W2CF_SYMBOL_preg_ty(sym2));
00396          break;
00397       default:
00398          Is_True(FALSE, ("Illegal W2CF_SYMKIND"));
00399          break;
00400       } /*switch*/
00401    } /*if*/
00402 
00403    return identical;
00404    
00405 } /* W2CF_Identical_Symkinds */
00406 
00407 
00408 static void
00409 W2CF_Insert_Symbol(W2CF_SYMHDR *symhdr, 
00410                    W2CF_SYMBOL *symbol)
00411 {
00412    /* Insert the symbol into the symbol-list associated with the given
00413     * symbol header.  The symbols are in order of increasing symids.
00414     * If the symbol has an INVALID or already used symid, then we create
00415     * a new one for it and update the symbol accordingly.
00416     */
00417    W2CF_SYMBOL *before_sym, *after_sym;
00418    INT32        symid;
00419    INT32        next_symid;
00420 
00421    /* The "next_symid" is a lower bound on new symids, so adjust
00422     * the symid accordingly.
00423     */
00424    symid = W2CF_SYMBOL_symid(symbol);
00425    if (symid < W2CF_SYMHDR_next_symid(symhdr))
00426       symid = W2CF_SYMHDR_next_symid(symhdr);
00427 
00428    /* Find the insertion point for this new symbol. 
00429     */
00430    for ((before_sym = W2CF_SYMHDR_symbol(symhdr), after_sym = NULL);
00431         before_sym != NULL && W2CF_SYMBOL_symid(before_sym) < symid;
00432         (after_sym = before_sym, before_sym = W2CF_SYMBOL_next(after_sym)));
00433    
00434    if (before_sym != NULL && W2CF_SYMBOL_symid(before_sym) == symid)
00435    {
00436       /* Another symbol was found with the same symid, which means
00437        * the symid cannot have been the next_symid.  Instead of
00438        * using a user-defined symid, use the next_symid. Note that
00439        * next_symid is guaranteed not to clash with any symbols
00440        * in this or any outer symbol-table.
00441        */
00442       symid = W2CF_SYMHDR_next_symid(symhdr);
00443       for ((before_sym = W2CF_SYMHDR_symbol(symhdr), after_sym = NULL);
00444            before_sym != NULL && W2CF_SYMBOL_symid(before_sym) < symid;
00445            (after_sym = before_sym, before_sym = W2CF_SYMBOL_next(after_sym)));
00446    }
00447 
00448    /* Update the symid and insert the symbol.
00449     */
00450    W2CF_SYMBOL_symid(symbol) = symid;
00451    W2CF_SYMBOL_next(symbol) = before_sym;
00452    if (after_sym == NULL)
00453       W2CF_SYMHDR_symbol(symhdr) = symbol;
00454    else
00455       W2CF_SYMBOL_next(after_sym) = symbol;
00456    
00457    /* Update next_symid if necessary.  Note that the next
00458     * next_symid always is larger than or equal to its former
00459     * value.
00460     */
00461    if (symid == W2CF_SYMHDR_next_symid(symhdr))
00462    {
00463       next_symid = symid + 1;
00464       for (before_sym = W2CF_SYMHDR_symbol(symhdr);
00465            before_sym != NULL && W2CF_SYMBOL_symid(before_sym) <= next_symid;
00466            before_sym = W2CF_SYMBOL_next(before_sym))
00467       {
00468          if (W2CF_SYMBOL_symid(before_sym) == next_symid)
00469             next_symid++;
00470       }
00471       W2CF_SYMHDR_next_symid(symhdr) = next_symid;
00472    }
00473 
00474 } /* W2CF_Insert_Symbol */
00475 
00476 
00477 static W2CF_SYMHDR *
00478 W2CF_Search_Symhdr(W2CF_SYMTAB *symtab, const char *basename)
00479 {
00480    /* Return NULL when there is no symhdr with the given basename
00481     * in the given symtab.  We make no assumptions about any ordering
00482     * of symhdrs hashing to the same symbol table entry. 
00483     */
00484    const UINT64 hashval = Get_Hash_Value_For_Name(basename);
00485    const UINT32 hashidx = Name_Hash_Idx(hashval, W2CF_SYMTAB_size(symtab));
00486    W2CF_SYMHDR *symhdr;
00487    
00488    /* Get the matching symhdr if one exists */
00489    for (symhdr = W2CF_SYMTAB_hash_tbl(symtab)[hashidx];
00490         (symhdr != NULL && 
00491          (hashval != W2CF_SYMHDR_hashval(symhdr) ||
00492           strcmp(basename, W2CF_SYMHDR_basename_string(symtab, symhdr)) != 0));
00493         symhdr = W2CF_SYMHDR_next(symhdr));
00494 
00495    return symhdr;
00496 
00497 } /* W2CF_Search_Symhdr */
00498 
00499 
00500 static W2CF_SYMBOL *
00501 W2CF_Search_Symbol(W2CF_SYMHDR *symhdr, W2CF_SYMBOL *match_symbol)
00502 {
00503    /* Return NULL when there is no symbol matching the symkind and
00504     * associated attributes of the given match_symbol.
00505     */
00506    W2CF_SYMBOL *symbol;
00507    
00508    /* Get the matching symbol, if one exists */
00509    for (symbol = W2CF_SYMHDR_symbol(symhdr);
00510         symbol != NULL && !W2CF_Identical_Symkinds(symbol, match_symbol);
00511         symbol = W2CF_SYMBOL_next(symbol));
00512    
00513    return symbol;
00514 } /* W2CF_Search_Symbol */
00515 
00516 
00517 static W2CF_SYMHDR *
00518 W2CF_Create_Symhdr(W2CF_SYMTAB *symtab, const char *basename)
00519 {
00520    /* Create a symbol header with the given basename.  The symtab will 
00521     * be updated to account for the new symbol header.  It is assumed
00522     * that no other symhdr exists in the symtab with the same basename.
00523     */
00524    const UINT64 hashval = Get_Hash_Value_For_Name(basename);
00525    const UINT32 hashidx = Name_Hash_Idx(hashval, W2CF_SYMTAB_size(symtab));
00526    W2CF_SYMHDR *symhdr = TYPE_ALLOC_N(W2CF_SYMHDR, 1);
00527    W2CF_SYMTAB *symtab2;
00528    W2CF_SYMHDR *symhdr2;
00529    W2CF_SYMBOL *symbol2;
00530    
00531    /* Initiate the new symhdr */
00532    W2CF_SYMHDR_next(symhdr) = W2CF_SYMTAB_hash_tbl(symtab)[hashidx];
00533    W2CF_SYMHDR_next_symid(symhdr) = W2CF_FIRST_VALID_SYMID;
00534    W2CF_SYMHDR_symbol(symhdr) = 0;
00535    W2CF_SYMHDR_symbol(symhdr) = 0;
00536    W2CF_SYMHDR_hashval(symhdr) = hashval;
00537    W2CF_SYMHDR_basename(symhdr) = 
00538       W2CF_Symtab_Alloc_Chars(symtab, strlen(basename)+1);
00539    
00540    (void)strcpy(W2CF_SYMHDR_basename_string(symtab, symhdr), basename);
00541 
00542    /* Insert the symhdr into the hash-table */
00543    W2CF_SYMTAB_hash_tbl(symtab)[hashidx] = symhdr;
00544 
00545    /* Ensure the the next_symid is outside the range of symids
00546     * in outer scope symbol-tables.
00547     */
00548    symtab2 = W2CF_SYMTAB_up(symtab);
00549    while (symtab2 != NULL)
00550    {
00551       symhdr2 = W2CF_Search_Symhdr(symtab2, basename);
00552       if (symhdr2 != NULL)
00553       {
00554          symbol2 = W2CF_SYMHDR_symbol(symhdr2);
00555          if (symbol2 != NULL)
00556          {
00557             /* Walk to the last symbol in the list (largest symid) */
00558             while (W2CF_SYMBOL_next(symbol2) != NULL) 
00559                symbol2 = W2CF_SYMBOL_next(symbol2);
00560 
00561             /* Set the symbol ids for this symbol to begin beyond
00562              * the range symids in any outer scopes!
00563              */
00564             if (W2CF_SYMBOL_symid(symbol2) >= W2CF_SYMHDR_next_symid(symhdr))
00565                 W2CF_SYMHDR_next_symid(symhdr) = W2CF_SYMBOL_symid(symbol2)+1;
00566          }
00567       }
00568       symtab2 = W2CF_SYMTAB_up(symtab2);
00569    } /* while more symtabs */
00570 
00571    return symhdr;
00572 } /* W2CF_Create_Symhdr */
00573 
00574 
00575 static W2CF_SYMBOL *
00576 W2CF_Create_Symbol(W2CF_SYMTAB *symtab, 
00577                    W2CF_SYMHDR *symhdr, 
00578                    W2CF_SYMBOL *match_symbol)
00579 {
00580    /* Create a symbol based at the given symhdr and with the symid,
00581     * symkind and associated attributes as specified by the match_
00582     * symbol.  If the symid is W2CF_INVALID_SYMID, then invent a 
00583     * new symid.
00584     */
00585    W2CF_SYMBOL *symbol = TYPE_ALLOC_N(W2CF_SYMBOL, 1);
00586    char        *symname;
00587 
00588    W2CF_SYMBOL_kind(symbol) = W2CF_SYMBOL_kind(match_symbol);
00589    W2CF_SYMBOL_attr(symbol) = W2CF_SYMBOL_attr(match_symbol);
00590    W2CF_SYMBOL_symid(symbol) = W2CF_SYMBOL_symid(match_symbol);
00591 
00592    /* Insert the symbol under the given symbol header, possibly 
00593     * changing the symid if it is already in use or is invalid.
00594     */
00595    W2CF_Insert_Symbol(symhdr, symbol);
00596 
00597    /* The symbol name will be constructed from the basename and the
00598     * the symbol identifier.
00599     */
00600 
00601    if (W2CF_SYMBOL_symid(symbol) == W2CF_NOSUFFIX_SYMID)
00602    {
00603       W2CF_SYMBOL_name(symbol) = W2CF_SYMHDR_basename(symhdr);
00604    }
00605    else
00606    {
00607      symname = W2CF_SYMHDR_basename_string(symtab, symhdr);
00608 
00609      if (!W2CF_Avoid_Suffix(symbol))
00610      {
00611        symname = Get_Name_Buf_Slot(strlen(symname) + 32);
00612        sprintf(symname, "%s%d",
00613                W2CF_SYMHDR_basename_string(symtab, symhdr), 
00614                W2CF_SYMBOL_symid(symbol));
00615      }
00616      W2CF_SYMBOL_name(symbol) = W2CF_Symtab_Alloc_Chars(symtab, strlen(symname)+1);
00617      (void)strcpy(W2CF_SYMBOL_name_string(symtab, symbol), symname);
00618    }
00619 
00620    //   W2CF_Dump_Symhdr(symhdr,symtab);
00621 
00622    return symbol;
00623 
00624 } /* W2CF_Create_Symbol */
00625 
00626 
00627 static void
00628 W2CF_Get_Symbol(W2CF_SYMTAB **found_symtab,
00629                 W2CF_SYMHDR **found_symhdr,
00630                 W2CF_SYMBOL **found_symbol,
00631                 W2CF_SYMBOL  *match_symbol,
00632                 const char   *basename)
00633 {
00634    /* This function searches for a symbol with the given basename and
00635     * symbol attributes and, if found, returns it; otherwise it inserts
00636     * a new symbol table entry and returns that.  The W2CF_SYMBOL_kind()
00637     * and W2CF_SYMBOL_attr() must have been set appropriately in 
00638     * match_symbol.
00639     */
00640    W2CF_SYMTAB *symtab;
00641    W2CF_SYMHDR *symhdr = NULL;
00642    W2CF_SYMBOL *symbol = NULL;
00643    W2CF_SYMHDR *top_symhdr;
00644    
00645    /* First, check to see if the given symbol is represented somewhere
00646     * on the top of the symbol-table stack.
00647     */
00648    symtab = W2CF_SYMTAB_STACK_top(Symtab_Stack);
00649    top_symhdr = W2CF_Search_Symhdr(symtab, basename);
00650    if (top_symhdr != NULL)
00651       symbol = W2CF_Search_Symbol(top_symhdr, match_symbol);
00652 
00653    /* If the given symbol cannot be found at the top of the stack,
00654     * then search through outer levels of scope-nesting.
00655     */
00656    symtab = W2CF_SYMTAB_up(symtab);
00657    while (symtab != NULL && symbol == NULL)
00658    {
00659       symhdr = W2CF_Search_Symhdr(symtab, basename);
00660       if (symhdr != NULL)
00661          symbol = W2CF_Search_Symbol(symhdr, match_symbol);
00662       symtab = W2CF_SYMTAB_up(symtab);
00663    }
00664 
00665    /* Restore the symtab to where the symbol is (or will be) found.
00666     */
00667    if (symtab != NULL)
00668       symtab = W2CF_SYMTAB_down(symtab);            /* Found local symbol */
00669    else if (symbol != NULL)
00670       symtab = W2CF_SYMTAB_STACK_bot(Symtab_Stack); /* Found global symbol */
00671    else
00672       symtab = W2CF_SYMTAB_STACK_top(Symtab_Stack); /* Did not find symbol */
00673 
00674    /* If no symbol was found, then create one.  Symtab is already set to
00675     * the most deeply nested one.
00676     */
00677    if (symbol == NULL)
00678    {
00679       if (top_symhdr == NULL)
00680          symhdr = W2CF_Create_Symhdr(symtab, basename);
00681       else
00682          symhdr = top_symhdr;
00683       symbol = W2CF_Create_Symbol(symtab, symhdr, match_symbol);
00684    }
00685    *found_symtab = symtab;
00686    *found_symhdr = symhdr;
00687    *found_symbol = symbol;
00688 } /* W2CF_Get_Symbol */
00689 
00690 
00691 /*------------ Exported functions for symtab manipulation -------------*
00692  *---------------------------------------------------------------------*/
00693 
00694 
00695 void
00696 W2CF_Symtab_Push(void)
00697 {
00698    /* Create a new symbol-table entry and push it onto the stack */
00699    W2CF_SYMTAB *symtab;
00700    INT32        hash_idx;
00701 
00702    if (Symtab_Free_List == NULL)
00703    {
00704       symtab = TYPE_ALLOC_N(W2CF_SYMTAB, 1);
00705       W2CF_SYMTAB_strbuf_size(symtab) = 0;
00706       W2CF_SYMTAB_strbuf_next(symtab) = 0;
00707       W2CF_SYMTAB_strbuf_chars(symtab) = NULL;
00708       W2CF_SYMTAB_hash_tbl(symtab) = 
00709          TYPE_ALLOC_N(W2CF_SYMHDR*, INITIAL_SYMTAB_SIZE);
00710       W2CF_SYMTAB_size(symtab) = INITIAL_SYMTAB_SIZE;
00711       for (hash_idx = 0; hash_idx < INITIAL_SYMTAB_SIZE; hash_idx++)
00712          W2CF_SYMTAB_hash_tbl(symtab)[hash_idx] = NULL;
00713    }
00714    else
00715    {
00716       /* Reuse the symbol-table entry and its string buffer */
00717       symtab = Symtab_Free_List;
00718       W2CF_SYMTAB_strbuf_next(symtab) = 0;
00719       Symtab_Free_List = W2CF_SYMTAB_down(Symtab_Free_List);
00720    }
00721    W2CF_SYMTAB_unique_label(symtab) = MAX_LABEL_NUMBER;
00722    W2CF_SYMTAB_down(symtab) = NULL;
00723    W2CF_SYMTAB_up(symtab) = W2CF_SYMTAB_STACK_top(Symtab_Stack);
00724    if (W2CF_SYMTAB_STACK_top(Symtab_Stack) != NULL)
00725       W2CF_SYMTAB_down(W2CF_SYMTAB_STACK_top(Symtab_Stack)) = symtab;
00726 
00727    W2CF_SYMTAB_STACK_top(Symtab_Stack) = symtab;
00728    if (W2CF_SYMTAB_STACK_bot(Symtab_Stack) == NULL)
00729       W2CF_SYMTAB_STACK_bot(Symtab_Stack) = symtab;
00730 
00731 } /* W2CF_Symtab_Push */
00732 
00733 
00734 
00735 void
00736 W2CF_Symtab_Pop(void)
00737 {
00738    /* Put the SYMTAB and its SYMHDRs and the SYMBOLs onto free-lists.
00739     * The string-buffer and the hash-table belongs to the SYMTAB, 
00740     * even when the SYMTAB is on the free-list.  To free up all of 
00741     * this from memory, instead of putting it on free-list, call:
00742     *
00743     *   W2CF_Symtab_Terminate()
00744     */
00745    W2CF_SYMTAB *symtab = W2CF_SYMTAB_STACK_top(Symtab_Stack);
00746    W2CF_SYMHDR *symhdr;
00747    W2CF_SYMBOL *symbol;
00748    INT32        tbl_idx;
00749 
00750    /* The new top of the stack is the symbol-table above the current
00751     * one in the scope-nesting.
00752     */
00753    W2CF_SYMTAB_STACK_top(Symtab_Stack) = W2CF_SYMTAB_up(symtab);
00754 
00755    /* The new top of the stack has no symbol table at a deeper level
00756     * of scope-nesting.
00757     */
00758    if (W2CF_SYMTAB_STACK_top(Symtab_Stack) != NULL)
00759       W2CF_SYMTAB_down(W2CF_SYMTAB_STACK_top(Symtab_Stack)) = NULL;
00760    else
00761       W2CF_SYMTAB_STACK_bot(Symtab_Stack) = NULL;
00762 
00763    /* Add the popped symtab to the free-list 
00764     */
00765    W2CF_SYMTAB_next(symtab) = Symtab_Free_List;
00766    Symtab_Free_List = symtab;
00767 
00768    /* Next put the symhdrs and the symbols on free lists 
00769     */
00770    for (tbl_idx = 0; tbl_idx < W2CF_SYMTAB_size(symtab); tbl_idx++)
00771    {
00772       symhdr = W2CF_SYMTAB_hash_tbl(symtab)[tbl_idx];
00773       while (W2CF_SYMTAB_hash_tbl(symtab)[tbl_idx] != NULL)
00774       {
00775          symhdr = W2CF_SYMTAB_hash_tbl(symtab)[tbl_idx];
00776          W2CF_SYMTAB_hash_tbl(symtab)[tbl_idx] = W2CF_SYMHDR_next(symhdr);
00777          W2CF_SYMHDR_next(symhdr) = Symhdr_Free_List;
00778          Symhdr_Free_List = symhdr;
00779          while (W2CF_SYMHDR_symbol(symhdr) != NULL)
00780          {
00781             symbol = W2CF_SYMHDR_symbol(symhdr);
00782             W2CF_SYMHDR_symbol(symhdr) = W2CF_SYMBOL_next(symbol);
00783             W2CF_SYMBOL_next(symbol) = Symbol_Free_List;
00784             Symbol_Free_List = symbol;
00785          } /* while there are no more symbols under this symhdr */
00786       } /* while there are no more symhdrs in the bucket */
00787    } /* for each element in the hash-table */
00788 } /* W2CF_Symtab_Pop */
00789 
00790 
00791 const char * 
00792 W2CF_Symtab_Nameof_St(const ST *st)
00793 {
00794    const char  *valid_name = NULL ;
00795    char        *symname;
00796    INT32        symid;
00797    W2CF_SYMTAB *symtab;
00798    W2CF_SYMHDR *symhdr;
00799    W2CF_SYMBOL *symbol;
00800    W2CF_SYMBOL  match_symbol;
00801    
00802    /* Get the valid version of the name in basename form and its numeric
00803     * suffix (symid).  Create a name-buffer large enough to hold the
00804     * name appended to the suffix (hence the "+32").
00805     */
00806  
00807    if (ST_sym_class(st) != CLASS_CONST) 
00808            valid_name = W2X_Unparse_Target->Make_Valid_Name(ST_name(st),!ST_is_temp_var(st));
00809 
00810    if (valid_name == NULL || valid_name[0] == '\0')
00811    {
00812       valid_name = W2CF_Anonymous_St;
00813    }
00814    else
00815    {
00816       valid_name = W2X_Unparse_Target->Get_St_Name(st, valid_name);
00817    }
00818 
00819    //WEI: again, don't think there's any reason to rename function names
00820    if (ST_sym_class(st) == CLASS_FUNC) {
00821      return valid_name;
00822    }
00823 
00824    symname = Get_Name_Buf_Slot(strlen(valid_name) + 32);
00825    W2CF_Get_Basename(valid_name, symname, &symid);
00826    
00827    /* Get the associated symbol entry (with a possibly modified symid).
00828     */
00829    W2CF_SYMBOL_symid(&match_symbol) = symid;
00830    W2CF_SYMBOL_kind(&match_symbol)  = SYMKIND_ST;
00831    W2CF_SYMBOL_st(&match_symbol)    = st;
00832    W2CF_Get_Symbol(&symtab, &symhdr, &symbol, &match_symbol, symname);
00833    
00834    /* Return the resultant disambiguated name */
00835 if (Run_w2f)
00836    return valid_name; // fzhao change to keep original name
00837 else
00838    return W2CF_SYMBOL_name_string(symtab, symbol);
00839    
00840 } /* W2CF_Symtab_Nameof_St */
00841 
00842 
00843 const char * 
00844 W2CF_Symtab_Nameof_St_Pointee(const ST *st)
00845 {
00846    const char  *pointee_name;
00847    char        *symname;
00848    INT32        symid;
00849    W2CF_SYMTAB *symtab;
00850    W2CF_SYMHDR *symhdr;
00851    W2CF_SYMBOL *symbol;
00852    W2CF_SYMBOL  match_symbol;
00853    
00854    /* Get the valid version of the name in basename form and its numeric
00855     * suffix (symid).  Create a name-buffer large enough to hold the
00856     * name appended to the suffix (hence the "+32").
00857     */
00858    //pointee_name = Concat2_Strings("deref_", W2CF_Symtab_Nameof_St(st));
00859    pointee_name = W2CF_Symtab_Nameof_St(st);
00860    symname = Get_Name_Buf_Slot(strlen(pointee_name) + 32);
00861    W2CF_Get_Basename(pointee_name, symname, &symid);
00862    
00863    /* Get the associated symbol entry (with a possibly modified symid).
00864     */
00865    W2CF_SYMBOL_symid(&match_symbol)  = symid;
00866    W2CF_SYMBOL_kind(&match_symbol)   = SYMKIND_ST_POINTEE;
00867    W2CF_SYMBOL_st_ptr(&match_symbol) = st;
00868    W2CF_Get_Symbol(&symtab, &symhdr, &symbol, &match_symbol, symname);
00869    
00870    /* Return the resultant disambiguated name */
00871    if (Run_w2f)
00872      return pointee_name;
00873    else
00874      return W2CF_SYMBOL_name_string(symtab, symbol);
00875    // the above does:    W2CF_SYMTAB_strbuf_chars(symtab)[W2CF_SYMBOL_name(symbol)]
00876 
00877 } /* W2CF_Symtab_Nameof_St_Pointee */
00878 
00879 
00880 const char * 
00881 W2CF_Symtab_Nameof_Ty(TY_IDX ty)
00882 {
00883    const char  *valid_name;
00884    char        *symname;
00885    INT32        symid;
00886    W2CF_SYMTAB *symtab;
00887    W2CF_SYMHDR *symhdr;
00888    W2CF_SYMBOL *symbol;
00889    W2CF_SYMBOL  match_symbol;
00890    
00891    /* Get the valid version of the name in basename form and its numeric
00892     * suffix (symid).  Create a name-buffer large enough to hold the
00893     * name appended to the suffix (hence the "+32").
00894     */
00895    valid_name = W2X_Unparse_Target->Make_Valid_Name(TY_name(ty),FALSE);
00896    if (valid_name == NULL || valid_name[0] == '\0')
00897    {
00898       valid_name = W2CF_Anonymous_Ty;
00899    }
00900    symname = Get_Name_Buf_Slot(strlen(valid_name) + 32);
00901    W2CF_Get_Basename(valid_name, symname, &symid);
00902    
00903    /* Get the associated symbol entry (with a possibly modified symid).
00904     */
00905    W2CF_SYMBOL_symid(&match_symbol) = symid;
00906    W2CF_SYMBOL_kind(&match_symbol)  = SYMKIND_TY;
00907    W2CF_SYMBOL_ty(&match_symbol)    = ty;
00908    W2CF_Get_Symbol(&symtab, &symhdr, &symbol, &match_symbol, symname);
00909 
00910    //WEI: for anonymous structs, we output the valid_name directly
00911    //(so different structs will have different names)
00912    if (Compile_Upc) {
00913      if (strncmp(valid_name, "anonymous", 9) == 0) {
00914        //cout << valid_name << " " << ty << endl;
00915        return valid_name;
00916      }
00917    }
00918    
00919    /* Return the resultant disambiguated name */
00920     return valid_name; 
00921 //    return W2CF_SYMBOL_name_string(symtab, symbol);
00922    
00923 } /* W2CF_Symtab_Nameof_Ty */
00924 
00925 
00926 const char * 
00927 W2CF_Symtab_Nameof_Fld(FLD_HANDLE fld)
00928 {
00929    const char  *valid_name;
00930    char        *symname;
00931    INT32        symid;
00932    W2CF_SYMTAB *symtab;
00933    W2CF_SYMHDR *symhdr;
00934    W2CF_SYMBOL *symbol;
00935    W2CF_SYMBOL  match_symbol;
00936    
00937    /* Get the valid version of the name in basename form and its numeric
00938     * suffix (symid).  Create a name-buffer large enough to hold the
00939     * name appended to the suffix (hence the "+32").
00940     */
00941    valid_name = W2X_Unparse_Target->Make_Valid_Name(FLD_name(fld),FALSE);
00942    if (valid_name == NULL || valid_name[0] == '\0')
00943    {
00944       valid_name = W2CF_Anonymous_Fld;
00945    }
00946    symname = Get_Name_Buf_Slot(strlen(valid_name) + 32);
00947    W2CF_Get_Basename(valid_name, symname, &symid);
00948 
00949    if (Compile_Upc) {
00950      return valid_name;
00951    }
00952    //WEI: is this really necessary? I think there's no need to rename fields in a struct
00953    //(How could you possibly get conflicts?)
00954 
00955    /* Get the associated symbol entry (with a possibly modified symid).
00956     */
00957    W2CF_SYMBOL_symid(&match_symbol) = symid;
00958    W2CF_SYMBOL_kind(&match_symbol)  = SYMKIND_FLD;
00959    W2CF_SYMBOL_fld(&match_symbol)   = fld.Idx ();
00960    W2CF_Get_Symbol(&symtab, &symhdr, &symbol, &match_symbol, symname);
00961    
00962    /* Return the resultant disambiguated name */
00963 //if (Run_w2f)
00964    return valid_name;
00965 //else
00966 //   return W2CF_SYMBOL_name_string(symtab, symbol);
00967    
00968 } /* W2CF_Symtab_Nameof_Fld */
00969 
00970 
00971 const char *
00972 W2CF_Symtab_Nameof_Fld_Pointee(FLD_HANDLE fld)
00973 {
00974    const char  *pointee_name;
00975    char        *symname;
00976    INT32        symid;
00977    W2CF_SYMTAB *symtab;
00978    W2CF_SYMHDR *symhdr;
00979    W2CF_SYMBOL *symbol;
00980    W2CF_SYMBOL  match_symbol;
00981    
00982    /* Get the valid version of the name in basename form and its numeric
00983     * suffix (symid).  Create a name-buffer large enough to hold the
00984     * name appended to the suffix (hence the "+32").
00985     */
00986    //pointee_name = Concat2_Strings("deref_", W2CF_Symtab_Nameof_Fld(fld));
00987    pointee_name = W2CF_Symtab_Nameof_Fld(fld);
00988    symname = Get_Name_Buf_Slot(strlen(pointee_name) + 32);
00989    W2CF_Get_Basename(pointee_name, symname, &symid);
00990    
00991    /* Get the associated symbol entry (with a possibly modified symid).
00992     */
00993    W2CF_SYMBOL_symid(&match_symbol)   = symid;
00994    W2CF_SYMBOL_kind(&match_symbol)    = SYMKIND_FLD_POINTEE;
00995    W2CF_SYMBOL_fld_ptr(&match_symbol) = fld.Idx ();
00996    W2CF_Get_Symbol(&symtab, &symhdr, &symbol, &match_symbol, symname);
00997    
00998    /* Return the resultant disambiguated name */
00999    return W2CF_SYMBOL_name_string(symtab, symbol);
01000    
01001 } /* W2CF_Symtab_Nameof_Fld_Pointee */
01002 
01003 
01004 const char *
01005 W2CF_Symtab_Nameof_Tempvar(INT32 tempvar_id)
01006 {
01007    char        *symname;
01008    char        *tmpvarname;
01009    INT32        symid;
01010    W2CF_SYMTAB *symtab;
01011    W2CF_SYMHDR *symhdr;
01012    W2CF_SYMBOL *symbol;
01013    W2CF_SYMBOL  match_symbol;
01014    
01015    /* Get the valid version of the name in basename form and its numeric
01016     * suffix (symid).  Create a name-buffer large enough to hold the
01017     * name appended to the suffix (hence the "+32").
01018     */
01019    tmpvarname = Get_Name_Buf_Slot(strlen(W2CF_Anonymous_Tempvar) + 32);
01020    sprintf(tmpvarname, "%s%d", W2CF_Anonymous_Tempvar, tempvar_id);
01021    symname = Get_Name_Buf_Slot(strlen(tmpvarname) + 32);
01022    W2CF_Get_Basename(tmpvarname, symname, &symid);
01023    
01024    /* Get the associated symbol entry (with a possibly modified symid).
01025     */
01026    W2CF_SYMBOL_symid(&match_symbol)      = symid;
01027    W2CF_SYMBOL_kind(&match_symbol)       = SYMKIND_TEMPVAR;
01028    W2CF_SYMBOL_tempvar_id(&match_symbol) = tempvar_id;
01029    W2CF_Get_Symbol(&symtab, &symhdr, &symbol, &match_symbol, symname);
01030    
01031    /* Return the resultant disambiguated name */
01032    return W2CF_SYMBOL_name_string(symtab, symbol);
01033    
01034 } /* W2CF_Symtab_Nameof_Tempvar */
01035 
01036 
01037 const char *
01038 W2CF_Symtab_Nameof_Preg(const TY_IDX preg_ty, PREG_NUM preg_num)
01039 {
01040    const char  *valid_name;
01041    char        *symname;
01042    INT32        symid;
01043    W2CF_SYMTAB *symtab;
01044    W2CF_SYMHDR *symhdr;
01045    W2CF_SYMBOL *symbol;
01046    W2CF_SYMBOL  match_symbol;
01047    
01048    /* Get the valid version of the name in basename form and its numeric
01049     * suffix (symid).  Create a name-buffer large enough to hold the
01050     * name appended to the suffix (hence the "+32").
01051     */
01052    valid_name = (preg_num > Last_Dedicated_Preg_Offset) 
01053       ? Preg_Name(preg_num) : NULL; 
01054    char buffer[64];
01055    if (valid_name == NULL && preg_ty == 0) {
01056      sprintf(buffer, "reg%d", preg_num);
01057      valid_name = buffer;
01058    }
01059    valid_name = W2X_Unparse_Target->Make_Valid_Name(valid_name,FALSE);
01060    if (valid_name == NULL || valid_name[0] == '\0')
01061    {
01062       symname = Get_Name_Buf_Slot(strlen(W2CF_Anonymous_Preg) + 32);
01063       sprintf(symname, "%s%d", W2CF_Anonymous_Preg, preg_num);
01064       valid_name = symname;
01065    }
01066    symname = Get_Name_Buf_Slot(strlen(valid_name) + 32);
01067    W2CF_Get_Basename(valid_name, symname, &symid);
01068    
01069    /* Get the associated symbol entry (with a possibly modified symid).
01070     */
01071    W2CF_SYMBOL_symid(&match_symbol)    = symid;
01072    W2CF_SYMBOL_kind(&match_symbol)     = SYMKIND_PREG;
01073    W2CF_SYMBOL_preg_ty(&match_symbol)  = preg_ty;
01074    W2CF_SYMBOL_preg_num(&match_symbol) = preg_num;
01075    W2CF_Get_Symbol(&symtab, &symhdr, &symbol, &match_symbol, symname);
01076    
01077    /* Return the resultant disambiguated name */
01078    return W2CF_SYMBOL_name_string(symtab, symbol);
01079    
01080 } /* W2CF_Symtab_Nameof_Preg */
01081 
01082 
01083 const char *
01084 W2CF_Symtab_Unique_Name(const char *name)
01085 {
01086    const char  *valid_name;
01087    char        *unique_name;
01088    INT32        symid;
01089    W2CF_SYMTAB *symtab;
01090    W2CF_SYMHDR *symhdr;
01091    W2CF_SYMBOL *symbol;
01092    W2CF_SYMBOL  match_symbol;
01093    
01094    /* Get the valid version of the name in basename form and its numeric
01095     * suffix (symid).  Create a name-buffer large enough to hold the
01096     * name appended to the suffix (hence the "+32").
01097     */
01098    valid_name = W2X_Unparse_Target->Make_Valid_Name(name,TRUE);
01099    if (valid_name == NULL || valid_name[0] == '\0')
01100       valid_name = W2CF_Anonymous_St;
01101    unique_name = Get_Name_Buf_Slot(strlen(valid_name) + 32);
01102    W2CF_Get_Basename(valid_name, unique_name, &symid);
01103    
01104    /* Get the associated symbol entry (with a possibly modified symid).
01105     */
01106    W2CF_SYMBOL_symid(&match_symbol)    = symid;
01107    W2CF_SYMBOL_kind(&match_symbol)     = SYMKIND_UNIQUE;
01108    W2CF_Get_Symbol(&symtab, &symhdr, &symbol, &match_symbol, unique_name);
01109    
01110    /* Return the resultant disambiguated name */
01111    return W2CF_SYMBOL_name_string(symtab, symbol);
01112    
01113 } /* W2CF_Symtab_Unique_Name */
01114 
01115 
01116 UINT32 
01117 W2CF_Symtab_Unique_Label(void)
01118 {
01119    return W2CF_SYMTAB_unique_label(W2CF_SYMTAB_STACK_top(Symtab_Stack))--;
01120 } /* W2CF_Symtab_Unique_Label */
01121 
01122 
01123 void
01124 W2CF_Symtab_Free(void)
01125 {
01126    /* Free up all symbol-table objects allocated, but not currently
01127     * in use.
01128     */
01129    W2CF_SYMTAB *symtab;
01130    W2CF_SYMHDR *symhdr;
01131    W2CF_SYMBOL *symbol;
01132 
01133    while (Symtab_Free_List != NULL)
01134    {
01135       symtab = Symtab_Free_List;
01136       Symtab_Free_List = W2CF_SYMTAB_next(symtab);
01137       FREE(W2CF_SYMTAB_hash_tbl(symtab));
01138       if (W2CF_SYMTAB_strbuf_chars(symtab) != NULL)
01139          FREE(W2CF_SYMTAB_strbuf_chars(symtab));
01140       FREE(symtab);
01141    }
01142    
01143    while (Symhdr_Free_List != NULL)
01144    {
01145       symhdr = Symhdr_Free_List;
01146       Symhdr_Free_List = W2CF_SYMHDR_next(symhdr);
01147       FREE(symhdr);
01148    }
01149    
01150    while (Symbol_Free_List != NULL)
01151    {
01152       symbol = Symbol_Free_List;
01153       Symbol_Free_List = W2CF_SYMBOL_next(symbol);
01154       FREE(symbol);
01155    }
01156 } /* W2CF_Symtab_Free */
01157 
01158 
01159 void
01160 W2CF_Symtab_Terminate(void)
01161 {   
01162    /* Pop all elements off the symbol table stack, thereby putting
01163     * all SYMTABs, all SYMHDRs, and all SYMBOLs on their respective
01164     * free-lists.
01165     */
01166    while (W2CF_SYMTAB_STACK_top(Symtab_Stack) != NULL)
01167       W2CF_Symtab_Pop();
01168 
01169    W2CF_Symtab_Free();
01170 } /* W2CF_Symtab_Terminate */
01171 
01172 
01173 /*---------- Dump routines --------------------------------------------*/
01174 /*---------------------------------------------------------------------*/
01175 
01176 static void 
01177 W2CF_Dump_Symhdr(W2CF_SYMHDR *symhdr,W2CF_SYMTAB *symtab)
01178 {
01179 
01180   if (symhdr != 0) 
01181   {
01182     printf ("symhdr: 0x%p, hashval=0x%llx, next_symid=%d, next_symhdr=0x%p \n",
01183             symhdr,
01184             W2CF_SYMHDR_hashval(symhdr),
01185             W2CF_SYMHDR_next_symid(symhdr),
01186             W2CF_SYMHDR_next(symhdr));
01187 
01188     if (symtab != NULL)
01189       printf ("    basename: %s \n",W2CF_SYMHDR_basename_string(symtab, symhdr)); 
01190     
01191     W2CF_SYMBOL *sym = W2CF_SYMHDR_symbol(symhdr);
01192     while (sym != NULL) 
01193     {
01194       W2CF_Dump_Symbol(sym,NULL);
01195       sym = W2CF_SYMBOL_next(sym);
01196     }
01197   }
01198 }
01199 
01200 static void 
01201 W2CF_Dump_Symtab(W2CF_SYMTAB *symtab)
01202 {
01203   if (symtab != 0) 
01204   {
01205     printf ("symtab: 0x%p, label=%d, num=%d, hash_tbl=0x%p, up=0x%p, down=0x%p next=0x%p\n",  
01206             symtab,
01207             W2CF_SYMTAB_unique_label(symtab),
01208             W2CF_SYMTAB_size(symtab),
01209             W2CF_SYMTAB_hash_tbl(symtab),
01210             W2CF_SYMTAB_up(symtab),
01211             W2CF_SYMTAB_down(symtab),
01212             W2CF_SYMTAB_next(symtab));
01213 
01214     W2CF_STRINGBUF str = W2CF_SYMTAB_strbuf(symtab);
01215 
01216     printf ("         strbuf: size=%d, next=0x%x chars=0x%p\n",
01217             W2CF_STRINGBUF_size(str), 
01218             W2CF_STRINGBUF_next_char(str),
01219             W2CF_STRINGBUF_chars(str));
01220 
01221     char * p = W2CF_STRINGBUF_chars(str);
01222     char * e = p + W2CF_STRINGBUF_next_char(str);
01223 
01224     while (p < e) 
01225     {
01226       printf("            %s\n",p);
01227       p += strlen(p) + 1;
01228     }
01229   }
01230 }
01231 
01232 static void 
01233 W2CF_Dump_Symbol(W2CF_SYMBOL *sym,W2CF_SYMTAB *symtab)
01234 {
01235   if (sym != NULL) 
01236   {
01237     const char * hdr = "          ";
01238 
01239     W2CF_STR_IDX nm = W2CF_SYMBOL_name(sym);   
01240 
01241     printf ("    symbol: 0x%p, id=%d, next=0x%p, str_idx 0x%d",
01242             sym,
01243             W2CF_SYMBOL_symid(sym),
01244             W2CF_SYMBOL_next(sym),
01245             nm);
01246 
01247     if (symtab != NULL) 
01248     {
01249       printf (", name %s",W2CF_SYMBOL_name_string(symtab,sym));
01250     }
01251     printf(" \n");
01252 
01253    switch(W2CF_SYMBOL_kind(sym))
01254    {
01255    case SYMKIND_UNIQUE:
01256      printf("%s unique",hdr);
01257      break;
01258    case SYMKIND_FLD:
01259    {
01260      FLD_HANDLE fld(W2CF_SYMBOL_fld(sym));
01261      printf("%s FLD 0x%x %s",hdr,W2CF_SYMBOL_fld(sym),FLD_name(fld));
01262      break; 
01263    }
01264    case SYMKIND_TY:
01265    {
01266      TY_IDX ty = W2CF_SYMBOL_ty(sym);
01267      printf("%s TY 0x%x %s",hdr,TY_IDX_index(ty),TY_name(ty));
01268      break;
01269    }
01270    case SYMKIND_ST:
01271    {
01272      const ST * st = W2CF_SYMBOL_st(sym);
01273      printf("%s ST 0x%p %s",hdr,st,ST_name(st));
01274      break;
01275    }
01276    case SYMKIND_PREG:
01277    {
01278      TY_IDX  ty = W2CF_SYMBOL_preg_ty(sym);  
01279      printf("%s PREG num 0x%x ty 0x%x %s",hdr,W2CF_SYMBOL_preg_num(sym),TY_IDX_index(ty),TY_name(ty));
01280      break;
01281    }
01282    default:
01283      printf("???");
01284      break;
01285    }
01286    printf("\n") ;
01287   }
01288 }
01289 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines