|
OpenADFortTk (basic)
|
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