Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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 * dd-mmm-95 - Original Version 00042 * 00043 * Description: This provides an auxiliary data structure for an ST 00044 * to hang odds and ends on. There's an AUXST table associated 00045 * with each level of the symtab, and it's deleted when 00046 * the symtab is deleted. The definition is in cwh_auxst.i 00047 * Most external entry points are defined via an ST and 00048 * perhaps the name of a list. The AUXST for an ST is 00049 * allocated, indirectly, by calls to cwh_auxst_find. 00050 * 00051 * There are allocation/deallocation routines, some routines 00052 * to deal with lists, some to extract details from the AUXST, 00053 * and a few routines to update procedures STs with the 00054 * accumulated detail of arguments and types. 00055 * 00056 * Dump routines are at the end. 00057 * 00058 * ==================================================================== 00059 * ==================================================================== 00060 */ 00061 /*REFERENCED*/ 00062 static char *source_file = __FILE__; 00063 00064 #ifdef _KEEP_RCS_ID 00065 #endif /* _KEEP_RCS_ID */ 00066 00067 #include <string.h> /* for memset() */ 00068 00069 /* general compiler includes */ 00070 00071 #include "defs.h" 00072 #include "glob.h" 00073 #include "stab.h" 00074 #include "strtab.h" 00075 #include "errors.h" 00076 #include "targ_const.h" 00077 #include "config_targ.h" 00078 #include "const.h" 00079 #include "wn.h" 00080 #include "cxx_memory.h" 00081 #include <stdio.h> 00082 00083 /* conversion includes */ 00084 00085 #include "cwh_defines.h" 00086 #include "cwh_preg.h" 00087 #include "cwh_types.h" 00088 #include "cwh_addr.h" 00089 #include "cwh_auxst.h" 00090 #include "cwh_auxst.i" 00091 #include "sgi_cmd_line.h" 00092 00093 /*=================================================== 00094 * 00095 * cwh_auxst_register_table 00096 * 00097 * For the current level, register an auxst table that 00098 * will automatically grow as the St_table grows. 00099 * convenient for a label table too. 00100 * 00101 ==================================================== 00102 */ 00103 extern void 00104 cwh_auxst_register_table(void) 00105 { 00106 Auxst_tab[CURRENT_SYMTAB].Auxst_table = CXX_NEW(AUXST_PTR_ARRAY(FE_Mempool), FE_Mempool); 00107 Scope_tab[CURRENT_SYMTAB].st_tab->Register(*(Auxst_tab[CURRENT_SYMTAB].Auxst_table)); 00108 00109 if (CURRENT_SYMTAB != GLOBAL_SYMTAB) 00110 Scope_tab[CURRENT_SYMTAB].label_tab->Register(Auxlabel_Table); 00111 00112 } 00113 00114 /*=================================================== 00115 * 00116 * cwh_auxst_un_register_table 00117 * 00118 * Unregister the auxst table and auxlabel tables. 00119 * 00120 ==================================================== 00121 */ 00122 extern void 00123 cwh_auxst_un_register_table(void) 00124 { 00125 Scope_tab[CURRENT_SYMTAB].st_tab->Un_register(*(Auxst_tab[CURRENT_SYMTAB].Auxst_table)); 00126 CXX_DELETE(Auxst_tab[CURRENT_SYMTAB].Auxst_table, FE_Mempool); 00127 00128 if (CURRENT_SYMTAB != GLOBAL_SYMTAB) 00129 Scope_tab[CURRENT_SYMTAB].label_tab->Un_register(Auxlabel_Table); 00130 } 00131 00132 /*=================================================== 00133 * 00134 * cwh_auxst_alloc_container_table 00135 * 00136 * This allocates a table analogous to the scope table 00137 * in common/com; we can index into this table by level 00138 * and then get to the auxst table for that level; 00139 * however, the entire mechanism should be transparent 00140 * and we should not ever need to explicitly refer to 00141 * Auxst_tab. 00142 * 00143 ==================================================== 00144 */ 00145 void 00146 cwh_auxst_alloc_container_table(void) 00147 { 00148 Auxst_tab = (AUXST_TAB *) MEM_POOL_Alloc (FE_Mempool, 00149 MAX_AUXST_LEVEL * sizeof(AUXST_TAB)); 00150 } 00151 00152 /*=================================================== 00153 * 00154 * cwh_auxst_find 00155 * 00156 * Allocate or find field which holds details 00157 * associated with this ST. The ST_temp holds the 00158 * pointer. The create flag builds auxst field, if absent. 00159 * 00160 ==================================================== 00161 */ 00162 static AUXST * 00163 cwh_auxst_find(ST *st, BOOL create) 00164 { 00165 AUXST * o ; 00166 00167 o = Auxst_Table[ST_st_idx(st)]; 00168 00169 if (o == NULL) { 00170 if (create) { 00171 o = (AUXST *) malloc(sizeof(AUXST)); 00172 00173 memset(o, '\0', sizeof(AUXST)); 00174 00175 AUXST_OwningST(o)= st ; 00176 AUXST_Next(o) = Top_Auxst[ST_level(st)]; 00177 AUXST_AssignId(o) = -1 ; 00178 AUXST_DstrPreg(o).preg = -1; 00179 00180 USRCPOS_clear(AUXST_SrcPos(o)); 00181 00182 Auxst_Table[ST_st_idx(st)] = o; 00183 Top_Auxst[ST_level(st)] = o ; 00184 } 00185 } 00186 return(o); 00187 } 00188 00189 /*=================================================== 00190 * 00191 * cwh_auxst_clear 00192 * 00193 * set the Auxst_Table entry for incoming st to null. 00194 * 00195 ==================================================== 00196 */ 00197 extern void 00198 cwh_auxst_clear(ST *st) 00199 { 00200 Auxst_Table[ST_st_idx(st)] = NULL; 00201 } 00202 00203 /*=================================================== 00204 * 00205 * cwh_auxst_free 00206 * 00207 * Free any AUXSTs, and set the corresponding 00208 * ST_temp to NULL; 00209 * 00210 ==================================================== 00211 */ 00212 extern void 00213 cwh_auxst_free(void) 00214 { 00215 AUXST *o,*n; 00216 LIST *l ; 00217 00218 00219 o = Top_Auxst[CURRENT_SYMTAB]; 00220 00221 while (o != NULL ) { 00222 00223 AUXST_Pragma(o) = NULL ; 00224 n = AUXST_Next(o); 00225 00226 ST *st = AUXST_OwningST(o); 00227 00228 Auxst_Table[ST_st_idx(st)] = NULL; 00229 00230 l = cwh_auxst_find_list(o,l_COMLIST); 00231 cwh_auxst_free_list(&l); 00232 00233 l = cwh_auxst_find_list(o,l_ALTENTRY); 00234 cwh_auxst_free_list(&l); 00235 00236 l = cwh_auxst_find_list(o,l_RETURN_TEMPS); 00237 cwh_auxst_free_list(&l); 00238 00239 l = cwh_auxst_find_list(o,l_NAMELIST); 00240 cwh_auxst_free_list(&l); 00241 00242 l = cwh_auxst_find_list(o,l_SPLITLIST); 00243 cwh_auxst_free_list(&l); 00244 00245 l = cwh_auxst_find_list(o,l_EQVLIST); 00246 cwh_auxst_free_list(&l); 00247 00248 l = cwh_auxst_find_list(o,l_DST_COMLIST); 00249 cwh_auxst_free_list(&l); 00250 00251 l = cwh_auxst_find_list(o,l_DST_PARMLIST); 00252 cwh_auxst_free_list(&l); 00253 00254 if (AUXST_Stem(o) != NULL) 00255 free (AUXST_Stem(o)) ; 00256 00257 if (AUXST_Dummies(o) != NULL) { 00258 if (AUXST_Dummies(o)->arglist != NULL) 00259 free (AUXST_Dummies(o)->arglist) ; 00260 free (AUXST_Dummies(o)) ; 00261 } 00262 free(o); 00263 o = n; 00264 } 00265 00266 Top_Auxst[CURRENT_SYMTAB] = NULL; 00267 } 00268 00269 00270 /*=================================================== 00271 * 00272 * cwh_auxst_clear_per_PU 00273 * 00274 * Clear any per_PU info associated with a global 00275 * or host auxst. For now, this is just the pragma flag. 00276 * and the label table for assigned/computed gotos. 00277 * 00278 ==================================================== 00279 */ 00280 extern void 00281 cwh_auxst_clear_per_PU(void) 00282 { 00283 AUXST * o ; 00284 SYMTAB_IDX s = CURRENT_SYMTAB; 00285 00286 while (s >= GLOBAL_SYMTAB) { 00287 o = Top_Auxst[s] ; 00288 while (o != NULL ) { 00289 AUXST_Pragma(o) = NULL; 00290 o = AUXST_Next(o); 00291 } 00292 s-- ; 00293 } 00294 00295 Auxlabel_Table.Clear(); 00296 } 00297 00298 /*=================================================== 00299 * 00300 * cwh_auxst_get_list 00301 * 00302 * Given an ST address and a enum which 00303 * identifies which list to get, return a pointer 00304 * to the list. 00305 * 00306 ==================================================== 00307 */ 00308 extern LIST * 00309 cwh_auxst_get_list(ST * st,enum list_name list) 00310 { 00311 LIST * l = NULL; 00312 AUXST * o = cwh_auxst_find(st,FALSE); 00313 00314 if (o) 00315 l = cwh_auxst_find_list(o,list); 00316 00317 return l; 00318 } 00319 00320 /*=================================================== 00321 * 00322 * cwh_auxst_find_list 00323 * 00324 * Given an AUXST address and a enum which 00325 * identifies which list to get, return a pointer 00326 * to the list. 00327 * 00328 ==================================================== 00329 */ 00330 static LIST * 00331 cwh_auxst_find_list(AUXST * o, enum list_name list) 00332 { 00333 LIST *l ; 00334 00335 switch (list) { 00336 case l_COMLIST: 00337 l = AUXST_Commons(o); 00338 break; 00339 00340 case l_ALTENTRY: 00341 l = AUXST_Altentries(o); 00342 break; 00343 00344 case l_NAMELIST: 00345 l = AUXST_Namelist(o); 00346 break; 00347 00348 case l_RETURN_TEMPS: 00349 l = AUXST_RtnTemps(o); 00350 break; 00351 00352 case l_SPLITLIST: 00353 l = AUXST_SplitCommons(o); 00354 break; 00355 00356 case l_EQVLIST: 00357 l = AUXST_Equivs(o); 00358 break; 00359 00360 case l_DST_COMLIST: 00361 l = AUXST_Dstcomlist(o); 00362 break; 00363 00364 case l_DST_PARMLIST: 00365 l = AUXST_Dstparmlist(o); 00366 break; 00367 00368 case l_TYMDLIST: 00369 l = AUXST_TyMdlist(o); 00370 break; 00371 00372 default: 00373 DevAssert((0),("list?")); 00374 } 00375 00376 return l; 00377 } 00378 00379 /*=================================================== 00380 * 00381 * cwh_auxst_add_item 00382 * 00383 * add ST to AUXST of parent ST. 00384 * 00385 * a) the list of elements in a COMMON block ST's 00386 * for DST info and full_split_common. If full_split 00387 * then are order the STs by offset. 00388 * 00389 * b) a list of alternate entry points associated 00390 * procedure. 00391 * 00392 * c) a list of Namelist items 00393 * d) a list of equivalence items 00394 * e) a list of alternate entry point return temp STs 00395 * f) a list of parameters needed for DST info 00396 * 00397 ==================================================== 00398 */ 00399 extern void 00400 cwh_auxst_add_item(ST * parent, ST *st, enum list_name list) 00401 { 00402 AUXST *o ; 00403 LIST *c ; 00404 BOOL b ; 00405 00406 b = FALSE; 00407 00408 if (list == l_COMLIST) 00409 b = TRUE; 00410 00411 o = cwh_auxst_find(parent,TRUE); 00412 c = cwh_auxst_find_list(o, list); 00413 00414 cwh_auxst_add_to_list(&c,st,b); 00415 } 00416 00417 /*=================================================== 00418 * 00419 * cwh_auxst_find_item 00420 * 00421 * Does this name match any of the ST's on 00422 * the given LIST? 00423 * 00424 ==================================================== 00425 */ 00426 extern ST * 00427 cwh_auxst_find_item(LIST *l, char * name) 00428 { 00429 ITEM *t ; 00430 ST *st; 00431 00432 st = NULL ; 00433 if (l == NULL) return (NULL); 00434 t = L_first(l) ; 00435 00436 while (t != NULL) { 00437 if (strcmp(ST_name(I_element(t)),name) == 0) { 00438 st = I_element(t); 00439 break ; 00440 } 00441 t = I_next(t); 00442 } 00443 00444 return(st); 00445 } 00446 00447 /*=================================================== 00448 * 00449 * cwh_auxst_add_list 00450 * 00451 * add list to AUXST of parent ST - only used for 00452 * namelist just now, but other enums are provided 00453 * (later, commented out...) 00454 * 00455 ==================================================== 00456 */ 00457 extern void 00458 cwh_auxst_add_list(ST * parent, LIST *l, enum list_name list) 00459 { 00460 AUXST *o ; 00461 00462 o = cwh_auxst_find(parent,TRUE); 00463 00464 switch (list) { 00465 case l_NAMELIST: 00466 *AUXST_Namelist(o) = *l; 00467 break; 00468 00469 #if 0 00470 case l_COMLIST: 00471 *AUXST_Commons(o) = *l ; 00472 break; 00473 00474 case l_ALTENTRY: 00475 *AUXST_Altentries(o) = *l ; 00476 break; 00477 00478 case l_RETURN_TEMPS: 00479 *AUXST_RtnTemps(o) = *l; 00480 break; 00481 00482 case l_SPLITLIST: 00483 *AUXST_SplitCommons(o) = *l ; 00484 break; 00485 00486 case l_EQVLIST: 00487 *AUXST_Equivs(o) = *l; 00488 break; 00489 00490 case l_DST_COMLIST: 00491 *AUXST_Dstcomlist(o) = *l; 00492 break; 00493 00494 case l_DST_PARMLIST: 00495 *AUXST_Dstparmlist(o) = *l; 00496 break; 00497 #endif 00498 00499 default: 00500 DevAssert((0),("list?")); 00501 00502 } 00503 } 00504 00505 /*=================================================== 00506 * 00507 * cwh_auxst_next_element 00508 * 00509 * Finds the ST of the next item within a list 00510 * in a parent ST's auxiliary info. 00511 * 00512 * If the ITEM argument is NULL, the first element is 00513 * returned. If there are no more elements the 00514 * result is NULL, otherwise the next item. The LIST 00515 * argument is examined & the correct list established. 00516 * 00517 ==================================================== 00518 */ 00519 extern ITEM * 00520 cwh_auxst_next_element(ST * parent, ITEM *i, enum list_name list) 00521 { 00522 AUXST *o; 00523 LIST *l; 00524 00525 if (i == NULL) { 00526 o = cwh_auxst_find(parent,TRUE); 00527 00528 if (o != NULL) { 00529 l = cwh_auxst_find_list(o,list); 00530 i = L_first(l); 00531 } 00532 } else 00533 i = I_next(i) ; 00534 00535 return (i); 00536 } 00537 00538 /*=================================================== 00539 * 00540 * cwh_auxst_add_to_list 00541 * 00542 * Add this ST to the list provided. A pointer to 00543 * the list is handed in - if NULL, the list is 00544 * created. A pointer to the last item added is 00545 * returned. If order is true, the list is ordered 00546 * by ST_ofst. (First == low). 00547 * 00548 ==================================================== 00549 */ 00550 extern ITEM * 00551 cwh_auxst_add_to_list(LIST ** lp, ST *st, BOOL order) 00552 { 00553 ITEM * i; 00554 ITEM * n; 00555 ITEM * p; 00556 LIST * l; 00557 00558 if (*lp == NULL) { 00559 *lp = (LIST *) malloc(sizeof(LIST)); 00560 l = *lp ; 00561 L_first(l) = NULL ; 00562 L_last(l) = NULL ; 00563 L_num(l) = 0 ; 00564 } 00565 00566 l = *lp ; 00567 i = (ITEM *)malloc(sizeof(ITEM)) ; 00568 00569 I_element(i) = st; 00570 I_next(i) = NULL; 00571 00572 if ( order ) { 00573 n = L_first(l) ; 00574 p = NULL ; 00575 00576 while (n != NULL) { 00577 00578 if (ST_ofst(I_element(n)) > ST_ofst(st)) { 00579 I_next(i) = n; 00580 00581 if (L_first(l) == n) 00582 L_first(l) = i ; 00583 else 00584 I_next(p) = i; 00585 00586 break; 00587 } 00588 p = n ; 00589 n = I_next(n); 00590 } 00591 00592 if (L_first(l) == NULL) 00593 L_first(l) = i; 00594 00595 if (L_last(l) == NULL) 00596 L_last(l) = i; 00597 00598 if (L_last(l) == p) { 00599 I_next(L_last(l)) = i; 00600 L_last(l) = i; 00601 } 00602 00603 } else { 00604 00605 if (L_first(l) == NULL) 00606 L_first(l) = i; 00607 00608 if (L_last(l) != NULL) 00609 I_next(L_last(l)) = i ; 00610 00611 L_last(l) = i; 00612 } 00613 00614 L_num(l) ++ ; 00615 00616 return i; 00617 } 00618 00619 00620 /*=================================================== 00621 * 00622 * cwh_auxst_free_list 00623 * 00624 * Free a LIST of items. Clears the LIST pointer. 00625 * 00626 ==================================================== 00627 */ 00628 extern void 00629 cwh_auxst_free_list (LIST ** lp) 00630 { 00631 ITEM *i; 00632 ITEM *n; 00633 LIST *l; 00634 00635 if (*lp != NULL) { 00636 l = *lp ; 00637 00638 i = L_first(l) ; 00639 00640 while (i != NULL) { 00641 n = I_next(i); 00642 free(i) ; 00643 i = n ; 00644 } 00645 00646 *lp = NULL ; 00647 } 00648 } 00649 00650 /*=================================================== 00651 * 00652 * cwh_auxst_set_flag 00653 * 00654 * Set the given flag to TRUE or FALSE. Allocate 00655 * the AUXST if required. Invoked via macro (cwh_stab.h) 00656 * 00657 ==================================================== 00658 */ 00659 extern void 00660 cwh_auxst_set_flag(ST * st, enum flags_a f, BOOL val) 00661 { 00662 AUXST *o ; 00663 00664 o = cwh_auxst_find(st,TRUE); 00665 00666 if (val) 00667 Set_AUXST_Flag(o,f); 00668 else 00669 Clear_AUXST_Flag(o,f); 00670 } 00671 00672 /*=================================================== 00673 * 00674 * cwh_auxst_read_flag 00675 * 00676 * Read the given flag in the AUXST. If no AUXST 00677 * returns F. Invoked via macro (cwh_auxst.h) 00678 * 00679 ==================================================== 00680 */ 00681 extern BOOL 00682 cwh_auxst_read_flag(ST * st, enum flags_a f) 00683 { 00684 AUXST *o ; 00685 BOOL res = FALSE ; 00686 00687 res = FALSE; 00688 00689 o = cwh_auxst_find(st,FALSE); 00690 00691 if (o != NULL) 00692 res = AUXST_Flag(o,f); 00693 00694 return res ; 00695 } 00696 00697 /*================================================================ 00698 * 00699 * Set_ST_auxst_data_info 00700 * 00701 * Set data_info ptr 00702 * 00703 *================================================================ 00704 */ 00705 extern void 00706 Set_ST_auxst_data_info(ST *st, data_info_s * data_info) 00707 { 00708 AUXST * o ; 00709 00710 o = cwh_auxst_find(st,TRUE); 00711 AUXST_DataInfo(o) = data_info; 00712 return ; 00713 } 00714 /*================================================================ 00715 * 00716 * ST_auxst_data_info 00717 * 00718 * retreive data_info ptr 00719 * 00720 *================================================================ 00721 */ 00722 extern data_info_s * 00723 ST_auxst_data_info(ST *st) 00724 { 00725 AUXST * o ; 00726 00727 o = cwh_auxst_find(st,FALSE); 00728 if (o) { 00729 return AUXST_DataInfo(o); 00730 } else { 00731 return (NULL); 00732 } 00733 } 00734 00735 /*=================================================== 00736 * 00737 * cwh_auxst_alloc_proc_entry 00738 * 00739 * For the entry point ST, allocate 00740 * a DUMMIES structure to record the argument list. 00741 * Allocate 2 entries per dummy, in case they are 00742 * character dummies with the length at the end. 00743 * Set the character_args_seen to point after all 00744 * regular dummies. 00745 * 00746 * Record all entry point ST's on a list, so we 00747 * can refer to a TEXT symbol if possible. 00748 * 00749 * Set EP_Current to this entry point.. 00750 * 00751 ==================================================== 00752 */ 00753 extern void 00754 cwh_auxst_alloc_proc_entry(ST *st,INT32 num_dum_args, TY_IDX ret_type) 00755 { 00756 DUMMIES *p ; 00757 AUXST *o ; 00758 00759 o = cwh_auxst_find(st,TRUE); 00760 p = cwh_auxst_find_entry(st); 00761 00762 if (p == NULL) 00763 p = AUXST_Dummies(o) = (DUMMIES *) malloc(sizeof(DUMMIES)); 00764 00765 p->total_args = num_dum_args ; 00766 p->fe_given_args = num_dum_args ; 00767 p->args_seen = 0; 00768 p->arg_lengths_index = num_dum_args ; 00769 00770 p->parms = NULL; 00771 00772 if (num_dum_args > 0) { 00773 p->parms = (PARMS *)malloc(sizeof(PARMS)*num_dum_args); 00774 for (INT32 i = 1; i < num_dum_args; i++) { 00775 PARMS_next(&(p->parms[i-1])) = &(p->parms[i]); 00776 } 00777 PARMS_next(&(p->parms[num_dum_args-1])) = NULL; 00778 } 00779 00780 p->last_parm_ty_seen = p->parms; 00781 p->orig_ret_type = ret_type; 00782 p->ret_type = ret_type; 00783 00784 p->last_len_ty_seen = NULL; 00785 p->arglist = NULL; 00786 if (num_dum_args > 0) 00787 p->arglist = (ST **) malloc(2 * num_dum_args * sizeof(ST *)) ; 00788 00789 EP_Current = o ; 00790 00791 } 00792 00793 /*=================================================== 00794 * 00795 * cwh_auxst_add_dummy 00796 * 00797 * add a dummy argument to the list associated 00798 * with the entry point. Add the type of the dummy 00799 * to the param list of of the entry's TY. 00800 * 00801 * If it's a character object, add the length dummy 00802 * and its type. If result is TRUE, then the dummy is 00803 * a function result and it goes after the address 00804 * and not at the end. 00805 * 00806 ==================================================== 00807 */ 00808 extern void 00809 cwh_auxst_add_dummy(ST * dummy, BOOL result) 00810 { 00811 DUMMIES *e ; 00812 ST *ln ; 00813 TY_IDX ty ; 00814 PARMS *tl ; 00815 PARMS *te ; 00816 PARMS *tn ; 00817 00818 e = AUXST_Dummies(EP_Current); 00819 ln = cwh_types_character_extra(dummy); 00820 00821 DevAssert((e->total_args > e->args_seen),(" arglist overflow")); 00822 00823 e->arglist[e->args_seen++] = dummy ; 00824 00825 ty = ST_type(dummy); 00826 tl = e->last_parm_ty_seen ; 00827 00828 if (ST_sclass(dummy) == SCLASS_FORMAL_REF) 00829 ty = Make_Pointer_Type(ty); 00830 00831 PARMS_ty(tl) = ty; 00832 00833 if (result) 00834 e->ret_type = ST_type(dummy); 00835 00836 /* if character dummy, add len to function parm list */ 00837 /* unless a result len, when it goes after the address */ 00838 /* (it will be first len seen). */ 00839 00840 if (ln != NULL) { 00841 00842 tn = (PARMS *) malloc(sizeof(PARMS)); 00843 PARMS_ty(tn) = Be_Type_Tbl(cwh_addr_char_len_typeid); 00844 PARMS_next(tn) = NULL; 00845 00846 if (result) { /* make it look as though FE gave the length */ 00847 e->arg_lengths_index++ ; 00848 e->fe_given_args++ ; 00849 e->arglist[e->args_seen++] = ln ; 00850 00851 te = (PARMS *) malloc(sizeof(PARMS)); 00852 PARMS_ty(te) = ST_type(ln); 00853 PARMS_next(te) = PARMS_next(tl); 00854 PARMS_next(tl) = te; 00855 tl = te ; 00856 00857 } else { 00858 00859 if (e->last_len_ty_seen == NULL) { 00860 te = e->last_parm_ty_seen ; 00861 00862 while(PARMS_next(te)) 00863 te = PARMS_next(te); 00864 00865 } else 00866 te = e->last_len_ty_seen ; 00867 00868 PARMS_next(te) = tn ; 00869 e->last_len_ty_seen = tn ; 00870 e->arglist[e->arg_lengths_index++] = ln ; 00871 } 00872 e->total_args++; 00873 } 00874 00875 e->last_parm_ty_seen = PARMS_next(tl) ; 00876 00877 } 00878 00879 /*=================================================== 00880 * 00881 * cwh_auxst_patch_proc 00882 * 00883 * discovered the function result is a small struct, 00884 * which is passed by value. To avoid changing the 00885 * FE, which assumes by address, the internal 00886 * structures for dummy args are patched up here. 00887 * 00888 ==================================================== 00889 */ 00890 extern void 00891 cwh_auxst_patch_proc(TY_IDX rty_idx) 00892 { 00893 DUMMIES *e ; 00894 00895 e = AUXST_Dummies(EP_Current) ; 00896 00897 e->ret_type = rty_idx ; 00898 e->parms = PARMS_next(e->parms); 00899 e->total_args --; 00900 e->arg_lengths_index --; 00901 e->fe_given_args --; 00902 00903 e->last_parm_ty_seen = e->parms; 00904 } 00905 00906 /*=================================================== 00907 * 00908 * cwh_auxst_find_entry 00909 * 00910 * Find an entry point, and return a pointer to 00911 * its DUMMIES structure. 00912 * 00913 * Sets up current entry point auxst data. 00914 * 00915 ==================================================== 00916 */ 00917 static DUMMIES * 00918 cwh_auxst_find_entry(ST * entry) 00919 { 00920 AUXST *o ; 00921 00922 o = cwh_auxst_find(entry,FALSE); 00923 EP_Current = o ; 00924 return (AUXST_Dummies(o)) ; 00925 } 00926 00927 /*=================================================== 00928 * 00929 * cwh_auxst_find_srcpos_addr 00930 * 00931 * Returns the address of the srcpos field in AUXST. 00932 * 00933 ==================================================== 00934 */ 00935 extern USRCPOS * 00936 cwh_auxst_srcpos_addr(ST * st) 00937 { 00938 AUXST *o ; 00939 00940 o = cwh_auxst_find(st, TRUE); 00941 return (&(AUXST_SrcPos(o))) ; 00942 } 00943 00944 /*=================================================== 00945 * 00946 * cwh_auxst_find_srcpos_val 00947 * 00948 * Returns the value of the srcpos field in AUXST. 00949 * 00950 ==================================================== 00951 */ 00952 extern USRCPOS 00953 cwh_auxst_srcpos_val(ST * st) 00954 { 00955 AUXST *o ; 00956 00957 o = cwh_auxst_find(st, TRUE); 00958 return (AUXST_SrcPos(o)) ; 00959 } 00960 00961 /*=================================================== 00962 * 00963 * cwh_auxst_distr_preg 00964 * 00965 * Returns (creates) the preg # for the associated PREG 00966 * for distributed arrays. 00967 * 00968 ==================================================== 00969 */ 00970 extern PREG_det 00971 cwh_auxst_distr_preg(ST * st) 00972 { 00973 AUXST *o ; 00974 00975 o = cwh_auxst_find(st, TRUE); 00976 if (AUXST_DstrReg(o) == -1) { 00977 AUXST_DstrPreg(o) = cwh_preg_next_preg(MTYPE_I4, NULL, NULL); 00978 } 00979 return (AUXST_DstrPreg(o)) ; 00980 } 00981 00982 /*=============================================== 00983 * 00984 * cwh_extern_stem_name 00985 * 00986 * Returns or sets the stem for a DST name. 00987 * 00988 *=============================================== 00989 */ 00990 extern char * 00991 cwh_auxst_stem_name(ST * st, char * name) 00992 { 00993 char * r ; 00994 AUXST * o ; 00995 00996 r = name ; 00997 o = cwh_auxst_find(st, name != NULL) ; 00998 00999 if ( o != NULL) { 01000 if (name) 01001 AUXST_Stem(o) = name; 01002 else 01003 r = AUXST_Stem(o) ; 01004 } 01005 01006 return r ; 01007 } 01008 01009 /*=================================================== 01010 * 01011 * cwh_auxst_cri_pointee 01012 * 01013 * Set the CRI_pointee of the give CRI_pointer. 01014 * If the pointee is present, otherwise just lookup. 01015 * Used for initialization. 01016 * 01017 ==================================================== 01018 */ 01019 extern ST * 01020 cwh_auxst_cri_pointee(ST * ptr, ST * pointee) 01021 { 01022 AUXST *o ; 01023 ST * res = pointee ; 01024 01025 o = cwh_auxst_find(ptr,res != NULL); 01026 01027 if (o) { 01028 if (pointee) 01029 AUXST_CRIPointee(o) = pointee ; 01030 else 01031 res = AUXST_CRIPointee(o); 01032 } 01033 return res; 01034 } 01035 01036 /*=================================================== 01037 * 01038 * cwh_auxst_pragma 01039 * 01040 * associate a pragme with an ST. This is preamble 01041 * information, usually for nested procedures. 01042 * It says host varble is read/modified etc. 01043 * 01044 ==================================================== 01045 */ 01046 extern WN * 01047 cwh_auxst_pragma(ST * ptr, WN * wn) 01048 { 01049 AUXST *o ; 01050 WN * res = wn ; 01051 01052 o = cwh_auxst_find(ptr,wn != NULL); 01053 01054 if (o) { 01055 if (wn) 01056 AUXST_Pragma(o) = wn ; 01057 else 01058 res = AUXST_Pragma(o); 01059 } 01060 return res; 01061 } 01062 /*=================================================== 01063 * 01064 * cwh_auxst_assign_id 01065 * 01066 * Returns the address of the auxiliary entry for this 01067 * label_idx. Currently used only for assigned goto's. 01068 * 01069 ==================================================== 01070 */ 01071 INT32 * 01072 cwh_auxst_assign_id(SYMTAB_IDX level, LABEL_IDX idx) 01073 { 01074 return &(Auxlabel_Table[idx].assign_id); 01075 } 01076 01077 /*=================================================== 01078 * 01079 * cwh_auxst_find_dummy 01080 * 01081 * Find if the dummy is already in the current list 01082 * ( for alternate entry points...) 01083 * 01084 ==================================================== 01085 */ 01086 extern BOOL 01087 cwh_auxst_find_dummy(ST * arg) 01088 { 01089 DUMMIES *p ; 01090 INT16 i ; 01091 ST **ap ; 01092 01093 p = AUXST_Dummies(EP_Current); 01094 ap = p->arglist; 01095 01096 for (i = 0 ; i < p->args_seen ; i ++ ) 01097 if (arg == *ap++ ) 01098 return (TRUE); 01099 01100 return(FALSE); 01101 } 01102 01103 /*=================================================== 01104 * 01105 * cwh_auxst_find_dummy_len 01106 * 01107 * Find the length argument of the character ST 01108 * in the current entry structure. If the dummy 01109 * is the result variable of a character function, 01110 * it's the second arg, not in the list of lengths. 01111 * 01112 ==================================================== 01113 */ 01114 extern ST * 01115 cwh_auxst_find_dummy_len(ST * arg) 01116 { 01117 DUMMIES *p ; 01118 INT16 i,c ; 01119 ST **ap ; 01120 01121 p = AUXST_Dummies(EP_Current); 01122 c = 0 ; 01123 ap = p->arglist; 01124 01125 /* char function result? */ 01126 01127 if (AUXST_Flag(EP_Current,f_RSLTTMP) && 01128 cwh_types_is_character(p->ret_type)) 01129 if (arg == *ap++ ) 01130 return (p->arglist[1]); 01131 01132 DevAssert((p->args_seen >= p->fe_given_args ),("Missing args")); 01133 01134 /* no, look for character dummies */ 01135 01136 for (i = 0 ; i < p->fe_given_args ; i ++ ) { 01137 if(cwh_types_is_character(ST_type(*ap))) { 01138 if (arg == *ap) 01139 return(p->arglist[p->args_seen+c]); 01140 else 01141 c++ ; 01142 } 01143 ap++ ; 01144 } 01145 01146 return (NULL); 01147 } 01148 01149 /*=================================================== 01150 * 01151 * cwh_auxst_arglist 01152 * 01153 * Return a pointer to an array of STs which 01154 * describe the dummy argument list for the given 01155 * entry point. Indirectly sets current entry point 01156 * to entry. 01157 * 01158 ==================================================== 01159 */ 01160 extern ST ** 01161 cwh_auxst_arglist(ST * entry) 01162 { 01163 DUMMIES * e ; 01164 01165 e = cwh_auxst_find_entry(entry); 01166 01167 return (e->arglist); 01168 } 01169 01170 /*=================================================== 01171 * 01172 * cwh_auxst_num_dummies 01173 * 01174 * Return the number of dummies associated 01175 * with this entry point, including hidden arguments. 01176 * Indirectly sets current entry point to entry. 01177 * 01178 ==================================================== 01179 */ 01180 extern INT16 01181 cwh_auxst_num_dummies(ST * entry) 01182 { 01183 DUMMIES * e ; 01184 01185 e = cwh_auxst_find_entry(entry); 01186 01187 return (e->total_args); 01188 } 01189 01190 /*=================================================== 01191 * 01192 * cwh_auxst_set_tylist 01193 * 01194 * Each entry point's ST has the args information stored 01195 * in the PARMS list of AUXST; extract that information 01196 * and create TYLISTs for the entry points. 01197 * 01198 * goes with assumptions in cwh_types_mk_procedure_TY 01199 * and cwh_auxst_patch_proc 01200 * 01201 ==================================================== 01202 */ 01203 extern void 01204 cwh_auxst_set_tylist(ST *en) 01205 { 01206 AUXST * o ; 01207 DUMMIES *e ; 01208 INT32 i; 01209 TYLIST_IDX tylist_idx; 01210 PARMS *parms; 01211 01212 o = cwh_auxst_find(en, FALSE); 01213 e = AUXST_Dummies(o); 01214 01215 /* if total args == 0, may have transformed struct arg into */ 01216 /* function result by value. If so it needs a return type */ 01217 01218 if (e->fe_given_args == 0 && !e->ret_type) 01219 return; 01220 01221 TY& ty = Ty_Table[ST_pu_type(en)]; 01222 01223 (void) New_TYLIST (tylist_idx); 01224 Set_TY_tylist (ty, tylist_idx); 01225 01226 if (ST_auxst_has_rslt_tmp(en) && 01227 !(e->ret_type && (STRUCT_BY_VALUE(e->ret_type)))) { 01228 01229 Tylist_Table [tylist_idx] = e->orig_ret_type; /* returns MTYPE_V */ 01230 01231 } else { 01232 Tylist_Table [tylist_idx] = e->ret_type; 01233 } 01234 01235 01236 /* add each argument */ 01237 01238 parms = e->parms; 01239 01240 for (i= 0 ; i < e->total_args; i++) { 01241 01242 (void) New_TYLIST (tylist_idx); 01243 Tylist_Table [tylist_idx] = PARMS_ty(parms); 01244 parms = PARMS_next(parms); 01245 } 01246 01247 /* mark end of argument list */ 01248 01249 (void) New_TYLIST (tylist_idx); 01250 Tylist_Table [tylist_idx] = 0; 01251 01252 } 01253 01254 /*=================================================== 01255 * 01256 * cwh_auxst_dump_list 01257 * 01258 * Dump a LIST of items. 01259 * 01260 ==================================================== 01261 */ 01262 extern void 01263 cwh_auxst_dump_list (LIST * l, BOOL verbose) 01264 { 01265 ITEM * i; 01266 01267 if (l == NULL) 01268 return ; 01269 01270 if (L_num(l) == 0) 01271 return ; 01272 01273 i = L_first(l); 01274 01275 while (i != NULL) { 01276 if (I_element(i) == NULL) 01277 printf (" < NULL ITEM ??>\n"); 01278 else { 01279 if (verbose) 01280 DUMP_ST(I_element(i)); 01281 else 01282 printf (" 0x%x (%s) \n",I_element(i),ST_name(I_element(i))); 01283 01284 i = I_next(i); 01285 } 01286 } 01287 printf (" \n"); 01288 } 01289 01290 /*=================================================== 01291 * 01292 * cwh_auxst_dump_dummies 01293 * 01294 * Dump a DUMMIES item 01295 * 01296 ==================================================== 01297 */ 01298 static void 01299 cwh_auxst_dump_dummies(DUMMIES * d) 01300 { 01301 INT32 i,k,j ; 01302 01303 if (d == NULL) 01304 return ; 01305 01306 printf (" DUMMIES : 0x%x next : 0x%x \n", 01307 d, 01308 d->next_entry); 01309 01310 if (d->ret_type != 0) 01311 printf (" result TY : 0x%x, \n",d->ret_type); 01312 01313 01314 if (d->total_args != 0) { 01315 01316 printf (" args : total# %d, #fe_given %d, #seen %d, # including lengths %d \n", 01317 d->total_args, 01318 d->fe_given_args, 01319 d->args_seen, 01320 d->arg_lengths_index); 01321 01322 for (i = 0 ; i < d->args_seen ; i ++ ) { 01323 printf (" arg ST : 0x%x (%s) \n", 01324 d->arglist[i], 01325 ST_name( d->arglist[i])); 01326 } 01327 01328 for (i = d->fe_given_args; 01329 i < d->arg_lengths_index ; 01330 i ++) { 01331 01332 printf (" len ST : 0x%x (%s) \n", 01333 d->arglist[i], 01334 ST_name( d->arglist[i])); 01335 } 01336 01337 j = d->args_seen; 01338 01339 PARMS * te = d->parms; 01340 while(te && (j-- >0)) { 01341 printf (" TY : 0x%x %s \n", PARMS_ty(te), 01342 TY_name(PARMS_ty(te))) ; 01343 te = PARMS_next(te); 01344 } 01345 } 01346 printf("\n"); 01347 } 01348 01349 /*=================================================== 01350 * 01351 * cwh_auxst_dump 01352 * 01353 * Dump an AUXST, given an ST. 01354 * 01355 ==================================================== 01356 */ 01357 extern void 01358 cwh_auxst_dump (ST * st) 01359 { 01360 AUXST * o; 01361 LIST * l; 01362 01363 o = cwh_auxst_find(st,FALSE); 01364 01365 if (o == NULL) 01366 return ; 01367 01368 printf ("AUXST: 0x%x next: 0x%x \n",o,AUXST_Next(o)); 01369 01370 if (AUXST_OwningST(o) != NULL ) { 01371 printf (" associated ST: 0x%x (%s) \n", 01372 AUXST_OwningST(o), 01373 ST_name(AUXST_OwningST(o))); 01374 } 01375 01376 if (USRCPOS_filenum(AUXST_SrcPos(o)) != 0) { 01377 printf (" file: %d line: %d \n", 01378 USRCPOS_filenum(AUXST_SrcPos(o)), 01379 USRCPOS_linenum(AUXST_SrcPos(o))); 01380 } 01381 01382 if (AUXST_Flag(o,f_ALTENT)) 01383 printf (" is alternate entry pt \n") ; 01384 01385 if (AUXST_Flag(o,f_ALTTY)) 01386 printf (" alternate entry STs have same TY \n") ; 01387 01388 if (AUXST_Flag(o,f_RSLTTMP)) 01389 printf (" first argument is result varbl \n"); 01390 01391 if (AUXST_Flag(o,f_ELEM)) 01392 printf (" elemental function \n"); 01393 01394 if (AUXST_Flag(o,f_NONCONT)) 01395 printf (" non-contiguous \n"); 01396 01397 if (AUXST_Flag(o,f_AUTO_OR_CPTR)) 01398 printf (" auto or cray pointer\n"); 01399 01400 if (AUXST_Flag(o,f_F90_PTR)) 01401 printf (" f90 pointer \n"); 01402 01403 if (AUXST_Flag(o,f_MODULE)) 01404 printf (" Common for module data \n"); 01405 01406 if (AUXST_Stem(o) != NULL) 01407 printf (" DST name: %s \n",AUXST_Stem(o)); 01408 01409 if (AUXST_Pragma(o)) 01410 printf (" pragma: WN 0x%x \n",AUXST_Pragma(o)) ; 01411 01412 if (AUXST_CRIPointee(o)) 01413 printf (" cri_pointee: ST 0x%x (%s)\n",AUXST_CRIPointee(o),ST_name(AUXST_CRIPointee(o))) ; 01414 01415 if (AUXST_DataInfo(o)) 01416 printf (" data info: 0x%x \n",AUXST_DataInfo(o)) ; 01417 01418 l = cwh_auxst_find_list(o,l_ALTENTRY) ; 01419 if (L_first(l) != NULL){ 01420 printf (" alternate entry points: \n") ; 01421 cwh_auxst_dump_list(l,FALSE); 01422 } 01423 01424 l = cwh_auxst_find_list(o,l_COMLIST); 01425 if (L_first(l) != NULL){ 01426 printf (" common items: \n") ; 01427 cwh_auxst_dump_list(l,FALSE); 01428 } 01429 01430 l = cwh_auxst_find_list(o,l_EQVLIST); 01431 if (L_first(l) != NULL){ 01432 printf (" equivalence items: \n") ; 01433 cwh_auxst_dump_list(l,FALSE); 01434 } 01435 01436 l = cwh_auxst_find_list(o,l_DST_COMLIST); 01437 if (L_first(l) != NULL){ 01438 printf (" commons for dst info: \n") ; 01439 cwh_auxst_dump_list(l,FALSE); 01440 } 01441 01442 l = cwh_auxst_find_list(o,l_DST_PARMLIST); 01443 if (L_first(l) != NULL){ 01444 printf (" parameters for dst info: \n") ; 01445 cwh_auxst_dump_list(l,FALSE); 01446 } 01447 01448 if (AUXST_Dummies(o) != NULL) 01449 cwh_auxst_dump_dummies(AUXST_Dummies(o)); 01450 01451 l = cwh_auxst_find_list(o,l_NAMELIST); 01452 if (L_first(l) != NULL){ 01453 printf (" namelist items: \n") ; 01454 cwh_auxst_dump_list(l,FALSE); 01455 } 01456 01457 l = cwh_auxst_find_list(o,l_RETURN_TEMPS); 01458 if (L_first(l) != NULL){ 01459 printf (" result temps: \n") ; 01460 cwh_auxst_dump_list(l,FALSE); 01461 } 01462 01463 l = cwh_auxst_find_list(o,l_SPLITLIST); 01464 if (L_first(l) != NULL){ 01465 printf (" split commons: \n") ; 01466 cwh_auxst_dump_list(l,FALSE); 01467 } 01468 01469 if (AUXST_AssignId(o) != -1) 01470 printf (" assign id: 0x%x \n", AUXST_AssignId(o)); 01471 01472 if (AUXST_DstrReg(o) != -1) 01473 printf (" distr preg: %d \n", AUXST_DstrReg(o)); 01474 01475 printf ("--\n"); 01476 01477 }