Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
cwh_dst.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 /* ====================================================================
00037  * ====================================================================
00038  *
00039  *
00040  * Revision history:
00041  *  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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines