OpenADFortTk (basic)
src/lib/support/Open64IRInterface/stab_attr.cpp
Go to the documentation of this file.
00001 // -*-Mode: C++;-*-
00002 #include "Open64BasicTypes.h"
00003 
00004 //*************************** User Include Files ****************************
00005 
00006 #include "stab_attr.h"
00007 
00008 //************************** Forward Declarations ***************************
00009 
00010 static BOOL
00011 Stab_Compare_Types(TY_IDX t1, TY_IDX t2, BOOL check_quals, 
00012                    BOOL check_pointed_quals, BOOL check_scalars,
00013                    BOOL ptrs_as_scalars, BOOL assign_t2_to_t1);
00014 
00015 #define TYPE_ALLOC_N(type, count)\
00016    TYPE_MEM_POOL_ALLOC_N(type, Malloc_Mem_Pool, count)
00017 
00018 #define TYPE_REALLOC_N(type, old_ptr, old_count, new_count)\
00019    TYPE_MEM_POOL_REALLOC_N(type, Malloc_Mem_Pool, old_ptr,\
00020                            old_count, new_count)
00021 
00022 #define FREE(ptr) MEM_POOL_FREE(Malloc_Mem_Pool, ptr)
00023 
00024 //***************************************************************************
00025 
00026 // REMOVE/FIXME
00027 
00028 /*-------------------- Global SYMTAB table sizes --------------------
00029  *
00030  * We record the size of certain tables in the global symtab at whirl2c
00031  * initialization.  This information is then used later on in whirl2c
00032  * finialization to reset the tables back to their original size and
00033  * thus undo any additions made to these tables during whirl2c.
00034  *
00035  *--------------------------------------------------------------------*/
00036 
00037 extern void Stab_initialize(void);
00038 extern void Stab_finalize(void);
00039 
00040 void
00041 Stab_initialize(void)
00042 {
00043    /* Record the original size of the Ty_Table, Fld_Table, Arb_Table,
00044       and Tylist_Table - per PU */
00045 
00046 } /* Stab_Initialize */
00047 
00048 void
00049 Stab_finalize(void)
00050 {
00051    /* Should ideally reset the Ty_Table, Fld_Table, Arb_Table, 
00052     * Tylist_Table and strtab (?) back to their original size at the 
00053     * start of whirl2c.  This is should also include resetting any 
00054     * references to such deleted symtab entries (e.g. TY_pointed).
00055     * For now we do not do so.
00056     */
00057 
00058 } /* Stab_finalize */
00059 
00060 
00061 void
00062 Stab_Reset_Referenced_Flag(SYMTAB_IDX symtab)
00063 {
00064   /* Reset the ST_is_referenced() flag for all symbols and constants
00065    * in the given symbol table.  Note that if this is done for the
00066    * global symbol-table for every PU (as I believe is necessary for
00067    * Fortran), we have an O(n^2 + m) algorithm where "n" is the number
00068    * of global symbols and "m" is the number of local PU symbols.
00069    */
00070   
00071   ST_IDX    st_idx;
00072   const ST* st;
00073   
00074   FOREACH_SYMBOL(symtab, st, st_idx)
00075     Clear_BE_ST_w2fc_referenced(st);
00076   
00077 } /* Stab_Reset_Referenced_Flag */
00078 
00079 
00080 //***************************************************************************
00081 // Active Information
00082 //***************************************************************************
00083 
00084 bool
00085 IsActivePU(ST* pu_st)
00086 {
00087   bool active = true;
00088 
00089   TY_IDX pu_ty = ST_pu_type(pu_st);
00090   TY_IDX pu_ret_ty = TY_ret_type(pu_ty);
00091 
00092   if (ST_is_in_module(pu_st) && !PU_is_nested_func(Pu_Table[ST_pu(pu_st)])) {
00093     active = false; // module
00094   } 
00095   else if (pu_ret_ty != 0 && TY_kind(pu_ret_ty) != KIND_VOID) {
00096     active = false; // function
00097   }
00098   
00099   // assume subroutines are all active
00100   
00101   return active;
00102 }
00103 
00104 
00105 //***************************************************************************
00106 // Type Information
00107 //***************************************************************************
00108 
00109 BOOL
00110 Stab_Identical_Types(TY_IDX t1, TY_IDX t2, BOOL check_quals, 
00111                      BOOL check_scalars, BOOL ptrs_as_scalars)
00112 {
00113    /* Compare the two types on an equal basis. */
00114    return Stab_Compare_Types(t1, t2, check_quals, FALSE,
00115                              check_scalars, ptrs_as_scalars, FALSE);
00116 }
00117 
00118 
00119 BOOL
00120 Stab_Assignment_Compatible_Types(TY_IDX t1, TY_IDX t2, BOOL check_quals, 
00121                                  BOOL check_scalars, BOOL ptrs_as_scalars)
00122 {
00123    /* Compare the two types for assignment compatibility, assuming
00124     * a value of type t2 will be assigned to a location of type t1. */
00125    return Stab_Compare_Types(t1, t2, check_quals, FALSE, 
00126                              check_scalars, ptrs_as_scalars, TRUE);
00127 }
00128 
00129 bool
00130 WN2F_Can_Assign_Types(TY_IDX ty1, TY_IDX ty2)
00131 {
00132   bool simple = Stab_Identical_Types(ty1, ty2, FALSE, /*check_quals*/
00133                                      FALSE, /*check_scalars*/ 
00134                                      TRUE); /*ptrs_as_scalars*/
00135   bool special = (TY_Is_Array(ty1) && TY_is_character(ty1) && 
00136                   TY_Is_Array(ty2) && TY_is_character(ty2));
00137   return (simple || special);
00138 }
00139 
00140 
00141 static BOOL
00142 Stab_Compare_Types(TY_IDX t1, TY_IDX t2, BOOL check_quals, 
00143                    BOOL check_pointed_quals, BOOL check_scalars,
00144                    BOOL ptrs_as_scalars, BOOL assign_t2_to_t1)
00145 {
00146    /* Two types compare if they have the same qualifiers, compatible
00147     * kinds, compatible MTYPEs, and identical substructure.  ENUM
00148     * types are treated as scalars.  While constructed types must
00149     * have identical substructure, we allow more lenient checks for
00150     * the top-level types:  We can turn off qualifier checks 
00151     * (check_quals == FALSE); we can treat all scalar values as 
00152     * identical (check_scalars == FALSE); and we can treat pointers
00153     * as scalars (ptrs_as_scalars == TRUE).
00154     *
00155     * This routine can be adopted to the particular needs of whirl2c,
00156     * and as such is not implemented in terms of Equivalent_Types()
00157     * in common/com/ttype.h.
00158     */
00159   INT i; /* Array dimensions */
00160 
00161   if (t1 == t2)
00162      return TRUE;
00163   else if (TY_kind(t1) == KIND_INVALID || 
00164            TY_kind(t2) == KIND_INVALID ||
00165            (check_quals && !Stab_Identical_Quals(t1, t2)) ||
00166            (check_pointed_quals && 
00167             !Stab_Assign_Compatible_Pointer_Quals(t1, t2)))
00168      return FALSE;
00169   else
00170   {
00171      switch (TY_kind(t1))
00172      {
00173      case KIND_VOID:
00174         return TY_kind(t2) == KIND_VOID; /* Must be identical kinds */
00175 
00176      case KIND_SCALAR:
00177         if (TY_Is_String(t1) && TY_Is_Array_Of_Chars(t2))
00178            return TRUE;
00179         else if (ptrs_as_scalars)
00180            return (TY_Is_Pointer_Or_Scalar(t2) &&
00181                    (!check_scalars || TY_mtype(t1) == TY_mtype(t2)));
00182         else
00183            return (TY_Is_Scalar(t2) &&
00184                    (!check_scalars || TY_mtype(t1) == TY_mtype(t2)));
00185 
00186      case KIND_POINTER:
00187         /* Should we also consider MTYPE_STRING identical to a (char*)? */
00188         if (ptrs_as_scalars)
00189            return (TY_Is_Pointer_Or_Scalar(t2) &&
00190                    (!check_scalars || TY_mtype(t1) == TY_mtype(t2)));
00191         else
00192            return 
00193               (TY_Is_Pointer(t2) &&
00194                (TY_kind(TY_pointed(t1)) == KIND_VOID ||
00195                 TY_kind(TY_pointed(t2)) == KIND_VOID ||
00196                 Stab_Compare_Types(
00197                    TY_pointed(t1), 
00198                    TY_pointed(t2), 
00199                    !assign_t2_to_t1,/* check_quals */
00200                    assign_t2_to_t1,/* check_pointed_quals */
00201                    TRUE,           /* check_scalars */
00202                    FALSE,          /* ptrs_as_scalars */
00203                    FALSE)));       /* assign_t2_to_t1 */
00204 
00205      case KIND_FUNCTION:
00206         /* We do a very quick check to see if two function types are
00207          * identical.  A more elaborate, but slower, method will check
00208          * each individual parameter type (TY_parms(t1) and TY_parms(t2))
00209          * for identity.
00210          */
00211         return (TY_Is_Function(t2)                           &&
00212                 TY_has_prototype(t1) == TY_has_prototype(t2) &&
00213                 TY_is_varargs(t1) == TY_is_varargs(t2)       &&
00214                 TY_parms(t1) == TY_parms(t2)                 &&
00215                 Stab_Compare_Types(Func_Return_Type(t1), 
00216                                    Func_Return_Type(t2),
00217                                    TRUE,  /* check_quals */
00218                                    FALSE, /* check_pointed_quals */
00219                                    TRUE,  /* check_scalars */
00220                                    FALSE, /* ptrs_as_scalars */
00221                                    FALSE) /* assign_t2_to_t1 */
00222                 );
00223 
00224      case KIND_ARRAY:
00225         if (TY_Is_String(t2) && TY_Is_Array_Of_Chars(t1))
00226            return TRUE;
00227         else if (!TY_Is_Array(t2) ||
00228                  TY_AR_ndims(t1) != TY_AR_ndims(t2))
00229            return FALSE;
00230         else
00231         {
00232            for (i=0; i<TY_AR_ndims(t1); i++)
00233            {
00234               /* First check if one constant and the other not;
00235                * then check if constants don't match; we assume
00236                * dynamic bounds/strides always match since we
00237                * implement them in terms of pointers in C.
00238                */
00239               if (TY_AR_const_lbnd(t1,i) != TY_AR_const_lbnd(t2,i) ||
00240                   TY_AR_const_ubnd(t1,i) != TY_AR_const_ubnd(t2,i) ||
00241                   TY_AR_const_stride(t1,i) != TY_AR_const_stride(t2,i))
00242                  return FALSE;
00243               else if (TY_AR_const_lbnd(t1,i) &&
00244                        (TY_AR_lbnd_val(t1,i) != TY_AR_lbnd_val(t2,i)))
00245                  return FALSE;
00246               else if (TY_AR_const_ubnd(t1,i) &&
00247                        (TY_AR_ubnd_val(t1,i) != TY_AR_ubnd_val(t2,i)))
00248                  return FALSE;
00249               else if (TY_AR_const_stride(t1,i) &&
00250                     (TY_AR_stride_val(t1,i) != TY_AR_stride_val(t2,i)))
00251                  return FALSE;
00252            }
00253            return Stab_Compare_Types(TY_AR_etype(t1), 
00254                                      TY_AR_etype(t2),
00255                                      TRUE,   /* check_quals */
00256                                      FALSE,  /* check_pointed_quals */
00257                                      TRUE,   /* check_scalars */
00258                                      FALSE,  /* ptrs_as_scalars */
00259                                      FALSE); /* assign_t2_to_t1 */
00260         }
00261 
00262      case KIND_STRUCT:
00263         return (TY_Is_Structured(t2) &&
00264                 TY_flist(Ty_Table[t1]) == TY_flist(Ty_Table[t2]));
00265 
00266      default:
00267         ErrMsg ( EC_Invalid_Case, "Stab_Compare_Types", __LINE__ );
00268         return FALSE;
00269      }
00270   }
00271 } /* Stab_Compare_Types */
00272 
00273 
00274 //***************************************************************************
00275 
00276 BOOL 
00277 Stab_Is_Element_Type_Of_Array(TY_IDX atype, TY_IDX etype)
00278 {
00279    if (Stab_Assignment_Compatible_Types(etype, TY_AR_etype(atype), 
00280                                         FALSE, /*check_quals*/
00281                                         TRUE,  /*check_scalars*/
00282                                         FALSE)) /*ptrs_as_scalars*/
00283       return TRUE;
00284    else if (TY_Is_Array(TY_AR_etype(atype)))
00285       return Stab_Is_Element_Type_Of_Array(TY_AR_etype(atype), etype);
00286    else
00287       return FALSE;
00288 } /* Stab_Is_Element_Type_Of_Array */
00289 
00290 
00291 BOOL
00292 Stab_Array_Has_Dynamic_Bounds(TY_IDX ty)
00293 {
00294    INT32 dim;
00295    BOOL is_const = TRUE;
00296    
00297    for (dim = 0; dim < TY_AR_ndims(ty); dim++)
00298    {
00299       is_const = (is_const                  &&
00300                   TY_AR_const_lbnd(ty, dim) &&
00301                   TY_AR_const_ubnd(ty, dim) &&
00302                   TY_AR_const_stride(ty, dim));
00303    }
00304    return !is_const;
00305 } /* Stab_Array_Has_Dynamic_Bounds */
00306 
00307 
00308 BOOL
00309 Stab_Is_Assumed_Sized_Array(TY_IDX ty)
00310 {
00311    BOOL assumed_size = FALSE;
00312 
00313    if (TY_Is_Array(ty))
00314    {
00315       /* Only the last bound may be assumed sized.  Multi-dimensional
00316        * arrays in whirl are represented in row-major order (as in
00317        * C/C++).  Therefore, check the first dimension in the TY which
00318        * is the last Fortran dimension.
00319        */
00320       ARB_HANDLE arb = TY_arb(ty);
00321       
00322       if (ARB_const_lbnd(arb) && 
00323           ARB_const_ubnd(arb) &&
00324           (ARB_ubnd_val(arb) - ARB_lbnd_val(arb) <= 0))
00325       {
00326          assumed_size = TRUE;
00327       }
00328       else if ((!ARB_const_lbnd(arb) && ARB_lbnd_var(arb) == (ST_IDX) 0) ||
00329                (!ARB_const_ubnd(arb) && ARB_ubnd_var(arb) == (ST_IDX) 0))
00330       {
00331          assumed_size = TRUE;
00332       }
00333    }
00334    return assumed_size;
00335 } /* Stab_Is_Assumed_Sized_Array */
00336 
00337 
00338 BOOL 
00339 Stab_Is_Equivalenced_Struct(TY_IDX ty)
00340 {
00341    FLD_ITER fld_iter = Make_fld_iter (TY_flist(Ty_Table[ty]));
00342    BOOL is_equivalent_fld = FALSE;
00343 
00344    do {
00345        FLD_HANDLE fld (fld_iter);
00346        is_equivalent_fld = FLD_equivalence (fld);
00347    } while (!FLD_last_field (fld_iter++) && !is_equivalent_fld);
00348        
00349    return is_equivalent_fld;
00350 } /* Stab_Is_Equivalenced_Struct */
00351 
00352 
00353 TY_IDX
00354 Stab_Get_Mload_Ty(TY_IDX base, STAB_OFFSET offset, STAB_OFFSET size)
00355 {
00356    /* Just try to find a field of the given size at the given offset.
00357     * The base should be a struct or union type Return the base
00358     * when it has the desired size or a size of zero (unknown size)
00359     */
00360    TY_IDX ty;
00361    
00362    Is_True(TY_Is_Structured(base),
00363            ("Expected pointer to struct/union type in TY2C_Get_Mload_Ty()"));
00364    Is_True((INT64)TY_size(base) <= size,
00365            ("Expected struct/union type >= size in TY2C_Get_Mload_Ty()"));
00366    
00367    if ((INT64)TY_size(base) == size ||
00368        (TY_size(base) == 0 && TY_flist(Ty_Table[base]).Is_Null ()))
00369    {
00370       /* End of recursive descent into the structure, so return
00371        * the base type.
00372        */
00373       ty = base;
00374    }
00375    else
00376    {
00377       /* Get the field we wish to access, then apply this algorithm
00378        * recursively.
00379        */
00380       Is_True(!TY_flist(Ty_Table[base]).Is_Null (),
00381               ("Expected non-empty field list in TY2C_Get_Mload_Ty()"));
00382       
00383       FLD_HANDLE this_fld = TY_flist(Ty_Table[base]);
00384       FLD_HANDLE next_fld = FLD_next(this_fld);
00385       if (TY_Is_Union(base))
00386       {
00387          /* Search for a struct or union field of the expected size */
00388          while (! next_fld.Is_Null () &&
00389                 (!TY_Is_Structured(FLD_type(this_fld)) ||
00390                  (INT64)TY_size(FLD_type(this_fld)) < size))
00391          {
00392             this_fld = next_fld;
00393             next_fld = FLD_next(next_fld);
00394          }
00395       }
00396       else /* TY_Is_Struct(TY_pointed(base)) */
00397       {
00398          /* Search for a struct or union field at the expected offset */
00399          while (! next_fld.Is_Null () && (INT64)FLD_ofst(next_fld) <= offset)
00400          {
00401             this_fld = next_fld;
00402             next_fld = FLD_next(next_fld);
00403          }
00404       }
00405       
00406       Is_True(!this_fld.Is_Null () &&
00407               (INT64)FLD_ofst(this_fld) <= offset           &&
00408               (INT64)FLD_ofst(next_fld) >= offset           &&
00409               (TY_Is_Structured(FLD_type(this_fld))) &&
00410               (INT64)TY_size(FLD_type(this_fld)) >= size, 
00411               ("Could not find a field as expected in TY2C_Get_Mload_Ty()"));
00412 
00413       ty = Stab_Get_Mload_Ty(FLD_type(this_fld), 
00414                              offset-FLD_ofst(this_fld),
00415                              size);
00416    }
00417    return ty;
00418 } /* Stab_Get_Mload_Ty */
00419 
00420 
00421 //***************************************************************************
00422 // Type creation
00423 //***************************************************************************
00424 
00425 extern TY_IDX
00426 Stab_Array_Of(TY_IDX etype, mINT64 num_elts)
00427 {
00428   /* Make a 1d array of (pointer?) types. Must handle 0-sized objects */
00429   /* and structs - Make_Array_Type doesn't like structs ...........*/
00430 
00431   TY_IDX  ty_idx;
00432 
00433   ARB_HANDLE arb = New_ARB ();
00434 
00435 //  ARB_Init (arb, 0, num_elts - 1, TY_size(etype));
00436 
00437 /* here,since we keep all arrays lower bound and upper bound     */
00438 /* same with the source files,we have to change this function     */
00439 /* set lower bound is 1 and upper bound is num_elts to consistent */
00440 /*with our source level definition----fzhao                       */
00441 
00442   ARB_Init (arb, 1, num_elts , TY_size(etype));
00443 
00444   Set_ARB_dimension (arb,1);
00445   Set_ARB_last_dimen (arb);
00446   Set_ARB_first_dimen (arb);
00447 
00448   TY& ty = New_TY (ty_idx);
00449   TY_Init (ty, TY_size(etype) * num_elts,KIND_ARRAY, MTYPE_UNKNOWN,0);
00450 
00451   Set_TY_align (ty_idx, TY_size(etype));
00452   Set_TY_etype (ty, etype);
00453   Set_TY_arb (ty, arb);
00454 
00455   return ty_idx;
00456 }   
00457 
00458 
00459 //***************************************************************************
00460 // Identifier naming utilities
00461 //***************************************************************************
00462 
00463 /*---------------------- Name manipulation -----------------------
00464  *
00465  *    We operate with a cyclic character buffer for identifier names,
00466  *    where the size of the buffer is a minimum of 1024 characters
00467  *    and at a maximum of 8 times the largest name encountered.  Note 
00468  *    that a call to any of the functions described below may allocate
00469  *    a new name buffer.  Name buffers are allocated from the cyclic
00470  *    character buffer, and a name-buffer may be reused at every 8th
00471  *    (MIN_NAME_SLOTS) allocation.  We guarantee that a name-buffer is 
00472  *    valid up until 7 subsequent name-buffer allocations, but no 
00473  *    longer.  After 7 subsequent name-buffer allocations, the name 
00474  *    buffer may be reused (overwritten) or even freed up from dynamic
00475  *    memory.  While the results from the calls to the functions 
00476  *    provided here may be used to construct identifier names, these 
00477  *    results should be saved off into a more permanent buffer area 
00478  *    once the names have been constructed.
00479  *----------------------------------------------------------------*/
00480 
00481 #define MIN_NAME_SLOTS 8
00482 #define MIN_NAME_BUF_SIZE 1024
00483 #define MAX_NUMSTRING_SIZE 128
00484 
00485 static char *Name_Buf;
00486 static UINT Name_Buf_Idx = 0;  /* Next available Name_Buf character */
00487 static UINT Name_Buf_Size = 0; /* Size of Name_Buf */
00488 
00489 static char *buffer_to_be_freed[MIN_NAME_SLOTS];
00490 static UINT  next_delay_slot = 0;
00491 static UINT  delay_count[MIN_NAME_SLOTS] = {0, 0, 0, 0, 0, 0, 0, 0};
00492 static INT   next_to_be_freed = -1;
00493 
00494 
00495 void
00496 Stab_Free_Namebufs(void)
00497 {
00498    /* Called at the end of processing every PU.
00499     */
00500    INT i;
00501    
00502    if (next_to_be_freed > 0)
00503    {
00504       for (i=0; i < MIN_NAME_SLOTS; i++)
00505          if (delay_count[i] > 0)
00506          {
00507             FREE(buffer_to_be_freed[i]);
00508             delay_count[i] = 0;
00509          }
00510       next_to_be_freed = -1;
00511       next_delay_slot = 0;
00512    }
00513    if (Name_Buf_Size > 0)
00514    {
00515       FREE(Name_Buf);
00516       Name_Buf_Idx = Name_Buf_Size = 0;
00517    }
00518 } /* Stab_Free_Namebufs */
00519 
00520 
00521 char * 
00522 Get_Name_Buf_Slot(UINT size)
00523 {
00524    char *name_slot;
00525    
00526    /* See if it is time to free up a buffer */
00527    if (next_to_be_freed >= 0 && 
00528        delay_count[next_to_be_freed] > 0)
00529    {
00530       delay_count[next_to_be_freed]--;
00531       if (delay_count[next_to_be_freed] == 0)
00532       {
00533          FREE(buffer_to_be_freed[next_to_be_freed]);
00534          buffer_to_be_freed[next_to_be_freed] = NULL;
00535          next_to_be_freed = (next_to_be_freed + 1) % MIN_NAME_SLOTS;
00536       }
00537    }
00538    
00539    /* See if we need a larger name-buffer */
00540    if (size*MIN_NAME_SLOTS > Name_Buf_Size)
00541    {
00542       /* (Re)allocate the character buffer */
00543       if (Name_Buf_Size > 0)
00544       {
00545          /* Delay freeing until this function has been called
00546           * MIN_NAME_SLOTS times.
00547           */
00548          buffer_to_be_freed[next_delay_slot] = Name_Buf;
00549          delay_count[next_delay_slot] = MIN_NAME_SLOTS;
00550          next_delay_slot = (next_delay_slot + 1) % MIN_NAME_SLOTS;
00551          
00552          /* Allocate a new buffer */
00553          Name_Buf = TYPE_ALLOC_N(char, size*MIN_NAME_SLOTS);
00554          Name_Buf_Size = size*MIN_NAME_SLOTS;
00555       }
00556       else
00557       {
00558          UINT s = MIN_NAME_BUF_SIZE;
00559 
00560          if (size*MIN_NAME_SLOTS > s) s = size*MIN_NAME_SLOTS;
00561          Name_Buf = TYPE_ALLOC_N(char, s);
00562          Name_Buf_Size = s;
00563       }
00564    }
00565 
00566    /* If the name does not fit in the unused part of the (cyclic)
00567     * buffer, then restart allocation of name slots at the beginning
00568     * of the buffer.
00569     */
00570    if (size + Name_Buf_Idx > Name_Buf_Size)
00571       Name_Buf_Idx = 0;
00572 
00573    /* Allocate a slot for the name within the buffer */
00574    name_slot = &Name_Buf[Name_Buf_Idx];
00575    Name_Buf_Idx += size;
00576 
00577    return name_slot;
00578 } /* Get_Name_Buf_Slot */
00579 
00580 
00581 const char * 
00582 Num2Str(INT64 number, const char *fmt)
00583 {
00584    char *new_name = Get_Name_Buf_Slot(MAX_NUMSTRING_SIZE);
00585 
00586    sprintf(new_name, fmt, number);
00587    return new_name;
00588 } /* Num2Str */
00589 
00590 
00591 const char * 
00592 Ptr_as_String(const void *ptr)
00593 {
00594    char *new_name = Get_Name_Buf_Slot(MAX_NUMSTRING_SIZE);
00595    union 
00596    {
00597       const void *ptr;
00598       UINT32      u32;
00599       UINT64      u64;
00600    } ptr_as_number;
00601 
00602    ptr_as_number.ptr = ptr;
00603    
00604    if (sizeof(void *) == sizeof(UINT32))
00605       sprintf(new_name, "%u", ptr_as_number.u32);
00606    else if (sizeof(void *) == sizeof(UINT64))
00607       sprintf(new_name, "%llu", ptr_as_number.u64);
00608    else
00609       Is_True(FALSE, ("Unknown pointer size in Ptr_as_String()"));
00610    
00611    return new_name;
00612 } /* Ptr_as_String */
00613 
00614 
00615 const char *
00616 StrCat(const char *name1, const char *name2)
00617 {
00618   /* Construct a new name by concatenating two other names.  The
00619    * new name will be put into a new name buffer.
00620    */
00621   INT   name1_length;
00622   INT   name2_length;
00623   char *new_name;
00624   
00625   if (name1 == NULL)
00626     return name2;
00627   else if (name2 == NULL)
00628     return name1;
00629   else if (*name1 == '\0')
00630     return name2;
00631   else if  (*name2 == '\0')
00632     return name1;
00633   else {
00634     name1_length = strlen(name1);
00635     name2_length = strlen(name2);
00636     new_name = Get_Name_Buf_Slot(name1_length + name2_length + 1);
00637     
00638     (void)strcpy(new_name, name1);
00639     (void)strcpy(&new_name[name1_length], name2);
00640     
00641     return new_name;
00642   }
00643 } /* StrCat */
00644 
00645 
00646 UINT64
00647 Get_Hash_Value_For_Name(const char *name)
00648 {
00649    /* Assume alpha-numeric characters only differ in the least
00650     * significant 6 bits.  Take only the rightmost characters
00651     * into account.
00652     */
00653    INT64       hash_value = 0;
00654    const char *cptr;
00655 
00656    if (name != NULL) 
00657    {
00658       for (cptr=name; *cptr != '\0'; cptr++)
00659          hash_value = (hash_value << (INT64)6) + (INT64)*cptr;
00660    }  /* if */
00661    if (hash_value < 0)
00662       hash_value = -hash_value;
00663 
00664    return hash_value;
00665 } /* Get_Hash_Value_For_Name */
00666 
00667 
00668 STAB_OFFSET 
00669 Stab_Full_Split_Offset(const ST *split_out_st)
00670 {
00671    const char *name = ST_name(split_out_st);
00672    INT         i;
00673    STAB_OFFSET offset = 0;
00674    UINT64      digit = 1;
00675 
00676    for (i = strlen(name) - 1;
00677         i >= 0 && '0' <= name[i] && '9' >= name[i];
00678         i--)
00679    {
00680       offset += (STAB_OFFSET)(name[i] - '0') * digit;
00681       digit *= 10;
00682    }
00683    return offset;
00684 } /* Stab_Full_Split_Offset */
00685 
00686 
00687 /*------------- Utilities for creating temporary variables ------------
00688  * 
00689  * Maintains an array of TMPVARINFOs, such that a tmpvar can be
00690  * reused whenever the type matches that of an existing tempvar and
00691  * it is not "locked".  The array is indexed by a unique tmpvar
00692  * number.
00693  *---------------------------------------------------------------------*/
00694 
00695 typedef struct TmpVarInfo
00696 {
00697    TY_IDX      ty;
00698    BOOL        locked;
00699 } TMPVARINFO;
00700 
00701 #define TMPVAR_ALLOC_INCREMENTS 32
00702 static TMPVARINFO *TmpVar = NULL;
00703 static INT Next_Tmpvar_Idx = 0;
00704 static INT Max_Tmpvar_Idx = -1;
00705 
00706 
00707 void
00708 Stab_Free_Tmpvars(void)
00709 {
00710    /* Called at the end of processing every PU.
00711     */
00712    if (TmpVar != NULL)
00713    {
00714       FREE(TmpVar);
00715       TmpVar = NULL;
00716       Next_Tmpvar_Idx = 0;
00717       Max_Tmpvar_Idx = -1;
00718    }
00719 } /* Stab_Free_Tmpvars */
00720 
00721 
00722 UINT 
00723 Stab_Lock_Tmpvar(TY_IDX ty, 
00724                  void (*declare_tmpvar)(TY_IDX, UINT))
00725 {
00726    /* Find an available (unlocked) temporary variable of the
00727     * given type, and if none is available, then declare a new
00728     * one.
00729     */
00730    INT idx;
00731    
00732    /* See if we have an available tmpvar of a compatible type */
00733    for (idx = Next_Tmpvar_Idx - 1;
00734         (idx >= 0 &&
00735          (TmpVar[idx].locked ||
00736           !Stab_Identical_Types(TmpVar[idx].ty, ty, FALSE, TRUE, FALSE)));
00737         idx--);
00738    
00739    if (idx < 0)
00740    {
00741       /* Could not find a suitable temporary variable, so declare
00742        * a new one and set "idx" to index this new entry.
00743        */
00744       if (Max_Tmpvar_Idx <= 0)
00745       {
00746          /* Need to allocate the TmpVar array */
00747          TmpVar = TYPE_ALLOC_N(TMPVARINFO, TMPVAR_ALLOC_INCREMENTS);
00748          Max_Tmpvar_Idx = TMPVAR_ALLOC_INCREMENTS;
00749       }
00750       if (Next_Tmpvar_Idx >= Max_Tmpvar_Idx)
00751       {
00752          /* Need to reallocate the TmpVar array */
00753          TmpVar = TYPE_REALLOC_N(TMPVARINFO, 
00754                                  TmpVar, 
00755                                  Next_Tmpvar_Idx,
00756                                  Next_Tmpvar_Idx + TMPVAR_ALLOC_INCREMENTS);
00757          Max_Tmpvar_Idx += TMPVAR_ALLOC_INCREMENTS;
00758       }
00759       idx = Next_Tmpvar_Idx++;
00760       TmpVar[idx].ty = ty;
00761       declare_tmpvar(ty, idx);
00762    }
00763    TmpVar[idx].locked = TRUE;
00764    return idx;
00765 } /* Stab_Lock_Tmpvar */
00766 
00767 
00768 void
00769 Stab_Unlock_Tmpvar(UINT idx)
00770 {
00771    Is_True((INT)idx < Next_Tmpvar_Idx, 
00772            ("Tmpvar index out of range in Stab_Unlock_Tmpvar()"));
00773    
00774    TmpVar[idx].locked = FALSE;
00775 } /* Stab_Unlock_Tmpvar */
00776 
00777 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines