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: Create and put out the DST information. An attempt is 00044 * made to use only ST information (& files), but there 00045 * are inquiries to other cwh* routines for dope vectors, 00046 * commmon elements and line numbers(?). These are indicated 00047 * by macros in cwh_dst.i. The support is enough for f90, 00048 * no effort was made for C or C++. 00049 * 00050 * The entry points are 00051 * 1) cwh_dst_init_file - initialize file level stuff. 00052 * 2) cwh_dst_write - write file's worth of DST to IRB file. 00053 * 3) cwh_dst_enter_pu - build the DST info for a PU. 00054 * 4) cwh_dst_enter_path - enter path of source file. 00055 * 00056 * ==================================================================== 00057 * ==================================================================== 00058 */ 00059 00060 static char *source_file = __FILE__; 00061 #ifdef _KEEP_RCS_ID 00062 #endif /* _KEEP_RCS_ID */ 00063 00064 /* sgi includes */ 00065 00066 #include <limits.h> 00067 #include <sys/stat.h> 00068 #include <unistd.h> 00069 00070 #include "x_stdio.h" // for fileno() 00071 #include "x_string.h" // for strdup() 00072 00073 #include "defs.h" 00074 #include "glob.h" 00075 #include "errors.h" 00076 #include "wn.h" 00077 #include "dwarf_DST_producer.h" 00078 #include "dwarf_DST_dump.h" 00079 #include "config_targ.h" 00080 #include "file_util.h" 00081 00082 /* conversion includes */ 00083 00084 #include "cwh_defines.h" 00085 #include "cwh_dst.h" 00086 #include "cwh_dst.i" 00087 #include "cwh_preg.h" 00088 #include "cwh_stab.h" 00089 #include "cwh_auxst.h" 00090 #include "cwh_types.h" 00091 #include "sgi_cmd_line.h" 00092 00093 char *FE_command_line = NULL; 00094 00095 /*=================================================== 00096 * 00097 * cwh_dst_init_file 00098 * 00099 * DST initialization for a file. Enter the path 00100 * as the first file, and the filename as the 00101 * compile_name. 00102 * 00103 * set the cwd as part of the include paths. 00104 * 00105 ==================================================== 00106 */ 00107 extern void 00108 cwh_dst_init_file(char *src_path) 00109 { 00110 char *comp_info = NULL; 00111 char *file ; 00112 00113 DST_Init(NULL,0) ; 00114 00115 file = strrchr(src_path,'/'); 00116 00117 comp_info = cwh_dst_get_command_line_options(); 00118 00119 00120 comp_unit_idx = DST_mk_compile_unit(++(file), 00121 current_host_dir, 00122 comp_info, 00123 DW_LANG_Fortran90, 00124 DW_ID_case_insensitive); 00125 (void) cwh_dst_enter_path(src_path); 00126 free (comp_info); 00127 } 00128 00129 /*=================================================== 00130 * 00131 * cwh_dst_write 00132 * 00133 * Write out DST information for a file. Each DST 00134 * fe_ptr has to be changed to a back end ST index 00135 * via DST_set_assoc_idx. 00136 * 00137 ==================================================== 00138 */ 00139 extern void 00140 cwh_dst_write(void) 00141 { 00142 00143 file_name_idx = DST_write_files(); 00144 incl_dir_idx = DST_write_directories(); 00145 00146 if (!DST_IS_NULL(comp_unit_idx)) 00147 (void) DST_preorder_visit(comp_unit_idx, 0, &DST_set_assoc_idx); 00148 00149 if (DSTdump_File_Name != NULL) { 00150 00151 DST_set_dump_filename(DSTdump_File_Name); 00152 DST_dump(incl_dir_idx, file_name_idx, comp_unit_idx); 00153 } 00154 00155 } 00156 00157 static void 00158 cwh_dst_process_var (UINT32, ST* st) 00159 { 00160 switch(ST_class(st)) { 00161 00162 case CLASS_VAR: 00163 cwh_dst_mk_var(st,current_scope_idx); 00164 break; 00165 00166 case CLASS_CONST: 00167 cwh_dst_mk_const(st,current_scope_idx); 00168 break; 00169 } 00170 } 00171 00172 /*=================================================== 00173 * 00174 * cwh_dst_mk_const 00175 * 00176 * Write out DST information for a constant. 00177 * 00178 ==================================================== 00179 */ 00180 static void 00181 cwh_dst_mk_const(ST * st,DST_INFO_IDX parent) 00182 { 00183 DST_CONST_VALUE cval; 00184 USRCPOS s; 00185 int exit = 0; 00186 DST_INFO_IDX i,t ; 00187 char *ptr; 00188 TY_IDX ty; 00189 TYPE_ID type ; 00190 char *name; 00191 char *str; 00192 00193 00194 /* DST_mk_constant_def(USRCPOS decl, Source location */ 00195 /* char *name, Name of constant */ 00196 /* DST_INFO_IDX type, Type of constant */ 00197 /* DST_CONST_VALUE cval, Value of constant */ 00198 /* BOOL is_external) External? */ 00199 00200 s = GET_ST_LINENUM(st); 00201 00202 ty = ST_type(st); 00203 type = TY_mtype(ty); 00204 t = cwh_dst_mk_type(ty); 00205 00206 switch(TY_mtype(ty)) { 00207 00208 case MTYPE_I1: 00209 case MTYPE_U1: 00210 DST_CONST_VALUE_form(cval) = DST_FORM_DATA1; 00211 DST_CONST_VALUE_form_data1(cval) = TCON_i0(Tcon_Table[ST_tcon(st)]); 00212 break; 00213 00214 case MTYPE_I2: 00215 case MTYPE_U2: 00216 DST_CONST_VALUE_form(cval) = DST_FORM_DATA2; 00217 DST_CONST_VALUE_form_data2(cval) = TCON_i0(Tcon_Table[ST_tcon(st)]); 00218 break; 00219 00220 case MTYPE_I4: 00221 case MTYPE_U4: 00222 DST_CONST_VALUE_form(cval) = DST_FORM_DATA4; 00223 DST_CONST_VALUE_form_data4(cval) = TCON_i0(Tcon_Table[ST_tcon(st)]); 00224 break; 00225 00226 case MTYPE_I8: 00227 case MTYPE_U8: 00228 DST_CONST_VALUE_form(cval) = DST_FORM_DATA8; 00229 DST_CONST_VALUE_form_data8(cval) = TCON_i0(Tcon_Table[ST_tcon(st)]); 00230 break; 00231 00232 case MTYPE_F4: 00233 DST_CONST_VALUE_form(cval) = DST_FORM_DATA4; 00234 DST_CONST_VALUE_form_data4(cval) = TCON_ival(Tcon_Table[ST_tcon(st)]); 00235 break; 00236 00237 case MTYPE_F8: 00238 DST_CONST_VALUE_form(cval) = DST_FORM_DATA8; 00239 DST_CONST_VALUE_form_data8(cval) = TCON_i0(Tcon_Table[ST_tcon(st)]); 00240 break; 00241 00242 case MTYPE_F16: 00243 case MTYPE_FQ: 00244 exit = 1; 00245 break; 00246 00247 case MTYPE_STR: /* Not generally used. */ 00248 exit = 1; 00249 break; 00250 00251 # if 0 00252 DST_CONST_VALUE_form(cval) = DST_FORM_STRING; 00253 DST_CONST_VALUE_form_string(cval) = 00254 DST_mk_string (Index_to_char_array (TCON_str_idx (ST_tcon_val(st)))); 00255 # endif 00256 00257 case MTYPE_UNKNOWN: 00258 00259 if (TY_kind(ty) == KIND_ARRAY && TY_is_character(ty)) { 00260 DST_CONST_VALUE_form(cval) = DST_FORM_STRING; 00261 DST_CONST_VALUE_form_string(cval) = 00262 DST_mk_string (Index_to_char_array (TCON_str_idx (ST_tcon_val(st)))); 00263 } 00264 break; 00265 } 00266 00267 if (exit == 1) return; /* Type is not implemented. */ 00268 00269 name = NULL; 00270 name = cwh_auxst_stem_name(st, name); 00271 00272 ptr = strtok(name, " "); 00273 00274 while (ptr != NULL) { 00275 i = DST_mk_constant_def(s, 00276 ptr, 00277 t, 00278 cval, 00279 FALSE); 00280 DST_append_child(current_scope_idx,i); 00281 ptr = strtok(NULL, " "); 00282 } 00283 return; 00284 } 00285 00286 /*=================================================== 00287 * 00288 * cwh_dst_enter_pu 00289 * 00290 * Enter DST information for this PU. The entry point 00291 * is required in the PU_info, and alternate entry points 00292 * are always generated, but the local symbols 00293 * are only generated with -g. 00294 * 00295 ==================================================== 00296 */ 00297 extern DST_IDX 00298 cwh_dst_enter_pu(ST *en) 00299 { 00300 00301 ITEM * al; 00302 ITEM * com; 00303 ITEM * parm; 00304 ST * st; 00305 DST_INFO_IDX i; 00306 PU& pu = Pu_Table[ST_pu(en)]; 00307 00308 00309 DST_begin_PU(); 00310 cwh_dst_struct_clear_DSTs(); 00311 00312 current_scope_idx = cwh_dst_mk_func(en); 00313 00314 if (PU_is_mainpu(pu)) 00315 cwh_dst_mk_MAIN(GET_MAIN_ST(),current_scope_idx); 00316 00317 /* nested? so is dwarf. Save idx until parent appears */ 00318 00319 if (PU_is_nested_func(pu)) 00320 cwh_dst_inner_add_DST(current_scope_idx); 00321 00322 else { 00323 00324 cwh_dst_inner_read_DSTs(current_scope_idx); 00325 cwh_dst_inner_clear_DSTs(); 00326 DST_append_child(comp_unit_idx,current_scope_idx); 00327 } 00328 00329 al = NULL ; 00330 while ((al = GET_NEXT_ALTENTRY(en,al)) != NULL) { 00331 i = cwh_dst_mk_func(I_element(al)); 00332 DST_append_child(comp_unit_idx,i); 00333 } 00334 00335 00336 if (Debug_Level > 0) { 00337 00338 /* Set up integer DSTs so MP lowerer can make DSTs for */ 00339 /* loop varbls and so forth (wn_mp.c Add_DST_variable) */ 00340 00341 (void) cwh_dst_basetype(Be_Type_Tbl(MTYPE_I4)); 00342 (void) cwh_dst_basetype(Be_Type_Tbl(MTYPE_I8)); 00343 00344 For_all (St_Table, CURRENT_SYMTAB, &cwh_dst_process_var); 00345 00346 /* look for commons or module data referenced within this */ 00347 /* PU, but promoted to the global symbol table */ 00348 00349 ITEM * com = NULL; 00350 ITEM * parm = NULL; 00351 00352 if (PU_lexical_level(pu) == 2) 00353 while ((com = GET_NEXT_COMMON(en,com)) != NULL) 00354 cwh_dst_mk_var(I_element(com),current_scope_idx); 00355 00356 if (PU_lexical_level(pu) == 2) 00357 while ((parm = GET_NEXT_PARAMETER(en,parm)) != NULL) 00358 cwh_dst_process_var(1, I_element(parm)); 00359 00360 } 00361 00362 DST_end_PU(); 00363 00364 return(current_scope_idx); 00365 } 00366 00367 /*=================================================== 00368 * 00369 * cwh_dst_mk_func 00370 * 00371 * Enter DST information for a CLASS_FUNC symbol, 00372 * ie: a procedure entry point. 00373 * 00374 * If it was an internal or module procedure the 00375 * name might not be the same as seen by the linker. 00376 * 00377 * Strip off any trailing underscores.. 00378 * 00379 *=================================================== 00380 */ 00381 static DST_IDX 00382 cwh_dst_mk_func(ST * st) 00383 { 00384 00385 DST_INFO_IDX t; 00386 DST_INFO_IDX i; 00387 00388 USRCPOS s; 00389 char *p ; 00390 char *r ; 00391 char *l ; 00392 INT32 n ; 00393 TY_IDX ty; 00394 PU& pu = Pu_Table[ST_pu(st)]; 00395 00396 s = GET_ST_LINENUM(st); 00397 00398 l = NULL; 00399 p = GET_MODIFIED_NAME(st); 00400 if (p != NULL) 00401 r = p ; 00402 00403 else { 00404 r = ST_name(st); 00405 n = strlen(r); 00406 00407 if (r[n-1] == '_') { 00408 l = ux_strdup(r); 00409 l[n-1] = '\0'; 00410 r = l ; 00411 } 00412 } 00413 00414 ty = PU_prototype(Pu_Table[ST_pu(st)]); 00415 t = cwh_dst_mk_subroutine_type(ty); 00416 00417 if (IS_ALTENTRY(st)) 00418 i = DST_mk_entry_point(s,r,t,(void *)ST_st_idx(st)); 00419 00420 else { 00421 i = DST_mk_subprogram(s, 00422 r, 00423 t, 00424 DST_INVALID_IDX, 00425 (void*)ST_st_idx(st), 00426 DW_INL_not_inlined, 00427 DW_VIRTUALITY_none, 00428 0, 00429 FALSE, 00430 FALSE, 00431 FALSE, 00432 TRUE); 00433 00434 if (p != NULL && !PU_is_mainpu(pu)) 00435 DST_add_linkage_name_to_subprogram(i,ST_name(st)); 00436 } 00437 00438 if (l != NULL) 00439 free(l); 00440 00441 return i; 00442 } 00443 00444 /*=================================================== 00445 * 00446 * cwh_dst_mk_MAIN 00447 * 00448 * If this is a named program a DST for MAIN_ is 00449 * also required, so the debugger can find which 00450 * file contains the program stmt. If anonymous, 00451 * then a DST entry for MAIN has already been created 00452 * and mn == NULL. It's distinct from mk_func_entry 00453 * because the arguments to mk_subprogram are for 00454 * a declaration & weak symbol 00455 * 00456 *=================================================== 00457 */ 00458 static void 00459 cwh_dst_mk_MAIN(ST *mn, DST_INFO_IDX en_idx) 00460 { 00461 DST_INFO_IDX t; 00462 DST_INFO_IDX i; 00463 USRCPOS s; 00464 TY_IDX ty; 00465 00466 if (mn != NULL) { 00467 00468 s = GET_ST_LINENUM(mn); 00469 ty = PU_prototype(Pu_Table[ST_pu(mn)]); 00470 t = cwh_dst_mk_subroutine_type(ty); 00471 i = DST_mk_subprogram(s, 00472 ST_name(mn), 00473 t, 00474 en_idx, 00475 (void*) ST_st_idx(mn), 00476 DW_INL_not_inlined, 00477 DW_VIRTUALITY_none, 00478 0, 00479 TRUE, 00480 FALSE, 00481 FALSE, 00482 TRUE); 00483 00484 DST_append_child(comp_unit_idx,i); 00485 } 00486 } 00487 00488 /*=================================================== 00489 * 00490 * cwh_dst_mk_var 00491 * 00492 * Enter DST information for a CLASS_VAR symbol, 00493 * ie: a variable. Variables in COMMON are ignored here, 00494 * but processed when the COMMON symbol is seen. Ditto 00495 * temps when required as bounds, etc. We assume a ST 00496 * name beginning with '@' is not required (it's a base) 00497 * as it can't be printed in the debugger, but module 00498 * dats is a COMMON starting with @.. 00499 * 00500 * The DST is appended to the parent. 00501 * 00502 *=================================================== 00503 */ 00504 static void 00505 cwh_dst_mk_var(ST * st,DST_INFO_IDX parent) 00506 { 00507 00508 DST_INFO_IDX i ; 00509 DST_INFO_IDX j ; 00510 00511 Top_ST = st ; 00512 Making_FLD_DST = FALSE; 00513 00514 switch(ST_sclass(st)) { 00515 00516 case SCLASS_FORMAL: 00517 case SCLASS_FORMAL_REF: 00518 if (!ST_is_temp_var(st)) { 00519 Top_ST_has_dope = cwh_dst_has_dope(ST_type(st)); 00520 i = cwh_dst_mk_formal(st) ; 00521 DST_append_child(parent,i); 00522 } 00523 break; 00524 00525 case SCLASS_COMMON: 00526 case SCLASS_DGLOBAL: 00527 i = cwh_dst_mk_common(st); 00528 if (!DST_IS_NULL(i)) { 00529 j = cwh_dst_mk_common_inclusion(st,i); 00530 00531 DST_append_child(parent,j); 00532 DST_append_child(parent,i); 00533 } 00534 break; 00535 00536 default: 00537 if (Has_Base_Block(st)) { 00538 if ((ST_sclass(ST_base(st)) != SCLASS_COMMON) && 00539 (ST_sclass(ST_base(st)) != SCLASS_DGLOBAL)) { 00540 Top_ST_has_dope = cwh_dst_has_dope(ST_type(st)); 00541 i = cwh_dst_mk_variable(st); 00542 DST_append_child(parent,i); 00543 } 00544 } else if (!ST_is_temp_var(st)) { 00545 if (* ST_name(st) != '@') { 00546 Top_ST_has_dope = cwh_dst_has_dope(ST_type(st)); 00547 i = cwh_dst_mk_variable(st); 00548 DST_append_child(parent,i); 00549 } 00550 } 00551 break; 00552 } 00553 } 00554 00555 /*=================================================== 00556 * 00557 * cwh_dst_mk_variable 00558 * 00559 * Enter DST information for an ST of CLASS_VAR and 00560 * and any of the static/auto sclasses. For BASED 00561 * variables, the ST of the base provides the ST 00562 * which later generates location information, but 00563 * cgdwarf.c figures this out. COMMON block elements 00564 * aren't processed here. 00565 * 00566 *=================================================== 00567 */ 00568 static DST_INFO_IDX 00569 cwh_dst_mk_variable(ST * st) 00570 { 00571 TY_IDX d; 00572 DST_VARIABLE *def_attr; 00573 DST_ATTR_IDX def_attr_idx; 00574 DST_INFO *def_info; 00575 BOOL dr; 00576 DST_INFO_IDX dope_ty; 00577 DST_INFO_IDX i; 00578 USRCPOS s; 00579 DST_INFO_IDX t; 00580 00581 00582 s = GET_ST_LINENUM(st); 00583 d = ST_type(st) ; 00584 00585 dr = (Has_Base_Block(st)) && ST_auxst_is_auto_or_cpointer(st) ; 00586 00587 if (IS_DOPE_TY(d)) { 00588 t = cwh_dst_dope_type(ST_type(st), 00589 st, 00590 ST_ofst(st), 00591 current_scope_idx, 00592 FALSE, 00593 &dope_ty); 00594 dr = TRUE ; 00595 } else 00596 t = cwh_dst_mk_type(d); 00597 00598 i = DST_mk_variable(s, 00599 ST_name(st), 00600 t, 00601 0, 00602 (void *) ST_st_idx(st), 00603 DST_INVALID_IDX, 00604 FALSE, 00605 ST_sclass(st) == SCLASS_AUTO, 00606 FALSE, 00607 ST_auxst_is_tmp(st)); 00608 00609 if (ST_auxst_is_assumed_size(st)) { 00610 DST_SET_assumed_size(DST_INFO_flag(DST_INFO_IDX_TO_PTR(i))); 00611 } 00612 00613 if (IS_DOPE_TY(d)) { 00614 def_info = DST_INFO_IDX_TO_PTR(i); 00615 def_attr_idx = DST_INFO_attributes(def_info); 00616 def_attr = DST_ATTR_IDX_TO_PTR(def_attr_idx, DST_VARIABLE); 00617 00618 DST_VARIABLE_def_dopetype(def_attr) = dope_ty; 00619 00620 if (ST_auxst_is_assumed_shape(st)) { 00621 DST_SET_assumed_shape(DST_INFO_flag(def_info)); 00622 } 00623 else if (ST_auxst_is_allocatable(st)) { 00624 DST_SET_allocatable(DST_INFO_flag(def_info)); 00625 } 00626 else if (ST_auxst_is_f90_pointer(st)) { 00627 DST_SET_f90_pointer(DST_INFO_flag(def_info)); 00628 } 00629 } 00630 00631 if (dr) 00632 DST_SET_deref(DST_INFO_flag(DST_INFO_IDX_TO_PTR(i))); 00633 00634 return i ; 00635 00636 } 00637 /*=================================================== 00638 * 00639 * cwh_dst_mk_formal 00640 * 00641 * Enter DST information for an ST of CLASS_VAR and 00642 * SCLASS_FORMAL. Assumes a formal parameter which 00643 * has a pointer TY is a fortran parameter by reference. 00644 * 00645 *=================================================== 00646 */ 00647 static DST_INFO_IDX 00648 cwh_dst_mk_formal(ST * st) 00649 { 00650 ST_IDX ba; 00651 DST_FORMAL_PARAMETER *def_attr; 00652 DST_ATTR_IDX def_attr_idx; 00653 DST_INFO *def_info; 00654 DST_INFO_IDX dope_ty; 00655 BOOL dr ; 00656 DST_INFO_IDX t; 00657 TY_IDX ta; 00658 TY_IDX ty; 00659 00660 BOOL c_pointee = FALSE; 00661 BOOL generated = FALSE ; 00662 DST_INFO_IDX i = DST_INVALID_IDX ; 00663 00664 USRCPOS s; 00665 00666 00667 s = GET_ST_LINENUM(st); 00668 00669 ty = ST_type(st); 00670 ta = ty ; 00671 dr = FALSE ; 00672 ba = ST_st_idx(st) ; 00673 00674 /* cray pointee? */ 00675 00676 if (Has_Base_Block(st)) { 00677 ba = ST_st_idx(ST_base(st)) ; 00678 c_pointee = TRUE; 00679 } 00680 00681 /* If FORMAL is result temp address, it's by_value */ 00682 /* if array/struct temp, it's by ref */ 00683 /* other by-values are scalars eg: char len temps */ 00684 00685 if (ST_sclass(st) == SCLASS_FORMAL) 00686 if (!ST_is_value_parm(st)) 00687 ta = TY_pointed(ty); 00688 else if (TY_kind(ty) == KIND_POINTER) 00689 ta = TY_pointed(ty); 00690 00691 00692 if (IS_DOPE_TY(ta)) { 00693 t = cwh_dst_dope_type(ST_type(st), 00694 st, 00695 ST_ofst(st), 00696 current_scope_idx, 00697 FALSE, 00698 &dope_ty); 00699 dr = TRUE ; 00700 } else 00701 t = cwh_dst_mk_type(ta); 00702 00703 i = DST_mk_formal_parameter(s, 00704 ST_name(st), 00705 t, 00706 (void *) ba, 00707 DST_INVALID_IDX, 00708 DST_INVALID_IDX, 00709 FALSE, /* FIX optional */ 00710 FALSE, 00711 generated, 00712 FALSE); /* is_declaration_only */ 00713 00714 00715 00716 if (IS_DOPE_TY(ta)) { 00717 def_info = DST_INFO_IDX_TO_PTR(i); 00718 def_attr_idx = DST_INFO_attributes(def_info); 00719 def_attr = DST_ATTR_IDX_TO_PTR(def_attr_idx, DST_FORMAL_PARAMETER); 00720 00721 DST_FORMAL_PARAMETER_dopetype(def_attr) = dope_ty; 00722 00723 if (ST_auxst_is_assumed_shape(st)) { 00724 DST_SET_assumed_shape(DST_INFO_flag(def_info)); 00725 } 00726 else if (ST_auxst_is_f90_pointer(st)) { 00727 DST_SET_f90_pointer(DST_INFO_flag(def_info)); 00728 } 00729 } 00730 00731 if (ST_auxst_is_assumed_size(st)) { 00732 DST_SET_assumed_size(DST_INFO_flag(DST_INFO_IDX_TO_PTR(i))); 00733 } 00734 00735 if ( dr || 00736 (TY_kind(ty) == KIND_POINTER) || 00737 (ST_sclass(st) == SCLASS_FORMAL_REF)) 00738 DST_SET_deref(DST_INFO_flag( DST_INFO_IDX_TO_PTR(i))); 00739 00740 if (dr || c_pointee) 00741 DST_SET_base_deref(DST_INFO_flag( DST_INFO_IDX_TO_PTR(i))); 00742 00743 return i; 00744 } 00745 00746 /*=================================================== 00747 * 00748 * cwh_dst_mk_common_inclusion 00749 * 00750 * Adds a common_inclusion to the DST. Sets up 00751 * the line number of the common. 00752 * 00753 ==================================================== 00754 */ 00755 static DST_INFO_IDX 00756 cwh_dst_mk_common_inclusion(ST * com, DST_INFO_IDX c) 00757 { 00758 DST_INFO_IDX i; 00759 00760 USRCPOS s; 00761 00762 s = GET_ST_LINENUM(com); 00763 00764 i = DST_mk_common_incl(s,c); 00765 00766 return i; 00767 } 00768 00769 /*=================================================== 00770 * 00771 * cwh_dst_mk_common 00772 * 00773 * Enter DST information for a COMMON block and 00774 * all of its members. It assumes the COMMON TY 00775 * is a struct, and its members are all on the TY. 00776 * 00777 *=================================================== 00778 */ 00779 static DST_INFO_IDX 00780 cwh_dst_mk_common(ST * st) 00781 { 00782 BOOL dr; 00783 DST_VARIABLE *def_attr; 00784 DST_ATTR_IDX def_attr_idx; 00785 DST_INFO *def_info; 00786 DST_INFO_IDX dope_ty; 00787 ITEM *e; 00788 ST *el; 00789 DST_INFO_IDX i; 00790 DST_INFO_IDX m; 00791 DST_INFO_IDX t; 00792 USRCPOS s; 00793 TY_IDX te; 00794 TY_IDX ty; 00795 00796 00797 ty = ST_type(st); 00798 00799 DevAssert((TY_kind(ty) == KIND_STRUCT),("DST complains about common")); 00800 00801 i = DST_mk_common_block(ST_name(st),(void*) ST_st_idx(st)); 00802 00803 e = NULL ; 00804 00805 while ((e = GET_NEXT_ELEMENT_ST(st,e)) != NULL) { 00806 00807 el = I_element(e); 00808 s = GET_ST_LINENUM(st); 00809 te = ST_type(el); 00810 00811 Top_ST = el; 00812 Top_ST_has_dope = cwh_dst_has_dope(te); 00813 00814 dr = IS_DOPE_TY(te); 00815 00816 if (dr) { 00817 t = cwh_dst_dope_type(ST_type(el), 00818 el, 00819 ST_ofst(el), 00820 i, 00821 FALSE, 00822 &dope_ty); 00823 } else 00824 t = cwh_dst_mk_type(te); 00825 00826 m = DST_mk_variable_comm(s, 00827 ST_name(el), 00828 t, 00829 (void *) ST_st_idx(st), 00830 ST_ofst(el)) ; 00831 00832 if (dr) { 00833 def_info = DST_INFO_IDX_TO_PTR(m); 00834 def_attr_idx = DST_INFO_attributes(def_info); 00835 def_attr = DST_ATTR_IDX_TO_PTR(def_attr_idx, DST_VARIABLE); 00836 00837 DST_VARIABLE_comm_dopetype(def_attr) = dope_ty; 00838 00839 if (ST_auxst_is_assumed_shape(el)) { 00840 DST_SET_assumed_shape(DST_INFO_flag(def_info)); 00841 } 00842 else if (ST_auxst_is_allocatable(el)) { 00843 DST_SET_allocatable(DST_INFO_flag(def_info)); 00844 } 00845 else if (ST_auxst_is_f90_pointer(el)) { 00846 DST_SET_f90_pointer(DST_INFO_flag(def_info)); 00847 } 00848 } 00849 00850 if (ST_auxst_is_assumed_size(el)) { 00851 DST_SET_assumed_size(DST_INFO_flag(DST_INFO_IDX_TO_PTR(m))); 00852 } 00853 00854 if (dr) 00855 DST_SET_deref(DST_INFO_flag( DST_INFO_IDX_TO_PTR(m))); 00856 00857 DST_append_child(i,m); 00858 } 00859 00860 return i; 00861 } 00862 00863 /*=================================================== 00864 * 00865 * cwh_dst_mk_type 00866 * 00867 * Make or find the DST info of this TY. 00868 * 00869 *=================================================== 00870 */ 00871 static DST_INFO_IDX 00872 cwh_dst_mk_type(TY_IDX ty) 00873 { 00874 DST_INFO_IDX i; 00875 00876 switch (TY_kind(ty)) { 00877 case KIND_VOID: 00878 i = DST_INVALID_IDX; 00879 break; 00880 00881 case KIND_SCALAR: 00882 i = cwh_dst_basetype(ty); 00883 break ; 00884 00885 case KIND_ARRAY: 00886 i = cwh_dst_array_type(ty); 00887 break ; 00888 00889 case KIND_STRUCT: 00890 i = cwh_dst_struct_type(ty); 00891 break; 00892 00893 case KIND_POINTER: 00894 i = cwh_dst_pointer_type(ty); 00895 break; 00896 00897 case KIND_FUNCTION: 00898 i = cwh_dst_mk_subroutine_type(ty); 00899 break ; 00900 00901 default: 00902 DevAssert((0),("DST TY")); 00903 } 00904 00905 return i; 00906 } 00907 00908 /*=================================================== 00909 * 00910 * cwh_dst_basetype 00911 * 00912 * Given a SCALAR ty, returns the corresponding DST 00913 * basetype for its typeid. Appends it to compilation 00914 * unit to avoid duplication. 00915 * 00916 *=================================================== 00917 */ 00918 static DST_INFO_IDX 00919 cwh_dst_basetype(TY_IDX ty) 00920 { 00921 TYPE_ID bt ; 00922 DST_INFO_IDX i ; 00923 00924 bt = TY_mtype(ty); 00925 00926 if (bt == MTYPE_V) return(DST_INVALID_IDX); 00927 00928 if (TY_is_logical(Ty_Table[ty])) 00929 bt = bt -MTYPE_I1 + MTYPE_V + 1 ; 00930 00931 if (!DST_IS_NULL(base_types[bt])) 00932 return base_types[bt]; 00933 00934 i = DST_mk_basetype(ate_types[bt].name, 00935 ate_types[bt].encoding, 00936 ate_types[bt].size); 00937 00938 base_types[bt] = i; 00939 DST_append_child(comp_unit_idx,i); 00940 return i; 00941 } 00942 00943 /*=================================================== 00944 * 00945 * cwh_dst_pointer_type 00946 * 00947 * Given a pointer TY, return an IDX. 00948 * Appends it to the current scope. 00949 * 00950 *=================================================== 00951 */ 00952 static DST_INFO_IDX 00953 cwh_dst_pointer_type(TY_IDX ty) 00954 { 00955 DST_INFO_IDX i; 00956 DST_INFO_IDX t; 00957 00958 t = cwh_dst_mk_type(TY_pointed(ty)); 00959 i = DST_mk_pointer_type(t, 00960 DW_ADDR_none, 00961 TY_size(ty)); 00962 00963 DST_append_child(current_scope_idx,i); 00964 return i ; 00965 00966 } 00967 00968 /*=================================================== 00969 * 00970 * cwh_dst_mk_subroutine_type 00971 * 00972 * Make the type DST info for a subroutine. 00973 * 00974 *=================================================== 00975 */ 00976 static DST_INFO_IDX 00977 cwh_dst_mk_subroutine_type(TY_IDX ty) 00978 { 00979 DST_INFO_IDX t ; 00980 00981 /* TEMPORARY TO DO FIX */ 00982 t = cwh_dst_basetype(Be_Type_Tbl(MTYPE_V)); 00983 /* t = cwh_dst_mk_type(TY_ret_type(ty)); TODO fix with scope */ 00984 00985 #if 0 00986 if (!DST_IS_NULL(t)) { 00987 00988 USRCPOS_clear(s); 00989 00990 i = DST_mk_subroutine_type(s, 00991 NULL, 00992 t, 00993 DST_INVALID_IDX, 00994 FALSE); 00995 00996 } 00997 DST_append_child(current_scope_idx,i); 00998 return i; 00999 #endif 01000 return t ; 01001 } 01002 01003 /*=================================================== 01004 * 01005 * cwh_dst_array_type 01006 * 01007 * Given a ARRAY ty, returns a DST_IDX for the 01008 * TY. Appends it to the current scope. 01009 * 01010 *=================================================== 01011 */ 01012 static DST_INFO_IDX 01013 cwh_dst_array_type(TY_IDX ty) 01014 { 01015 01016 DST_INFO_IDX i ; 01017 DST_INFO_IDX t ; 01018 DST_INFO_IDX d ; 01019 01020 USRCPOS s; 01021 INT32 j; 01022 INT idx; 01023 01024 USRCPOS_clear(s); 01025 01026 if (cwh_dst_is_character_TY(ty)) { 01027 i = cwh_dst_substring_type(ty); 01028 01029 } else { 01030 01031 t = cwh_dst_mk_type(TY_AR_etype(ty)); 01032 i = DST_mk_array_type(s, 01033 TY_name(ty), 01034 t, 01035 0, 01036 DST_INVALID_IDX, 01037 TRUE); 01038 01039 TY& tt = Ty_Table[ty]; 01040 ARB_HANDLE arb = TY_arb(ty); 01041 for (idx = TY_AR_ndims(ty) - 1; idx >=0 ; idx--) { 01042 d = cwh_dst_subrange(arb[idx]) ; 01043 DST_append_child(i,d); 01044 } 01045 } 01046 DST_append_child(current_scope_idx,i); 01047 return i; 01048 } 01049 01050 /*=================================================== 01051 * 01052 * cwh_dst_struct_type 01053 * 01054 * Given a STRUCT TY, returns a DST_IDX for the 01055 * TY. Appends it to the current scope. 01056 * 01057 * A list of DSTs associated with STRUCT TYs is 01058 * kept for recursive types. 01059 * 01060 *=================================================== 01061 */ 01062 static DST_INFO_IDX 01063 cwh_dst_struct_type(TY_IDX ty) 01064 { 01065 DST_INFO_IDX i ; 01066 01067 USRCPOS s; 01068 01069 USRCPOS_clear(s); 01070 01071 i = cwh_dst_struct_has_DST(ty); 01072 01073 if (DST_IS_NULL(i) || Top_ST_has_dope) { 01074 01075 i = DST_mk_structure_type(s, 01076 TY_name(ty), 01077 TY_size(ty), 01078 DST_INVALID_IDX, 01079 FALSE); 01080 01081 Top_ST_has_dope = FALSE; 01082 cwh_dst_struct_set_DST(ty,i) ; 01083 01084 FLD_HANDLE f = TY_fld(Ty_Table[ty]); 01085 01086 while (!f.Is_Null ()) { 01087 (void) cwh_dst_member(f,i); 01088 f = FLD_next(f); 01089 } 01090 01091 DST_append_child(current_scope_idx, i); 01092 } 01093 01094 return i; 01095 } 01096 01097 /*=================================================== 01098 * 01099 * cwh_dst_substring_type 01100 * 01101 * Given a character TY with a 1D KIND_ARRAY of 01102 * scalars, make the substring IDX. 01103 * 01104 *=================================================== 01105 */ 01106 static DST_INFO_IDX 01107 cwh_dst_substring_type(TY_IDX ty) 01108 { 01109 01110 DST_INFO_IDX i ; 01111 DST_cval_ref len ; 01112 DST_flag const_len ; 01113 USRCPOS s; 01114 01115 USRCPOS_clear(s); 01116 01117 ARB_HANDLE arb = TY_arb(ty); 01118 01119 const_len = ARB_const_ubnd(arb); 01120 01121 if (const_len) 01122 len.cval = ARB_ubnd_val(arb); 01123 else { 01124 len.ref = cwh_dst_mk_variable(&St_Table[ARB_ubnd_var(arb)]); 01125 DST_append_child(current_scope_idx,len.ref); 01126 } 01127 01128 i = DST_mk_string_type(s, 01129 TY_name(ty), 01130 const_len, 01131 len); 01132 01133 DST_append_child(current_scope_idx, i); 01134 return i; 01135 } 01136 01137 /*=================================================== 01138 * 01139 * cwh_dst_is_character_TY 01140 * 01141 * Given TY, returns T if this is the TY that 01142 * represents a character substring. ie: a 01143 * 1D KIND_ARRAY of scalar characters. Assumed 01144 * to be called with an KIND_ARRAY. 01145 * 01146 *=================================================== 01147 */ 01148 static BOOL 01149 cwh_dst_is_character_TY(TY_IDX ty) 01150 { 01151 TY_IDX ts ; 01152 BOOL rs ; 01153 01154 DevAssert((TY_kind(ty) == KIND_ARRAY),("bad char ty")); 01155 01156 rs = FALSE; 01157 ts = TY_AR_etype(ty); 01158 01159 if (TY_is_character(Ty_Table[ts])) 01160 if (TY_kind(ts) == KIND_SCALAR) 01161 rs = TRUE; 01162 01163 return rs ; 01164 } 01165 01166 /*=================================================== 01167 * 01168 * cwh_dst_dope_type 01169 * 01170 * Given a TY which which uses a dope vector, make 01171 * the type IDX for the dope and pass it back. The 01172 * ST is a convenience to form adresses in the subrange 01173 * IDX (bounds expressions) for assumed shape dummies. 01174 * (to get the correct dereferencing). if the ST is NULL 01175 * then it's a type component and the derefs are constant 01176 * offsets into the type. 01177 * 01178 * The address in the dope is at location 0, so there 01179 * isn't any fiddling with the offset in the parent 01180 * routines, just the offset of a derived type entry 01181 * or common. 01182 * 01183 * comp == component of derived type. 01184 * 01185 *=================================================== 01186 */ 01187 static DST_INFO_IDX 01188 cwh_dst_dope_type(TY_IDX td , ST * st, mINT64 off, DST_INFO_IDX parent, BOOL comp, DST_INFO_IDX *dope_ty) 01189 { 01190 DST_INFO_IDX i ; 01191 DST_INFO_IDX t ; 01192 01193 USRCPOS s; 01194 TY_IDX ty; 01195 01196 char *n = '\0'; 01197 01198 USRCPOS_clear(s); 01199 01200 /* Create a type for the dope vector itself. This is attached to the */ 01201 /* object to be used by the debugger for cracking the dope vector. */ 01202 01203 *dope_ty = cwh_dst_mk_type(td); 01204 01205 ty = GET_DOPE_BASE_TY(td); 01206 01207 if (TY_kind(ty) == KIND_ARRAY) { 01208 ty = TY_AR_etype(ty); 01209 01210 t = cwh_dst_mk_type(ty); 01211 i = DST_mk_array_type(s,n,t,0,DST_INVALID_IDX,TRUE); 01212 01213 cwh_dst_dope_bounds(td,st,off,i,parent, comp); 01214 DST_append_child(parent,i); 01215 01216 } else { 01217 01218 i = cwh_dst_mk_type(ty); 01219 01220 } 01221 01222 if (comp) { 01223 i = DST_mk_pointer_type(i, 01224 DW_ADDR_none, 01225 Pointer_Size); 01226 DST_append_child(parent,i); 01227 } 01228 01229 return i ; 01230 } 01231 01232 /*=================================================== 01233 * 01234 * cwh_dst_dope_bounds 01235 * 01236 * Get the bounds associated with the dope and 01237 * put them into subrange types. There may not be 01238 * any in a scalar pointer. This assumes the bounds 01239 * are an array of STRUCTs, each - lb,ub,str - and the 01240 * bounds are all the same size. 01241 * 01242 * td - dope vector TY. 01243 * st - NULL if in dtype, or symbol ST. 01244 * off - offset of dope into derived type, or 01245 * arr idx of array type DST 01246 * p - parent idx (symbol or current scope) 01247 * comp - TRUE if component of derived type 01248 *=================================================== 01249 */ 01250 static void 01251 cwh_dst_dope_bounds(TY_IDX td, ST * st, mINT64 off, DST_INFO_IDX arr, DST_INFO_IDX p, BOOL comp) 01252 { 01253 TY_IDX tf; 01254 01255 DST_cval_ref u ; 01256 DST_cval_ref l ; 01257 01258 DST_INFO_IDX i ; 01259 DST_INFO_IDX t ; 01260 DST_INFO_IDX s ; 01261 DST_INFO_IDX x ; 01262 01263 INT32 rnk,k,sz; 01264 BOOL str = FALSE; 01265 enum str_knd kind; 01266 01267 FLD_HANDLE fld = GET_DOPE_BOUNDS(td); 01268 01269 if (st != NULL) 01270 str = (ST_sclass(st) == SCLASS_FORMAL) || (ST_sclass(st) == SCLASS_FORMAL_REF) ; 01271 01272 str = TY_is_f90_pointer(Ty_Table[td]) || str; 01273 kind = cwh_dst_stride_kind(GET_DOPE_BASE_TY(td)); 01274 01275 01276 /* axis bounds - 1d array of structs, lb,ub,str per struct */ 01277 01278 if (!fld.Is_Null ()) { 01279 01280 off = FLD_ofst(fld) + off; 01281 tf = FLD_type(fld); 01282 rnk = TY_AR_ubnd_val(tf,0); 01283 FLD_HANDLE bnd_fld = TY_fld(Ty_Table[TY_AR_etype(tf)]); 01284 t = cwh_dst_mk_type(FLD_type(bnd_fld)); 01285 sz = FLD_ofst(FLD_next(bnd_fld))- FLD_ofst(bnd_fld); 01286 01287 for (k = 0 ; k <= rnk ; k ++) { 01288 01289 l.ref = cwh_dst_mk_dope_bound(st,off,t,p,comp); 01290 off += sz ; 01291 u.ref = cwh_dst_mk_dope_bound(st,off,t,p,comp); 01292 off += sz ; 01293 01294 i = DST_mk_subrange_type(FALSE,l,FALSE,u); 01295 DST_SET_count(DST_INFO_flag(DST_INFO_IDX_TO_PTR(i))) ; 01296 01297 if (str) { 01298 s = cwh_dst_mk_dope_bound(st,off,t,p,comp); 01299 x = DST_INFO_attributes(DST_INFO_IDX_TO_PTR(i)) ; 01300 DST_SUBRANGE_TYPE_stride_ref(DST_ATTR_IDX_TO_PTR(x,DST_SUBRANGE_TYPE)) = s ; 01301 01302 if (kind == s_TWO_BYTE) 01303 DST_SET_stride_2byte(DST_INFO_flag(DST_INFO_IDX_TO_PTR(i))) ; 01304 else if ((kind == s_BYTE) || (kind == s_CHAR)) 01305 DST_SET_stride_1byte(DST_INFO_flag(DST_INFO_IDX_TO_PTR(i))) ; 01306 } 01307 01308 off += sz ; 01309 01310 DST_append_child(arr,i); 01311 } 01312 } 01313 } 01314 01315 /*=================================================== 01316 * 01317 * cwh_dst_stride_kind 01318 * 01319 * Given the base TY of a dope vector, figure 01320 * out what sort of stride multiplier it has, 01321 * consequently, what DST_stride_<info> to put 01322 * out. The stride is a word, unless integer*1,*2 or 01323 * logical*1,2 or a derived type with only character 01324 * components or subtypes. 01325 * 01326 *=================================================== 01327 */ 01328 static enum str_knd 01329 cwh_dst_stride_kind(TY_IDX ty) 01330 { 01331 enum str_knd rt = s_NONE; 01332 enum str_knd at ; 01333 01334 switch (TY_kind(ty)) { 01335 case KIND_ARRAY: 01336 rt = cwh_dst_stride_kind(TY_AR_etype(ty)); 01337 break; 01338 01339 case KIND_STRUCT: 01340 if (IS_DOPE_TY(ty)) 01341 rt = s_WORD ; 01342 else { 01343 01344 FLD_HANDLE f = TY_fld(Ty_Table[ty]); 01345 while ((!f.Is_Null ()) && ((rt == s_CHAR) || (rt == s_NONE))) { 01346 01347 at = cwh_dst_stride_kind(FLD_type(f)) ; 01348 01349 if (at == s_CHAR) 01350 rt = s_CHAR ; 01351 else 01352 rt = s_WORD; 01353 01354 f = FLD_next(f); 01355 } 01356 } 01357 break; 01358 01359 01360 case KIND_SCALAR: 01361 if (cwh_types_is_character(ty)) 01362 rt = s_CHAR; 01363 else if ((TY_mtype(ty) == MTYPE_I1) || (TY_mtype(ty) == MTYPE_U1)) 01364 rt = s_BYTE ; 01365 else if ((TY_mtype(ty) == MTYPE_I2) || (TY_mtype(ty) == MTYPE_U2)) 01366 rt = s_TWO_BYTE ; 01367 else 01368 rt = s_WORD; 01369 break ; 01370 01371 case KIND_POINTER: 01372 rt = cwh_dst_stride_kind(TY_pointed(ty)); 01373 break ; 01374 01375 default: 01376 DevAssert((0),(" dope type")); 01377 01378 } 01379 01380 return rt ; 01381 } 01382 01383 /*=================================================== 01384 * 01385 * cwh_dst_member 01386 * 01387 * Given an FLD make a member IDX. For fortran we 01388 * assume there are no bitfields or static members. 01389 * 01390 * Result tacked on to parent 01391 * 01392 *=================================================== 01393 */ 01394 01395 static DST_INFO_IDX 01396 cwh_dst_member(FLD_HANDLE fld, DST_INFO_IDX parent) 01397 { 01398 DST_MEMBER *def_attr; 01399 DST_ATTR_IDX def_attr_idx; 01400 DST_INFO *def_info; 01401 DST_INFO_IDX dope_ty; 01402 BOOL dope ; 01403 DST_INFO_IDX i ; 01404 DST_INFO_IDX t ; 01405 TY_IDX ty; 01406 01407 USRCPOS s; 01408 01409 01410 USRCPOS_clear(s); 01411 01412 Making_FLD_DST=TRUE ; 01413 01414 ty = FLD_type(fld); 01415 dope = IS_DOPE_TY(ty); 01416 01417 if (dope) 01418 t = cwh_dst_dope_type(ty, 01419 Top_ST, 01420 FLD_ofst(fld), 01421 parent, 01422 TRUE, 01423 &dope_ty); 01424 else 01425 t = cwh_dst_mk_type(ty); 01426 01427 i = DST_mk_member(s, 01428 FLD_name(fld), 01429 t, 01430 FLD_ofst(fld), 01431 0, 01432 FLD_bofst(fld), 01433 FLD_bsize(fld), 01434 FLD_is_bit_field(fld), 01435 FALSE, 01436 FALSE, 01437 FALSE); 01438 01439 if (dope) { 01440 def_info = DST_INFO_IDX_TO_PTR(i); 01441 def_attr_idx = DST_INFO_attributes(def_info); 01442 def_attr = DST_ATTR_IDX_TO_PTR(def_attr_idx, DST_MEMBER); 01443 01444 DST_MEMBER_dopetype(def_attr) = dope_ty; 01445 DST_SET_f90_pointer(DST_INFO_flag(def_info)); 01446 } 01447 01448 DST_append_child(parent,i); 01449 01450 Making_FLD_DST=FALSE ; 01451 return i; 01452 01453 } 01454 01455 /*=================================================== 01456 * 01457 * cwh_dst_struct_has_DST 01458 * 01459 * Given an STRUCT TY, search the list of 01460 * Struct TYs for a DST. If found, return it. 01461 * 01462 * Dwarf won't handle addressing operations in 01463 * structures, but the bounds of a pointer component 01464 * (dope) are in a structure. A new DST is emitted 01465 * for each variable of a type that includes a pointer 01466 * array component, so the bounds in the array 01467 * subrange DST can get DST location entries. eg: 01468 * 01469 * type t1 01470 * integer, pointer, dimension :: a(:) 01471 * end type 01472 * type (t1) var1, var2 01473 * 01474 * gets a distinct type die for var1 & var2. Hence 01475 * can't enter such TYs here. 01476 * 01477 *=================================================== 01478 */ 01479 static DST_INFO_IDX 01480 cwh_dst_struct_has_DST(TY_IDX ty) 01481 { 01482 INT32 i ; 01483 TY_IDX ts ; 01484 FLD_HANDLE fld ; 01485 BOOL has_ptr_array_dope = FALSE; 01486 01487 if (!IS_DOPE_TY(ty)) { 01488 01489 ts = ty ; 01490 01491 fld = TY_fld(Ty_Table[ts]); 01492 01493 while (!fld.Is_Null () && !has_ptr_array_dope) { 01494 01495 ts = FLD_type(fld) ; 01496 01497 TY& t = Ty_Table[ts]; 01498 01499 if (IS_DOPE_TY(ts)) 01500 if (TY_is_f90_pointer(t)) { 01501 ts = GET_DOPE_BASE_TY(ts); 01502 if (TY_kind(ts) == KIND_ARRAY) 01503 if (TY_kind(TY_AR_etype(Ty_Table[ts])) == KIND_STRUCT) /* allow recursive types */ 01504 if (!Making_FLD_DST) /* as ptr components but */ 01505 has_ptr_array_dope = TRUE; /* not at top level */ 01506 } 01507 01508 fld = FLD_next(fld); 01509 } 01510 } 01511 01512 if (! has_ptr_array_dope) { 01513 01514 /* look for most recent, in case of duplicates for ptrs */ 01515 01516 for(i = Struct_Top ; i >= 0 ; i --) 01517 if (ty == Struct_DSTs[i].ty) 01518 return Struct_DSTs[i].idx; 01519 01520 } 01521 01522 return (DST_INVALID_IDX); 01523 } 01524 01525 /*=================================================== 01526 * 01527 * cwh_dst_struct_set_DST 01528 * 01529 * Associate a STRUCT TY and a DST_INFO_IDX. A slot 01530 * for a visited flag in the TY would be better. 01531 * 01532 * There are 2 reasons for this routine 01533 * a) to economize on DST entries. 01534 * b) to handle recursive types. 01535 * 01536 *=================================================== 01537 */ 01538 static void 01539 cwh_dst_struct_set_DST(TY_IDX ty, DST_INFO_IDX i) 01540 { 01541 Struct_Top ++ ; 01542 if (Struct_Top >= Struct_Current_Size) { 01543 Struct_Current_Size += STRUCT_DST_SIZE_CHANGE; 01544 Struct_DSTs = (TYIDX *) realloc(Struct_DSTs,sizeof(TYIDX)*Struct_Current_Size); 01545 } 01546 01547 Struct_DSTs[Struct_Top].ty = ty; 01548 Struct_DSTs[Struct_Top].idx = i; 01549 } 01550 01551 /*=================================================== 01552 * 01553 * cwh_dst_struct_clear_DSTs 01554 * 01555 * Clean up the list of STRUCT<->DST entries. 01556 * 01557 *=================================================== 01558 */ 01559 static void 01560 cwh_dst_struct_clear_DSTs(void) 01561 { 01562 Struct_Top = -1 ; 01563 } 01564 01565 /*=================================================== 01566 * 01567 * cwh_dst_add_inner 01568 * 01569 * Remember the DST_IDX of an inner procedure 01570 * until the parent comes along. 01571 * 01572 *=================================================== 01573 */ 01574 static void 01575 cwh_dst_inner_add_DST(DST_INFO_IDX i) 01576 { 01577 01578 Inner_Top ++ ; 01579 01580 if (Inner_Top >= Inner_Current_Size) { 01581 Inner_Current_Size += INNER_DST_SIZE_CHANGE; 01582 Inner_DSTs = (DST_INFO_IDX *) realloc(Inner_DSTs,sizeof(DST_INFO_IDX)*Inner_Current_Size); 01583 } 01584 01585 Inner_DSTs[Inner_Top] = i; 01586 } 01587 01588 /*=================================================== 01589 * 01590 * cwh_dst_inner_clear_DSTs 01591 * 01592 * Clean up the array of inner procedure DST's 01593 * 01594 *=================================================== 01595 */ 01596 static void 01597 cwh_dst_inner_clear_DSTs(void) 01598 { 01599 Inner_Top = -1 ; 01600 } 01601 01602 /*=================================================== 01603 * 01604 * cwh_dst_inner_read_DSTs 01605 * 01606 * Given a DST of a parent procedure, tack on all 01607 * its inner procedures. 01608 * 01609 *=================================================== 01610 */ 01611 static void 01612 cwh_dst_inner_read_DSTs(DST_INFO_IDX parent) 01613 { 01614 INT32 i ; 01615 01616 for(i = 0 ; i <= Inner_Top ; i ++) 01617 DST_append_child(parent,Inner_DSTs[i]); 01618 } 01619 01620 /*=================================================== 01621 * 01622 * cwh_dst_subrange 01623 * 01624 * Given an ARB make a subrange type. 01625 * 01626 *=================================================== 01627 */ 01628 static DST_INFO_IDX 01629 cwh_dst_subrange(ARB_HANDLE ar) 01630 { 01631 DST_INFO_IDX i ; 01632 DST_cval_ref lb,ub; 01633 DST_flag const_lb,const_ub ; 01634 BOOL extent = FALSE ; 01635 const_lb = ARB_const_lbnd(ar) ; 01636 const_ub = ARB_const_ubnd(ar) ; 01637 01638 if (const_lb) 01639 lb.cval = ARB_lbnd_val(ar) ; 01640 else { 01641 lb.ref = cwh_dst_mk_variable(&St_Table[ARB_lbnd_var(ar)]); 01642 DST_append_child(current_scope_idx,lb.ref); 01643 } 01644 01645 if (const_ub) 01646 ub.cval = ARB_ubnd_val(ar) ; 01647 else { 01648 ub.ref = cwh_dst_mk_variable(&St_Table[ARB_ubnd_var(ar)]); 01649 DST_append_child(current_scope_idx,ub.ref); 01650 } 01651 01652 i = DST_mk_subrange_type(const_lb, 01653 lb, 01654 const_ub, 01655 ub); 01656 01657 if (extent) 01658 DST_SET_count(DST_INFO_flag(DST_INFO_IDX_TO_PTR(i))) ; 01659 01660 return i; 01661 } 01662 /*=================================================== 01663 * 01664 * cwh_dst_mk_dope_bound 01665 * 01666 * Make a DST dope bound. This is an anonymous variable 01667 * whose type is the type of the FLD and whose address 01668 * is derived from the ST of the dope. If the ST is NULL, 01669 * then the bound is in a dtype component and is an offset. 01670 * But dbx doesn't like this dwarf, so we make a new DST struct 01671 * for each dope vector and and set the bounds as DST locations. 01672 * 01673 * The dwarf location is 01674 * non-based: <ST location> <offset> 01675 * based/formal: <ST location> <deref> <offset> 01676 * component: <offset> 01677 * 01678 * dp - dope vector 01679 * offset - into common or struct of this bound. 01680 * t - idx of bound type 01681 * p - idx of parent scope (common/current scope) 01682 * component - is ptr component of derived type? 01683 * 01684 *=================================================== 01685 */ 01686 static DST_INFO_IDX 01687 cwh_dst_mk_dope_bound(ST *dp, mINT64 offset, DST_INFO_IDX t, DST_INFO_IDX p, BOOL component) 01688 { 01689 DST_INFO_IDX i ; 01690 01691 TY_IDX ty ; 01692 BOOL dr = FALSE; /* deref reqd */ 01693 BOOL ce = FALSE; /* common element (eg:module data) */ 01694 BOOL dapc= FALSE; /* dope array with array valued ptr component */ 01695 char *n = '\0'; 01696 USRCPOS s; 01697 01698 USRCPOS_clear(s); 01699 01700 DevAssert((dp != NULL),(" missing dope ST ")); 01701 01702 BOOL class_based = (ST_base_idx(dp) != ST_st_idx(dp)); 01703 ce = (class_based && 01704 ((ST_sclass(ST_base(dp)) == SCLASS_COMMON) || 01705 (ST_sclass(ST_base(dp)) == SCLASS_DGLOBAL))) ; 01706 01707 dr = (ST_sclass(dp) == SCLASS_FORMAL) || (ST_sclass(dp) == SCLASS_FORMAL_REF); 01708 01709 /* If a pointer component & f90 pointer, then the bounds are */ 01710 /* indirectly accesssed via the address in the ptr's dope. */ 01711 /* If in common, it's an offset into the common */ 01712 01713 dr |= (class_based && !ce) || 01714 ((component && ST_auxst_is_f90_pointer(dp))) ; 01715 01716 /* if a dtype array with an array valued ptr component, then */ 01717 /* can't represent ptr bounds with location (ie: need to index */ 01718 /* into dope vector array) so use a field, as we'd like to do */ 01719 /* for all bounds */ 01720 01721 ty = ST_type(dp); 01722 dapc = TY_kind(ty) == KIND_ARRAY && Making_FLD_DST ; 01723 01724 /* but since dbx falls over immediately with array location of */ 01725 /* DW_AT_member the locations of the array bounds of the 1st */ 01726 /* pointer compenent are generated. */ 01727 01728 dapc = FALSE; 01729 01730 if (!dapc) { 01731 01732 if (ce) { 01733 01734 i = DST_mk_variable_comm(s, 01735 NULL, 01736 t, 01737 (void *) ST_st_idx(ST_base(dp)), 01738 offset); 01739 01740 } else { 01741 01742 i = DST_mk_variable(s, 01743 n, 01744 t, 01745 offset, 01746 (void *) ST_st_idx(dp), 01747 DST_INVALID_IDX, 01748 FALSE, 01749 ST_sclass(dp) == SCLASS_AUTO, 01750 FALSE, 01751 TRUE); 01752 } 01753 01754 if (dr) 01755 DST_SET_base_deref(DST_INFO_flag(DST_INFO_IDX_TO_PTR(i))); 01756 01757 } else { 01758 01759 i = DST_mk_member(s, 01760 n, 01761 t, 01762 offset, 01763 Pointer_Size, /*FIX */ 01764 0,FALSE,FALSE,FALSE,FALSE,FALSE); 01765 01766 } 01767 DST_append_child(p,i); 01768 01769 return i ; 01770 } 01771 01772 /*=================================================== 01773 * 01774 * cwh_dst_has_dope 01775 * 01776 * Does this derived type TY contain any dope information. 01777 * If so TRUE. A dope TY at the top level is ignored 01778 * because it belongs to a variable. 01779 * 01780 * Assumes STRUCTS have been flattened. 01781 * 01782 *=================================================== 01783 */ 01784 static BOOL 01785 cwh_dst_has_dope(TY_IDX ty) 01786 { 01787 while(TY_kind(ty) == KIND_POINTER) 01788 ty = TY_pointed(ty); 01789 01790 if (!IS_DOPE_TY(ty)) { 01791 01792 if (TY_kind(ty) == KIND_STRUCT) { 01793 01794 FLD_HANDLE fld = TY_fld(Ty_Table[ty]); 01795 01796 while (!fld.Is_Null ()) { 01797 if (IS_DOPE_TY(FLD_type(fld))) 01798 if (!GET_DOPE_BOUNDS(FLD_type(fld)).Is_Null ()) 01799 return(TRUE); 01800 01801 fld = FLD_next(fld); 01802 } 01803 } 01804 } 01805 01806 return (FALSE); 01807 } 01808 01809 /*=================================================== 01810 * 01811 * DST_set_assoc_idx 01812 * 01813 * Set up the DST/ST be association. The ST was stuffed 01814 * into the fe_ptr of the DST_ASSOC_INFO when the DST 01815 * was made. Now the ST's have been written, convert the 01816 * ASSOC info into the BE ST indexes. 01817 * 01818 *=================================================== 01819 */ 01820 static INT32 01821 DST_set_assoc_idx(INT32 dummy, 01822 DST_DW_tag tag, 01823 DST_flag flag, 01824 DST_ATTR_IDX iattr, 01825 DST_INFO_IDX inode) 01826 { 01827 DST_INFO *node; 01828 DST_ASSOC_INFO *assoc; 01829 mINT32 level, index; 01830 ST_IDX st; 01831 #if 0 // buggy code--FMZ 01832 if (DST_IS_assoc_fe(flag)) 01833 { 01834 /* Set the ASSOC_INFO_st_level && ASSOC_INFO_st_index fields 01835 * pointed to by the assoc_info field in the 01836 * source_correspondence. We need to dispatch on the tag value 01837 * to determine the form of assoc_info. 01838 */ 01839 switch (tag) 01840 { 01841 case DW_TAG_subprogram: 01842 if (DST_IS_memdef(flag)) 01843 { 01844 assoc = &DST_SUBPROGRAM_memdef_st( 01845 DST_ATTR_IDX_TO_PTR(iattr, DST_SUBPROGRAM)); 01846 } 01847 else if (!DST_IS_declaration(flag)) 01848 { 01849 assoc = &DST_SUBPROGRAM_def_st( 01850 DST_ATTR_IDX_TO_PTR(iattr, DST_SUBPROGRAM)); 01851 } 01852 else 01853 { 01854 DevAssert((FALSE), ("Illegal subprogram DST_ASSOC_INFO")); 01855 } 01856 st = (ST_IDX) pDST_ASSOC_INFO_fe_ptr(assoc); 01857 Get_ST_Id( st, &level, &index ); 01858 pDST_ASSOC_INFO_st_idx(assoc) = st; 01859 break; 01860 01861 case DW_TAG_entry_point: 01862 assoc = &DST_ENTRY_POINT_st( 01863 DST_ATTR_IDX_TO_PTR(iattr, DST_ENTRY_POINT)); 01864 st = (ST_IDX) pDST_ASSOC_INFO_fe_ptr(assoc); 01865 Get_ST_Id( st, &level, &index ); 01866 pDST_ASSOC_INFO_st_idx(assoc) = st; 01867 break; 01868 01869 case DW_TAG_formal_parameter: 01870 assoc = &DST_FORMAL_PARAMETER_st( 01871 DST_ATTR_IDX_TO_PTR(iattr, DST_FORMAL_PARAMETER)); 01872 st = (ST_IDX) pDST_ASSOC_INFO_fe_ptr(assoc); 01873 Get_ST_Id( st, &level, &index ); 01874 pDST_ASSOC_INFO_st_idx(assoc) = st; 01875 break; 01876 01877 case DW_TAG_common_block: 01878 assoc = &DST_COMMON_BLOCK_st( 01879 DST_ATTR_IDX_TO_PTR(iattr, DST_COMMON_BLOCK ) ); 01880 st = (ST_IDX) pDST_ASSOC_INFO_fe_ptr(assoc); 01881 Get_ST_Id( st, &level, &index ); 01882 pDST_ASSOC_INFO_st_idx(assoc) = st; 01883 break; 01884 01885 case DW_TAG_variable: 01886 if (DST_IS_comm(flag)) { 01887 assoc = &DST_VARIABLE_comm_st( 01888 DST_ATTR_IDX_TO_PTR(iattr, DST_VARIABLE)); 01889 } 01890 else if (DST_IS_memdef(flag)) 01891 { 01892 assoc = &DST_VARIABLE_memdef_st( 01893 DST_ATTR_IDX_TO_PTR(iattr, DST_VARIABLE)); 01894 } 01895 else if (!DST_IS_declaration(flag)) 01896 { 01897 assoc = &DST_VARIABLE_def_st( 01898 DST_ATTR_IDX_TO_PTR(iattr, DST_VARIABLE)); 01899 } 01900 else 01901 { 01902 DevAssert((FALSE), ("Illegal DST variable assoc ptr")); 01903 } 01904 01905 01906 st = (ST_IDX) pDST_ASSOC_INFO_fe_ptr(assoc); 01907 01908 Get_ST_Id( st, &level, &index ); 01909 pDST_ASSOC_INFO_st_idx(assoc) = st; 01910 break; 01911 01912 case DW_TAG_label: 01913 assoc = &DST_LABEL_low_pc(DST_ATTR_IDX_TO_PTR(iattr, DST_LABEL)); 01914 DevAssert((0),("NEW_SYMTAB: DW_TAG_label")); 01915 pDST_ASSOC_INFO_st_idx(assoc) = make_ST_IDX(index,level); 01916 break; 01917 01918 case DW_TAG_lexical_block: 01919 assoc = &DST_LEXICAL_BLOCK_low_pc( 01920 DST_ATTR_IDX_TO_PTR(iattr, DST_LEXICAL_BLOCK)); 01921 DevAssert((0),("NEW_SYMTAB: DW_TAG_lexical_block")); 01922 pDST_ASSOC_INFO_st_idx(assoc) = make_ST_IDX(index,level); 01923 assoc = &DST_LEXICAL_BLOCK_high_pc( 01924 DST_ATTR_IDX_TO_PTR(iattr, DST_LEXICAL_BLOCK)); 01925 DevAssert((0),("NEW_SYMTAB: DW_TAG_lexical_block")); 01926 pDST_ASSOC_INFO_st_idx(assoc) = make_ST_IDX(index,level); 01927 break; 01928 01929 case DW_TAG_inlined_subroutine: 01930 assoc = &DST_INLINED_SUBROUTINE_low_pc( 01931 DST_ATTR_IDX_TO_PTR(iattr, DST_INLINED_SUBROUTINE)); 01932 st = (ST_IDX) pDST_ASSOC_INFO_fe_ptr(assoc); 01933 Get_ST_Id( st, &level, &index ); 01934 pDST_ASSOC_INFO_st_idx(assoc) = st; 01935 assoc = &DST_INLINED_SUBROUTINE_high_pc( 01936 DST_ATTR_IDX_TO_PTR(iattr, DST_INLINED_SUBROUTINE)); 01937 st = (ST_IDX) pDST_ASSOC_INFO_fe_ptr(assoc); 01938 Get_ST_Id( st, &level, &index ); 01939 pDST_ASSOC_INFO_st_idx(assoc) = st; 01940 break; 01941 01942 default: 01943 DevAssert((FALSE),("Invalid DST_ASSOC_INFO field access")); 01944 break; 01945 } 01946 node = DST_INFO_IDX_TO_PTR(inode); 01947 DST_SET_assoc_idx(DST_INFO_flag(node)); 01948 DST_RESET_assoc_fe(DST_INFO_flag(node)); 01949 } 01950 #endif 01951 01952 return dummy; 01953 } 01954 01955 01956 /*=================================================== 01957 * 01958 * DST_get_ordinal_num 01959 * 01960 * get the DST number of this file. Looks in the 01961 * list of files, and returns an index if exists, 01962 * otherwise creates an entry. 01963 * 01964 *=================================================== 01965 */ 01966 01967 static mUINT16 01968 DST_get_ordinal_num(char *the_name, 01969 char ***the_list, 01970 mUINT16 *the_next, 01971 mUINT16 *the_size) 01972 { 01973 mUINT16 idx, next = *the_next, size = *the_size; 01974 char **list = *the_list; 01975 01976 /* See if it exists */ 01977 01978 if ((the_name == NULL) || (the_name[0] == '\0')) 01979 idx = 0; 01980 else { 01981 for (idx = 0; (idx < next) && (strcmp(the_name, list[idx]) != 0); idx += 1); 01982 01983 /* does not exist so create it */ 01984 01985 if (idx == next) { 01986 if (next >= size) { 01987 size += DST_NAME_TABLE_SIZE; 01988 *the_size = size; 01989 if (next == 0) 01990 list = (char **)malloc(size*sizeof(char *)); 01991 else 01992 list = (char **)realloc((char *)list,size*sizeof(char *)); 01993 01994 *the_list = list; 01995 } 01996 list[next] = the_name; 01997 *the_next += 1; 01998 } 01999 idx += 1; /* ordinal number is one larger than dir_list idx */ 02000 } 02001 return idx; 02002 } 02003 02004 /*=================================================== 02005 * 02006 * DST_write_files 02007 * 02008 * Write out DST filelist - these are written out 02009 * as filename string, pathname #. The list was 02010 * created with cwh_dst_enter_file. 02011 * 02012 ==================================================== 02013 */ 02014 static DST_FILE_IDX 02015 DST_write_files(void) 02016 { 02017 struct stat fstat; 02018 char *dir_name, *file_name; 02019 UINT64 file_size ; 02020 UINT64 fmod_time ; 02021 DST_FILE_IDX file_idx, first_file_idx = DST_INVALID_INIT; 02022 UINT32 dir_length; 02023 INT32 name_idx; 02024 02025 for (name_idx = 0; name_idx < next_file_idx; name_idx += 1) 02026 { 02027 file_name = file_list[name_idx]; 02028 02029 if (stat(file_name, &fstat) == 0) { 02030 file_size = (UINT64)fstat.st_size; 02031 fmod_time = (UINT64)fstat.st_mtime; 02032 02033 } else { 02034 file_size = 0ll; 02035 fmod_time = 0ll; 02036 } 02037 DST_directory_of(file_name, &dir_name, &dir_length); 02038 file_idx = DST_mk_file_name( 02039 &file_name[dir_length], /* name */ 02040 DST_get_ordinal_num(dir_name, /* path */ 02041 &dir_list, 02042 &next_dir_idx, 02043 &dir_list_size), 02044 file_size, 02045 fmod_time); 02046 if (name_idx == 0) 02047 first_file_idx = file_idx; 02048 } 02049 return first_file_idx; 02050 } 02051 02052 /*=================================================== 02053 * 02054 * DST_directory_of 02055 * 02056 * Copy file_path into dir_name then remove the 02057 * filename by placing a '\0' at the last '/' 02058 * can be used separately. 02059 * 02060 ==================================================== 02061 */ 02062 02063 static void 02064 DST_directory_of(char *file_path, char **dir_name, UINT32 *dir_length) 02065 { 02066 char *dir; 02067 02068 *dir_name = ux_strdup(file_path); 02069 dir= strrchr(*dir_name,'/') ; 02070 02071 *dir = '\0'; 02072 *dir_length = dir - *dir_name + 1 ; 02073 } 02074 02075 /*=================================================== 02076 * 02077 * DST_write_directories 02078 * 02079 * Write out all directories, and return the idx 02080 * of the first. 02081 * 02082 ==================================================== 02083 */ 02084 static DST_DIR_IDX 02085 DST_write_directories(void) 02086 { 02087 mUINT16 name_idx; 02088 DST_DIR_IDX dir_idx, first_idx = DST_INVALID_INIT; 02089 02090 for (name_idx = 0; name_idx < next_dir_idx; name_idx += 1) { 02091 02092 dir_idx = DST_mk_include_dir(dir_list[name_idx]); 02093 if (name_idx == 0) 02094 first_idx = dir_idx; 02095 } 02096 02097 return first_idx; 02098 } 02099 02100 /*=================================================== 02101 * 02102 * cwh_dst_enter_path 02103 * 02104 * Enter a new pathname into the file_list and get 02105 * back its index. 02106 * 02107 ==================================================== 02108 */ 02109 extern mUINT16 02110 cwh_dst_enter_path(char * fname) 02111 { 02112 mUINT16 idx; 02113 mUINT16 old; 02114 char *file_name; 02115 02116 file_name = Make_Absolute_Path(fname); 02117 02118 old = next_file_idx; 02119 idx = DST_get_ordinal_num(file_name, 02120 &file_list, 02121 &next_file_idx, 02122 &file_list_size); 02123 02124 if (next_file_idx == old) 02125 free(file_name); 02126 02127 return idx ; 02128 } 02129 02130 /*=================================================== 02131 * 02132 * cwh_dst_get_command_line_options 02133 * 02134 * Given the set of options passed into the front-end, string 02135 * together the ones of interest for debugging and return 02136 * the resultant string. The options of interest depends on 02137 * the level of debugging. The caller should free the malloced 02138 * string once it is no longer needed. 02139 * 02140 * 02141 ==================================================== 02142 */ 02143 02144 static char * 02145 cwh_dst_get_command_line_options(void) 02146 { 02147 INT32 i, 02148 strlength = 0; 02149 INT32 num_opts = 0; 02150 char **selected_opt; 02151 INT32 *opt_size; 02152 char *rtrn, *cp; 02153 char ch; 02154 BOOL record_option; 02155 02156 if (FE_command_line != NULL) { 02157 /* 02158 * driver passed in a command-line file, whose contents are (currently) 02159 * 02160 * command-line 02161 * current working directory 02162 * 02163 * As it turns out, we need only the first line. We read it in, and use 02164 * it in place of the arguments passed in to the frontend, which are 02165 * generally useless for the purposes of tools that need to 02166 * automatically rebuild these objects.. 02167 * 02168 * If no command line was passed in, we just return the contents of 02169 * argv[] as usual. 02170 */ 02171 02172 struct stat statb; 02173 FILE *cmdfile; 02174 02175 if ((cmdfile = fopen(FE_command_line, "r")) != NULL) { 02176 if (fstat(ux_fileno(cmdfile), &statb) == 0) { 02177 char *endcp; 02178 02179 /* allocate a buffer as big as the file: this is safe and fast */ 02180 rtrn = (char *) malloc(statb.st_size+1); 02181 02182 /* we need only the first line */ 02183 fgets(rtrn, statb.st_size, cmdfile); 02184 02185 /* scan for newline or end of buffer, and stick in a 02186 * terminating NULL */ 02187 for (cp = rtrn, endcp = rtrn+statb.st_size; 02188 *cp != 0 && *cp != '\n' && cp < endcp; 02189 cp++); 02190 *cp = '\0'; 02191 fclose(cmdfile); 02192 return rtrn; 02193 } 02194 /* If we got here, we managed to fopen the file, but not fstat it. 02195 * This is technically an internal error, but what the heck, we 02196 * will just ignore it and fall through to the "default" code.. 02197 */ 02198 fclose(cmdfile); 02199 } 02200 } 02201 /* else fall back to returning argv[] formatted into string */ 02202 02203 selected_opt = (char **)malloc(sizeof(char*) * save_argc); 02204 opt_size = (INT32 *)malloc(sizeof(INT32) * save_argc); 02205 02206 for (i = 1; i < save_argc; i++) 02207 { 02208 if (save_argv[i] != NULL && save_argv[i][0] == '-') 02209 { 02210 ch = save_argv[i][1]; /* Next flag character */ 02211 if (Debug_Level <= 0) 02212 /* No debugging */ 02213 record_option = (ch == 'g' || /* Debugging option */ 02214 ch == 'O'); /* Optimization level */ 02215 else 02216 /* Full debugging */ 02217 record_option = (ch == 'D' || /* Macro symbol definition */ 02218 ch == 'g' || /* Debugging option */ 02219 ch == 'I' || /* Search path for #include files */ 02220 ch == 'O' || /* Optimization level */ 02221 ch == 'U'); /* Macro symbol undefined */ 02222 if (record_option) 02223 { 02224 opt_size[num_opts] = strlen(save_argv[i]) + 1; /* Arg + space/null */ 02225 selected_opt[num_opts] = save_argv[i]; 02226 strlength += opt_size[num_opts]; 02227 num_opts += 1; 02228 } 02229 } 02230 } 02231 02232 if (strlength == 0) 02233 { 02234 rtrn = (char *)calloc(1, 1); /* An empty string */ 02235 } 02236 else 02237 { 02238 rtrn = (char *)malloc(strlength); 02239 cp = rtrn; 02240 02241 /* Append the selected options to the string (rtrn) */ 02242 for (i = 0; i < num_opts; i++) 02243 if (opt_size[i] > 0) 02244 { 02245 cp = strcpy(cp, selected_opt[i]) + opt_size[i]; 02246 cp[-1] = ' '; /* Space character */ 02247 } 02248 cp[-1] = '\0'; /* Terminating null character */ 02249 } 02250 02251 free(selected_opt); 02252 free(opt_size); 02253 return rtrn; 02254 } 02255 02256 static char 02257 Get_ST_Id (ST_IDX st_idx, INT *level, INT *index) 02258 { 02259 if (st_idx) { 02260 02261 *level = ST_IDX_level(st_idx); 02262 *index = ST_IDX_index(st_idx); 02263 } 02264 02265 else { 02266 02267 *level = 0; 02268 *index = 0; 02269 } 02270 02271 return NULL; 02272 } 02273 02274 /*================================================================ 02275 * 02276 * char * cwh_dst_filename_from_filenum(SRCPOS s) 02277 * 02278 * given a file number, return a pointer to the associated file name. 02279 * 02280 *================================================================ 02281 */ 02282 extern char * 02283 cwh_dst_filename_from_filenum(INT idx) 02284 { 02285 Is_True((idx > 0 && idx <= next_file_idx),("Bad file number (%d)\n",idx)); 02286 return file_list[idx-1]; 02287 }