• Main Page
  • Modules
  • Data Types
  • Files

osprey/crayf90/fe90/module.c

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2006. QLogic Corporation. All Rights Reserved.
00003  */
00004 
00005 /*
00006  * Copyright 2004, 2005, 2006 PathScale, Inc.  All Rights Reserved.
00007  */
00008 
00009 /*
00010 
00011   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00012 
00013   This program is free software; you can redistribute it and/or modify it
00014   under the terms of version 2 of the GNU General Public License as
00015   published by the Free Software Foundation.
00016 
00017   This program is distributed in the hope that it would be useful, but
00018   WITHOUT ANY WARRANTY; without even the implied warranty of
00019   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00020 
00021   Further, this software is distributed without any warranty that it is
00022   free of the rightful claim of any third person regarding infringement 
00023   or the like.  Any license provided herein, whether implied or 
00024   otherwise, applies only to this software file.  Patent licenses, if 
00025   any, provided herein do not apply to combinations of this program with 
00026   other software, or any other product whatsoever.  
00027 
00028   You should have received a copy of the GNU General Public License along
00029   with this program; if not, write the Free Software Foundation, Inc., 59
00030   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00031 
00032   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00033   Mountain View, CA 94043, or:
00034 
00035   http://www.sgi.com
00036 
00037   For further information regarding this notice, see:
00038 
00039   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00040 
00041 */
00042 
00043 
00044 static char USMID[] = "\n@(#)5.0_pl/sources/module.c  5.17  09/30/99 15:47:54\n";
00045 
00046 # include "defines.h"   /* Machine dependent ifdefs */
00047 
00048 # include "host.m"    /* Host machine dependent macros.*/
00049 # include "host.h"    /* Host machine dependent header.*/
00050 # include "target.m"    /* Target machine dependent macros.*/
00051 # include "target.h"    /* Target machine dependent header.*/
00052 
00053 # include "globals.m"
00054 # include "tokens.m"
00055 # include "sytb.m"  
00056 # include "p_globals.m"  
00057 # include "debug.m"
00058 # include "module.m"
00059 
00060 # include "globals.h"
00061 # include "tokens.h"
00062 # include "sytb.h"
00063 # include "p_globals.h"
00064 # include "module.h"
00065 
00066 # include <ar.h>
00067 
00068 # include <sys/types.h>
00069 # include <sys/stat.h>
00070 
00071 # include <dirent.h>
00072 
00073 # include <errno.h>
00074 
00075 # if (defined(_TARGET_OS_IRIX) || defined(_TARGET_OS_LINUX) || defined(_TARGET_OS_DARWIN)) && defined(_MODULE_TO_DOT_o)
00076 # include <fcntl.h>
00077 # include <libelf.h>
00078 # include <sys/elf.h>
00079 
00080   /* These are the originator string and .note type this program removes  */
00081   /* from files.                                                          */
00082 
00083 # define NOTE_ORIG_NAME  "Cray Research, Incorporated\0"
00084 # define NOTE_ORGNAM_LEN 28
00085 # define NOTE_TYPE        1
00086 
00087 # elif defined(_TARGET_OS_SOLARIS) && defined(_MODULE_TO_DOT_o)
00088 # include <fcntl.h>
00089 # include <libelf.h>
00090 # include <sys/elf_SPARC.h>
00091 
00092   /* These are the originator string and .note type this program removes  */
00093   /* from files.                                                          */
00094 
00095 # define NOTE_ORIG_NAME  "Cray Research, Incorporated\0"
00096 # define NOTE_ORGNAM_LEN 28
00097 # define NOTE_TYPE        1
00098 # endif
00099 
00100 # if !defined(AR_HDR_SIZE)
00101 # define  AR_HDR_SIZE sizeof(ar_hdr_type)
00102 # endif
00103 
00104 /******************************************************************************\
00105 |*                                                                            *|
00106 |* Notes if a new field is added to the symbol tables.                        *|
00107 |*                                                                            *|
00108 |*   1) Add it to the appropriate set_mod_link_tbl_for ... routine            *|
00109 |*      This routine sets the KEEP_ME and IDX flags in the mod link table     *|
00110 |*      so that the table entry gets kept during compression.                 *|
00111 |*                                                                            *|
00112 |*   2) Add it to update_idxs_in_attr_entry or compress_tbls for non attr     *|
00113 |*      fields.  These routines do the actual compression and reset the       *|
00114 |*      fields.  compress_tbls calls update_idxs_in_attr_entry.               *|
00115 |*                                                                            *|
00116 |*   3) Add it to update_new_idxs_after_input.  This routine sets the indexes *|
00117 |*      after a module is read in.  When a module is in a file, all the table *|
00118 |*      indexes are 1 based.  When it is read in, each new table is           *|
00119 |*      concatenated to the existing table, so all the indexs need the table  *|
00120 |*      size before reading added to the index.  This is generally the        *|
00121 |*      location to correct for symbol table changes.                         *|
00122 |*                                                                            *|
00123 \******************************************************************************/
00124 
00125 
00126 /******************************************************************************\
00127 |*                                                                            *|
00128 |* Steps for compressing tables.  (Both partial and full compressions.)       *|
00129 |*                                                                            *|
00130 |*   These routines allow for full and partial compressions.  (See #2 to      *|
00131 |*   set indexes for a partial compression.  A full compression is everything *|
00132 |*   in a table.  A partial compression starts at a given index in a table    *|
00133 |*   and goes to the end of a table.  These routines will not do a compression*|
00134 |*   in the middle of a table.                                                *|
00135 |*                                                                            *|
00136 |*   1) Allocate the mod_link_tbl.  This table is allocated so that it is as  *|
00137 |*      big as the largest symbol/ir table.  If between marking the entries   *|
00138 |*      in the mod_link_tbl and the actual compression, any tables grow       *|
00139 |*      always make sure the mod_link_tbl size is still big enough to cover   *|
00140 |*      the new entries.  No matter what table is being compressed, the mod_  *|
00141 |*      link_tbl must be allocated as large as the largest table.             *|
00142 |*                                                                            *|
00143 |*   2) Set the zeroth entries in the mod_link_tbl to one less than the       *|
00144 |*      starting index for compression.  If this is a full compression, then  *|
00145 |*      they should be set to 0.  Anything in a table past this index is      *|
00146 |*      subject to compression.                                               *|
00147 |*                                                                            *|
00148 |*   3) Call set_mod_link_tbl_for_attr  each attr entry that needs to be kept.*|
00149 |*      If this is a partial compression, this only needs to be called for    *|
00150 |*      those attr entries in the part of the attr table to be compressed.    *|
00151 |*      This routine calls set_mod_link_tbl routines for other tables.  If the*|
00152 |*      local name table is to be compressed, these entries will have to be   *|
00153 |*      marked.  (See create_mod_info_tbl for how this is done for a full     *|
00154 |*      compression.)  This routine marks each table entry that needs to be   *|
00155 |*      kept in the mod_link_tbl, with its current index.  That way if the    *|
00156 |*      item being compressed points into a part of the table not being       *|
00157 |*      compressed, it will get the correct index out of the mod_link_tbl.    *|
00158 |*                                                                            *|
00159 |*   4) Call assign_new_idxs.  It will start at the point of compression for  *|
00160 |*      each table.  If the mod_link_tbl is set for that entry, it will be    *|
00161 |*      given a new index.  (The new index for a table starts at the index    *|
00162 |*      where compression starts and is incremented each time a table entry   *|
00163 |*      is kept.)  The new index is put into the mod_link_tbl for the entry.  *|
00164 |*                                                                            *|
00165 |*   5) Call compress_tbls to move the table entries to their new index spots.*|
00166 |*      This is where actual compression takes place.  As the entries are     *|
00167 |*      being moved, all their links are updated with the correct links from  *|
00168 |*      the mod_link_tbl.                                                     *|
00169 |*                                                                            *|
00170 |*   Example:  Compress the attr_tbl starting at index 65.  attr_tbl_idx = 70 *|
00171 |*             Entries  66, 68 and 70 are to be kept.                         *|
00172 |*             1) Allocate mod_link_tbl as large as the largest table.        *|
00173 |*             2) ML_AT_IDX(0) = 64  (65 - one)                               *|
00174 |*                The rest of the tables mod_link_tbl[0] entries are set to   *|
00175 |*                the current table indexes so that no other table compresses.*|
00176 |*             3) Call set_mod_link_tbl_for_attr for attr entries 66, 68 & 70.*|
00177 |*             4) Call assign_new_idxs.       Old Idx        New Idx          *|
00178 |*                                              66             65             *|
00179 |*                                              68             66             *|
00180 |*                                              70             67             *|
00181 |*             5) Call compress_tbls which moves the attr tbl entries.        *|
00182 |*                attr_tbl_idx is set to 67.                                  *|
00183 |*                                                                            *|
00184 |*   NOTE:  compress_tbls and assign_new_idxs will go through all the tables, *|
00185 |*      so in the above example, any references to attrs 66, 68 and 70 will   *|
00186 |*      be reset.  If there are references to attrs 67 or 69, these           *|
00187 |*      references will be set to NULL_IDX.  This is where alot of bugs are   *|
00188 |*      found during module processing.  Full compressions are done when      *|
00189 |*      files are written out for modules or inlining.  Partial compressions  *|
00190 |*      are done when files for module or inlining are read in and also for   *|
00191 |*  interface block compression.                                          *|
00192 |*                                                                            *|
00193 |*                                                                            *|
00194 \******************************************************************************/
00195 
00196 extern  boolean is_directory(char *);
00197 
00198 /*****************************************************************\
00199 |* function prototypes of static functions declared in this file *|
00200 \*****************************************************************/
00201 static  void  allocate_mod_link_tbl (int);
00202 static  void  assign_new_idxs (boolean);
00203 static  void  assign_new_idxs_after_input (int);
00204 static  void  check_ir_for_attrs (int);
00205 static  void  check_il_for_attrs (int);
00206 static  void  compress_tbls (int, boolean);
00207 static  void  compress_type_tbl (int);
00208 # if 0
00209 static  void  create_module_list_from_str_pool (void);
00210 # endif
00211 
00212 # if defined(_TARGET_OS_SOLARIS) && defined(_MODULE_TO_DOT_o)
00213 static  boolean do_elf_notes_section(Elf_Data *, int, int);
00214 static  boolean do_elf_object(Elf *, Elf32_Ehdr *, int, int);
00215 # endif
00216 
00217 # if defined(_DEBUG)
00218 static  void  dump_pdt(FILE *);
00219 static  void  print_mod_tbl(void);
00220 # endif
00221 
00222 static  void  find_files_in_directory(int);
00223 static  void  merge_interfaces (int, int);
00224 static  void  not_visible_semantics (int, int, int);
00225 static  int ntr_file_in_fp_tbl(int, char *, int);
00226 static  FILE   *open_module_file (int, int);
00227 static  void  process_procs_for_inlining (int);
00228 static  boolean read_in_module_tbl (int, int, FILE *, char *);
00229 static  boolean read_module_tbl_header (int, int, FILE *);
00230 static  boolean read_sytb_from_module_file(int, FILE *, char *);
00231 static  boolean rename_only_semantics (int, boolean);
00232 static  boolean resolve_attr(int);
00233 static  void  resolve_all_components(int, int);
00234 static  void  resolve_used_modules (int);
00235 static  void  set_attr_flds_for_output (void);
00236 static  void  set_mod_link_tbl_for_attr (int);
00237 static  void  set_mod_link_tbl_for_bd (int);
00238 static  void  set_mod_link_tbl_for_cn (int);
00239 static  void  set_mod_link_tbl_for_ir (int);
00240 static  void  set_mod_link_tbl_for_il (int);
00241 static  void  set_mod_link_tbl_for_typ (int);
00242 static  boolean srch_ar_file_for_module_tbl (int, int *, int, FILE *);
00243 static  boolean srch_for_module_tbl (int, int *, int, int, FILE *);
00244 static  void  update_idxs_in_attr_entry (int, int);
00245 static  void  update_intrinsic (int);
00246 
00247 # if defined(_TARGET_OS_SOLARIS) && defined(_MODULE_TO_DOT_o)
00248 static  boolean srch_elf_file_for_module_tbl(int, int);
00249 # endif
00250 
00251 
00252 /***********************************\
00253 |* Globals used only in this file  *|
00254 \***********************************/
00255 
00256 static  boolean alternate_entry;
00257 static  boolean count_derived_types;
00258 static  boolean only_update_new_tbl_entries;
00259 static  boolean inline_search;
00260 static  int list_of_modules_in_module;
00261 static  long  mod_file_end_offset;
00262 static  long  num_module_derived_types;
00263 static  int save_const_pool_idx;
00264 static  int save_const_tbl_idx;
00265 static  boolean search_for_duplicate_attrs;
00266 
00267 extern  char  compiler_gen_date[];
00268 
00269 # if (defined(_HOST_OS_IRIX) || defined(_HOST_OS_LINUX) || defined(_HOST_OS_DARWIN))
00270 # pragma inline set_mod_link_tbl_for_typ
00271 # pragma inline set_mod_link_tbl_for_cn
00272 # pragma inline set_mod_link_tbl_for_ir
00273 # pragma inline set_mod_link_tbl_for_bd
00274 # else
00275 # pragma _CRI inline set_mod_link_tbl_for_typ
00276 # pragma _CRI inline set_mod_link_tbl_for_cn
00277 # pragma _CRI inline set_mod_link_tbl_for_ir
00278 # pragma _CRI inline set_mod_link_tbl_for_bd
00279 # endif
00280 
00281 
00282 /******************************************************************************\
00283 |*                        *|
00284 |* Description:                     *|
00285 |*  This routine enters a rename and/or only name for a USE statement     *|
00286 |*  into the rename only table.  All entries are kept in sorted order.    *|
00287 |*  Rename entries actually get two entries in the table.  The original   *|
00288 |*  name entry is the sorted one.  The new name entry is indexed off the  *|
00289 |*  original name entry.  The whole list of renames/only entries is       *|
00290 |*  indexed by ATP_USE_LIST for the module.                               *|
00291 |*                        *|
00292 |* Input parameters:                    *|
00293 |*  module_idx - The attr index for the module specified in the use stmt. *|
00294 |*  ro_idx     - The new name index if this is a rename entry.   (This    *|
00295 |*               routine is called to enter the new name first.  The ro   *|
00296 |*               index is returned.  Then it is called again with the     *|
00297 |*               original name and the ro index.  An entry is made for    *|
00298 |*               the original name and the rename entry is hung off of it.*|
00299 |*  rename_entry -> TRUE if this is the new name.  It doesn't need to be  *|
00300 |*                  sorted or added to the list.                          *|
00301 |*                        *|
00302 |* Output parameters:                   *|
00303 |*  NONE                      *|
00304 |*                        *|
00305 |* Returns:                     *|
00306 |*  ro_idx just entered.                  *|
00307 |*                        *|
00308 \******************************************************************************/
00309 int  make_ro_entry(int    module_idx,
00310                    int    ro_idx,
00311        boolean  rename_entry)
00312 
00313 {
00314    int    cmp_idx;
00315    int    matched;
00316    int    np_idx;
00317    int    prev_idx;
00318 
00319 
00320    TRACE (Func_Entry, "make_ro_entry", NULL);
00321 
00322    if (ro_idx == NULL_IDX) {
00323       ++rename_only_tbl_idx;
00324       CHECK_TBL_ALLOC_SIZE(rename_only_tbl, rename_only_tbl_idx);
00325 
00326       ro_idx = rename_only_tbl_idx;
00327 
00328       CLEAR_TBL_NTRY(rename_only_tbl, ro_idx);
00329 
00330       NTR_NAME_POOL(TOKEN_ID(token).words, TOKEN_LEN(token), np_idx);
00331 
00332       RO_LINE_NUM(ro_idx) = TOKEN_LINE(token);
00333       RO_COLUMN_NUM(ro_idx) = TOKEN_COLUMN(token);
00334       RO_NAME_LEN(ro_idx) = TOKEN_LEN(token);
00335       RO_NAME_IDX(ro_idx) = np_idx;
00336    }
00337 
00338    if (rename_entry) {   /* Do not sort - assume it is a rename entry */
00339       RO_RENAME_NAME(ro_idx)  = TRUE;
00340    }
00341    else {  /* Find a sorted spot for it */
00342       RO_RENAME_NAME(ro_idx)  = FALSE;
00343 
00344       if (ATP_USE_LIST(module_idx) == NULL_IDX) {
00345          ATP_USE_LIST(module_idx) = ro_idx;
00346       }
00347       else {
00348          cmp_idx  = ATP_USE_LIST(module_idx);
00349          prev_idx = NULL_IDX;
00350 
00351          for (;;) {
00352             matched = compare_names(RO_NAME_LONG(cmp_idx),
00353                                     RO_NAME_LEN(cmp_idx),
00354                                     TOKEN_ID(token).words,
00355                                     TOKEN_LEN(token));
00356 
00357             if (matched >= 0) {  
00358 
00359                /* Name in table is same or greater than new name.  Add the */
00360                /* new name before the current index.                       */
00361 
00362                RO_NEXT_IDX(ro_idx) = cmp_idx;
00363 
00364                if (prev_idx == NULL_IDX) {
00365                   ATP_USE_LIST(module_idx) = ro_idx;
00366                }
00367                else {
00368                   RO_NEXT_IDX(prev_idx) = ro_idx;
00369                }
00370                break;
00371             }
00372             else {
00373                prev_idx = cmp_idx;
00374                cmp_idx  = RO_NEXT_IDX(cmp_idx);
00375 
00376                if (cmp_idx == NULL_IDX) {  /* Add at end */
00377                   RO_NEXT_IDX(prev_idx) = ro_idx;
00378                   break;
00379                }
00380             }
00381          }
00382       }
00383    }
00384 
00385    TRACE (Func_Exit, "make_ro_entry", NULL);
00386 
00387    return(ro_idx);
00388 
00389 }   /* make_ro_entry */
00390 
00391 /******************************************************************************\
00392 |*                        *|
00393 |* Description:                     *|
00394 |*  Search the renames table to see if this new name exists already.      *|
00395 |*  This would happen if the same name was used to rename something twice.*|
00396 |*  If it is found, RO_DUPLICATE_RENAME is set for both entries.  Errors  *|
00397 |*  will be issued during use_stmt_semantics.                             *|
00398 |*                        *|
00399 |* Input parameters:                    *|
00400 |*  rename_idx -> The ro index for the name to search for.          *|
00401 |*                        *|
00402 |* Output parameters:                   *|
00403 |*  NONE                      *|
00404 |*                        *|
00405 |* Returns:                     *|
00406 |*  NOTHING                     *|
00407 |*                        *|
00408 \******************************************************************************/
00409 void  check_for_duplicate_renames(int   rename_idx)
00410 
00411 {
00412    int    ro_idx;
00413 
00414 
00415    TRACE (Func_Entry, "check_for_duplicate_renames", NULL);
00416 
00417    for (ro_idx = 1; ro_idx < rename_only_tbl_idx; ro_idx++) {
00418 
00419       if (RO_RENAME_NAME(ro_idx) &&
00420           (compare_names(RO_NAME_LONG(rename_idx),
00421                          RO_NAME_LEN(rename_idx),
00422                          RO_NAME_LONG(ro_idx),
00423                          RO_NAME_LEN(ro_idx)) == 0) && ro_idx != rename_idx) {
00424          RO_DUPLICATE_RENAME(rename_idx)  = TRUE;
00425          RO_DUPLICATE_RENAME(ro_idx)    = TRUE;
00426          break;
00427       }
00428    }
00429 
00430    TRACE (Func_Exit, "check_for_duplicate_renames", NULL);
00431 
00432    return;
00433 
00434 }   /* check_for_duplicate_renames */
00435 
00436 /******************************************************************************\
00437 |*                                                                            *|
00438 |* Description:                                                               *|
00439 |*      Allocate and clear the module link table.  This is used for table     *|
00440 |*      compression.                                                          *|
00441 |*                                                                            *|
00442 |* Input parameters:                                                          *|
00443 |*      size -> Size to allocate.  If this is zero, we will calculate the     *|
00444 |*              size to allocate, by finding the largest table.               *|
00445 |*                                                                            *|
00446 |* Output parameters:                                                         *|
00447 |*      NONE                                            *|
00448 |*                                                                            *|
00449 |* Returns:                                                                   *|
00450 |*      NOTHING                                           *|
00451 |*                                                                            *|
00452 \******************************************************************************/
00453 static  void allocate_mod_link_tbl(int    size)
00454 
00455 {
00456    long   *idx;
00457    long    new_size;
00458 
00459 
00460    TRACE (Func_Entry, "allocate_mod_link_tbl", NULL);
00461 
00462    if (size == 0) {
00463 
00464       /* Find the largest table and allocate the mod link table to this size. */
00465 
00466       new_size = (attr_tbl_idx > bounds_tbl_idx)? attr_tbl_idx : bounds_tbl_idx;
00467       new_size = (new_size > const_tbl_idx) ? new_size : const_tbl_idx;
00468       new_size = (new_size > const_pool_idx)  ? new_size : const_pool_idx;
00469       new_size = (new_size > loc_name_tbl_idx)  ? new_size : loc_name_tbl_idx;
00470       new_size = (new_size > name_pool_idx) ? new_size : name_pool_idx;
00471       new_size = (new_size > sec_name_tbl_idx)  ? new_size : sec_name_tbl_idx;
00472       new_size = (new_size > stor_blk_tbl_idx)  ? new_size : stor_blk_tbl_idx;
00473       new_size = (new_size > type_tbl_idx)  ? new_size : type_tbl_idx;
00474       new_size = (new_size > ir_tbl_idx)  ? new_size : ir_tbl_idx;
00475       new_size = (new_size > ir_list_tbl_idx) ? new_size : ir_list_tbl_idx;
00476       new_size = (new_size > sh_tbl_idx)  ? new_size : sh_tbl_idx;
00477    }
00478    else {
00479       new_size  = size;
00480    }
00481 
00482    new_size++;    /* Do not use entry 0, so increase size by 1 */
00483 
00484    CHECK_TBL_ALLOC_SIZE(mod_link_tbl, new_size);
00485    mod_link_tbl_idx = mod_link_tbl_size - 1;
00486 
00487    idx = ((long *) (&mod_link_tbl[0]));
00488 
00489    memset(idx, 0, mod_link_tbl_size * NUM_ML_WDS * TARGET_BYTES_PER_WORD);
00490 
00491    TRACE (Func_Exit, "allocate_mod_link_tbl", NULL);
00492 
00493    return;
00494 
00495 }  /* allocate_mod_link_tbl */
00496 
00497 /******************************************************************************\
00498 |*                        *|
00499 |* Description:                     *|
00500 |*                        *|
00501 |* Input parameters:                    *|
00502 |*  NONE                      *|
00503 |*                        *|
00504 |* Output parameters:                   *|
00505 |*  NONE                      *|
00506 |*                        *|
00507 |* Returns:                     *|
00508 |*  false if we printed error 855 saying we won't create module file      *|
00509 |*                        *|
00510 \******************************************************************************/
00511 #ifdef KEY /* Bug 3477 */
00512 extern  boolean create_mod_info_file(void)
00513 #else
00514 extern  void  create_mod_info_file(void)
00515 #endif /* KEY Bug 3477 */
00516 {
00517 #ifdef KEY /* Bug 10177 */
00518       int    ga_idx = 0;
00519 #else /* KEY Bug 10177 */
00520       int    ga_idx;
00521 #endif /* KEY Bug 10177 */
00522     FILE    *fp_file_ptr;
00523       int    fp_idx     = NULL_IDX;
00524       int    idx;
00525       int    length;
00526       long    *mod_idx;
00527       int    module_attr_idx;
00528       int    name_idx;
00529     long_type  offset;
00530    static int    preinline_fp_idx = NULL_IDX;
00531     long    *ptr;
00532       int    wd_len;
00533 
00534 # if defined(_MODULE_TO_DOT_M) || defined(_MODULE_TO_DOT_o)
00535       char    *mod_name_ptr;
00536       char    *src_name_ptr;
00537 # endif
00538 
00539 # if defined(_MODULE_TO_DOT_M)
00540     FILE    *fp_file_ptr;
00541    static int    m_file_fp_idx    = NULL_IDX;
00542 # endif
00543 
00544 
00545    TRACE (Func_Entry, "create_mod_info_file", NULL);
00546 
00547    module_attr_idx = SCP_ATTR_IDX(MAIN_SCP_IDX);
00548 
00549    /* The module is a global name, so it was entered into the global name   */
00550    /* table during parse_module_stmt.  The global name table entry contains */
00551    /* an index to the file path entry for this module, so that if we have   */
00552    /* a USE statement referencing the module during this compilation, we    */
00553    /* can find it in the file quickly by using the offset in its file path  */
00554    /* table entry.  We can also use it to detect duplicate modules.         */
00555 
00556    if (!srch_global_name_tbl(AT_OBJ_NAME_PTR(module_attr_idx),
00557                              AT_NAME_LEN(module_attr_idx),
00558                              &name_idx)) {
00559 
00560       if (num_prog_unit_errors == 0) {
00561          PRINTMSG(AT_DEF_LINE(module_attr_idx), 1250, Internal,
00562                   AT_DEF_COLUMN(module_attr_idx),
00563                   AT_OBJ_NAME_PTR(module_attr_idx));
00564       }
00565       else if (ATP_PGM_UNIT(module_attr_idx) == Module ||
00566                !AT_DCL_ERR(module_attr_idx)) {
00567          ntr_global_name_tbl(module_attr_idx, NULL_IDX, name_idx);
00568       }
00569       else {  /* Error in attr for function name. - Bypass */
00570          ga_idx   = NULL_IDX;
00571          name_idx = NULL_IDX;
00572       }
00573    }
00574 
00575    if (name_idx != NULL_IDX) {
00576       ga_idx  = GN_ATTR_IDX(name_idx);
00577 
00578       if (GA_OBJ_CLASS(ga_idx) == Common_Block) {
00579          ga_idx = GAC_PGM_UNIT_IDX(ga_idx);
00580 
00581          if (ga_idx == NULL_IDX && num_prog_unit_errors == 0) {
00582             PRINTMSG(AT_DEF_LINE(module_attr_idx), 1250, Internal,
00583                      AT_DEF_COLUMN(module_attr_idx),
00584                      AT_OBJ_NAME_PTR(module_attr_idx));
00585          }
00586          else {  /* Name must have been in error situation.  Make an entry. */
00587             ntr_global_name_tbl(module_attr_idx, NULL_IDX, name_idx);
00588             ga_idx  = GN_ATTR_IDX(name_idx);
00589          }
00590       }
00591    }
00592 
00593    if (num_prog_unit_errors > 0) {
00594 
00595       if (ga_idx != NULL_IDX && GAP_FP_IDX(ga_idx) != NULL_IDX) {
00596 
00597          /* We already have a module by this name and have created a mod */
00598          /* file for it.  Set SCP_IN_ERR so we don't write out a another */
00599          /* module table.  We would never find this one, because the     */
00600          /* search would always hit the first one.                       */
00601 
00602          SCP_IN_ERR(MAIN_SCP_IDX) = TRUE;
00603       }
00604 
00605       AT_DCL_ERR(module_attr_idx)    = TRUE;
00606 
00607       if (ATP_PGM_UNIT(module_attr_idx) == Module) {
00608          PRINTMSG(AT_DEF_LINE(module_attr_idx), 855, Error,
00609                   AT_DEF_COLUMN(module_attr_idx),
00610                   AT_OBJ_NAME_PTR(module_attr_idx));
00611 
00612 #ifdef KEY /* Bug 3477 */
00613    return FALSE;
00614 #else
00615          if (SCP_IN_ERR(MAIN_SCP_IDX)) {
00616             return;
00617          }
00618 #endif /* KEY Bug 3477 */
00619       }
00620       else {  /* Inline information file */
00621          PRINTMSG(AT_DEF_LINE(module_attr_idx), 1322, Error,
00622                   AT_DEF_COLUMN(module_attr_idx),
00623                   AT_OBJ_NAME_PTR(module_attr_idx));
00624       }
00625    }
00626 
00627    offset = 0;
00628 
00629    /* If we are in a preinline compile, everything goes out to the       */
00630    /* preinline_file including modules.                                  */
00631 
00632    if (dump_flags.preinline) {
00633 
00634       if (preinline_fp_idx != NULL_IDX) {
00635          fp_idx   = preinline_fp_idx;
00636          fp_file_ptr  = fopen(FP_NAME_PTR(fp_idx), "ab");
00637          offset   = ftell(fp_file_ptr);
00638          fclose(fp_file_ptr);
00639       }
00640       else {
00641          TBL_REALLOC_CK(file_path_tbl, 1);
00642          CLEAR_TBL_NTRY(file_path_tbl, file_path_tbl_idx);
00643 
00644          fp_idx       = file_path_tbl_idx;      
00645          preinline_fp_idx   = fp_idx;
00646          FP_NAME_LEN(fp_idx)    = strlen(preinline_file);
00647          FP_NAME_IDX(fp_idx)    = str_pool_idx + 1;
00648          FP_SRCH_THE_FILE(fp_idx) = FALSE;
00649          length       = WORD_LEN(FP_NAME_LEN(fp_idx));
00650 
00651          /* We do not do inlining in a preinline   */
00652          /* compile, so this, can just be File_Fp. */
00653 
00654          FP_CLASS(fp_idx)   = File_Fp;
00655 
00656          TBL_REALLOC_CK(str_pool, length);
00657 
00658          ptr = (long *) (&str_pool[FP_NAME_IDX(fp_idx)].name_long);
00659 
00660          memset(ptr, 0, length * TARGET_BYTES_PER_WORD);
00661 
00662          strcpy(FP_NAME_PTR(fp_idx), preinline_file);
00663 
00664          /* We do not do inlining in a preinline compile so always    */
00665          /* put this on the module path in case it contains a module. */
00666 
00667          FP_NEXT_FILE_IDX(fp_idx) = module_path_idx;
00668       }
00669    }
00670 
00671    /* This creates a name for the module output file.  These are not     */
00672    /* true temp files because they need to last beyond the frontend.     */
00673 
00674    /* There are three naming schemes: _MODULE_TO_DOT_o, _MODULE_TO_DOT_M */
00675    /* and module to .mod (-em). If it is DOT_o, temp files are created   */
00676    /* for each module called .file.module.m.  The file names are passed  */
00677    /* thru the interface, where the backend puts the files where it      */
00678    /* wants.  If the file ends with .m, the backend must clean the file  */
00679    /* up.  If it ends with .mn, the frontend must remove the file.       */
00680    /* If DOT_M, the modules are all put in the same file.M file.  If     */
00681    /* .mod), the modules are each put to a file called modulename.mod.   */
00682 
00683    /* How the commandline option and defines work together:  If -dm is   */
00684    /* specified then either _MODULE_TO_DOT_M or _MODULE_TO_DOT_o         */
00685    /* is the default.                                                    */
00686 
00687    if (on_off_flags.module_to_mod) {
00688 
00689       if (fp_idx == NULL_IDX) {
00690 
00691          /* Create module.mod for the name. */
00692          /* Also, check to see if user specified a dir for the .mod files. */
00693 
00694          if (cmd_line_flags.mod_out_path) {
00695             strcpy(&(mod_file_name[0]), mod_out_path);
00696             strcat(mod_file_name, "/");
00697             strcat(mod_file_name, AT_OBJ_NAME_PTR(module_attr_idx));
00698          }
00699          else {
00700             strcpy(&(mod_file_name[0]), AT_OBJ_NAME_PTR(module_attr_idx));
00701          }
00702          strcat(mod_file_name, ".mod");
00703          TBL_REALLOC_CK(file_path_tbl, 1);
00704          CLEAR_TBL_NTRY(file_path_tbl, file_path_tbl_idx);
00705 
00706          fp_idx       = file_path_tbl_idx;      
00707          FP_NEXT_FILE_IDX(fp_idx) = (ATP_PGM_UNIT(module_attr_idx) != Module) ? 
00708                                      inline_path_idx : module_path_idx;
00709          FP_NAME_LEN(fp_idx)    = strlen(mod_file_name);
00710          FP_NAME_IDX(fp_idx)    = str_pool_idx + 1;
00711          FP_SRCH_THE_FILE(fp_idx) = FALSE;
00712          length       = WORD_LEN(FP_NAME_LEN(fp_idx));
00713          FP_CLASS(fp_idx)   = File_Fp;
00714 
00715          TBL_REALLOC_CK(str_pool, length);
00716 
00717          for (idx = FP_NAME_IDX(fp_idx); idx <= str_pool_idx; idx++) {        
00718             str_pool[idx].name_long = 0;
00719          }
00720 
00721          strcpy(FP_NAME_PTR(fp_idx), mod_file_name);
00722       }
00723    }
00724    else { /* Default to MODULE_TO_DOT_o or MODULE_TO_DOT_M */
00725 
00726 # if defined(_MODULE_TO_DOT_o)
00727 
00728       if (fp_idx == NULL_IDX) {
00729          mod_file_name[0] = '.';
00730          mod_name_ptr = &(mod_file_name[1]);
00731          src_name_ptr = strrchr (src_file, SLASH);
00732          src_name_ptr = (src_name_ptr == NULL) ? src_file : src_name_ptr+1;
00733 
00734          while (*mod_name_ptr++ = *src_name_ptr++);
00735 
00736          /* This returns a pointer to the last */
00737          /* occurence of dot in the file name  */
00738 
00739          src_name_ptr = strrchr (mod_file_name, DOT);
00740 
00741          if (src_name_ptr != NULL && 
00742              (EQUAL_STRS(src_name_ptr, ".f") ||
00743               EQUAL_STRS(src_name_ptr, ".f90"))){
00744              src_name_ptr++;
00745          }
00746          else {                  /* Just append module.m on */
00747              strcpy(src_name_ptr, ".");
00748              src_name_ptr++;
00749          }
00750 
00751          TBL_REALLOC_CK(file_path_tbl, 1);
00752 
00753          strncpy(src_name_ptr, 
00754                  AT_OBJ_NAME_PTR(module_attr_idx), 
00755                  AT_NAME_LEN(module_attr_idx));
00756 
00757          src_name_ptr += AT_NAME_LEN(module_attr_idx);
00758 
00759          /* KAY - Use for running the frontend alone. */
00760 
00761 # if 0
00762          strcpy(src_name_ptr, ".m");      /* Backend will delete this. */
00763 # endif
00764 
00765          strcpy(src_name_ptr, ".mn");     /* Backend will not delete this. */
00766 
00767          TBL_REALLOC_CK(file_path_tbl, 1);
00768          CLEAR_TBL_NTRY(file_path_tbl, file_path_tbl_idx);
00769 
00770          fp_idx       = file_path_tbl_idx;      
00771          FP_NEXT_FILE_IDX(fp_idx) = (ATP_PGM_UNIT(module_attr_idx) != Module) ? 
00772                                      inline_path_idx : module_path_idx;
00773          FP_NAME_LEN(fp_idx)    = strlen(mod_file_name);
00774          FP_NAME_IDX(fp_idx)    = str_pool_idx + 1;
00775          FP_SRCH_THE_FILE(fp_idx) = FALSE;
00776          length       = WORD_LEN(FP_NAME_LEN(fp_idx));
00777          FP_CLASS(fp_idx)   = File_Fp;
00778 
00779          /* This file will be read up and copied by the backend.  It will be  */
00780          /* deleted by the backend (if suffix is .m) or the frontend if       */
00781          /* suffix if the file name suffix is .mn.                            */
00782 
00783          FP_TMP_FILE(fp_idx)  = TRUE;
00784 
00785          TBL_REALLOC_CK(str_pool, length);
00786 
00787          ptr = (long *) (&str_pool[FP_NAME_IDX(fp_idx)].name_long);
00788 
00789          memset(ptr, 0, length * TARGET_BYTES_PER_WORD);
00790 
00791          strcpy(FP_NAME_PTR(fp_idx), mod_file_name);
00792 
00793          if (num_prog_unit_errors == 0 && !dump_flags.no_module_output) {
00794 
00795             /* Send file name through interface to be put into the .o file. */
00796    
00797             FP_OUTPUT_TO_O(fp_idx)  = cmd_line_flags.binary_output;
00798          }
00799       }
00800 
00801 # elif defined(_MODULE_TO_DOT_M)
00802 
00803       if (fp_idx != NULL_IDX) {
00804 
00805          /* intentionally blank */
00806 
00807       }
00808       else if (m_file_fp_idx != NULL_IDX) {
00809          fp_idx   = m_file_fp_idx;
00810          fp_file_ptr  = fopen(FP_NAME_PTR(fp_idx), "ab");
00811          offset   = ftell(fp_file_ptr);
00812          fclose(fp_file_ptr);
00813       }
00814       else {
00815          mod_name_ptr = &(mod_file_name[0]);
00816          src_name_ptr = strrchr (src_file, SLASH);
00817          src_name_ptr = (src_name_ptr == NULL) ? src_file : src_name_ptr+1;
00818 
00819          while (*mod_name_ptr++ = *src_name_ptr++);
00820 
00821          /* This returns a pointer to the last */
00822          /* occurence of dot in the file name  */
00823 
00824          src_name_ptr = strrchr (mod_file_name, DOT);
00825 
00826          if (src_name_ptr != NULL && 
00827              (EQUAL_STRS(src_name_ptr, ".f") ||
00828               EQUAL_STRS(src_name_ptr, ".f90"))){
00829             src_name_ptr++;
00830          }
00831          else {                  /* Just append module.m on */
00832             strcpy(src_name_ptr, ".");
00833             src_name_ptr++;
00834          }
00835 
00836          strcpy(src_name_ptr, "M");
00837 
00838          TBL_REALLOC_CK(file_path_tbl, 1);
00839          CLEAR_TBL_NTRY(file_path_tbl, file_path_tbl_idx);
00840 
00841          fp_idx       = file_path_tbl_idx;      
00842          FP_NEXT_FILE_IDX(fp_idx) = (ATP_PGM_UNIT(module_attr_idx) != Module) ? 
00843                                    inline_path_idx : module_path_idx;
00844          FP_NAME_LEN(fp_idx)    = strlen(mod_file_name);
00845          FP_NAME_IDX(fp_idx)    = str_pool_idx + 1;
00846          FP_SRCH_THE_FILE(fp_idx) = FALSE;
00847          length       = WORD_LEN(FP_NAME_LEN(fp_idx));
00848          FP_CLASS(fp_idx)   = File_Fp;
00849 
00850          TBL_REALLOC_CK(str_pool, length);
00851 
00852          for (idx = FP_NAME_IDX(fp_idx); idx <= str_pool_idx; idx++) {        
00853             str_pool[idx].name_long = 0;
00854          }
00855 
00856          strcpy(FP_NAME_PTR(fp_idx), mod_file_name);
00857 
00858          m_file_fp_idx  = fp_idx;
00859          fp_file_ptr  = fopen(mod_file_name, "wb");
00860          fclose(fp_file_ptr);
00861       }
00862 # endif
00863    }
00864 
00865    /* Keep track of the file index for the first module written out.  This */
00866    /* will get updated with a directory listing all modules in this file.  */
00867 
00868    if (ATP_PGM_UNIT(module_attr_idx) == Module) {
00869 
00870       if (module_path_idx == NULL_IDX) {
00871          module_path_idx  = fp_idx;
00872       }
00873    }
00874    else if (inline_path_idx == NULL_IDX && !dump_flags.preinline) {
00875       inline_path_idx   = fp_idx;
00876    }
00877 
00878    /* Create an entry for the module being written out.  fp_idx  */
00879    /* is the file path table index for the file entry.           */
00880 
00881    TBL_REALLOC_CK(file_path_tbl, 1);
00882    CLEAR_TBL_NTRY(file_path_tbl, file_path_tbl_idx);
00883 
00884    /* Put this module at the top of the list. */
00885 
00886    FP_MODULE_IDX(file_path_tbl_idx) = FP_MODULE_IDX(fp_idx);
00887    FP_MODULE_IDX(fp_idx)    = file_path_tbl_idx;
00888 
00889    FP_NAME_LEN(file_path_tbl_idx) = AT_NAME_LEN(module_attr_idx);
00890    FP_NAME_IDX(file_path_tbl_idx) = str_pool_idx + 1;
00891    FP_OFFSET(file_path_tbl_idx)   = offset;
00892    FP_FILE_IDX(file_path_tbl_idx) = fp_idx;     /* Link to file entry */
00893    FP_CLASS(file_path_tbl_idx)    = Current_Compile_Fp;
00894 
00895    mod_idx        = &(mit_header.wd[0]);
00896 
00897    for (idx=0; idx < sizeof(mit_header_type) / TARGET_BYTES_PER_WORD; idx++) {
00898       *mod_idx = 0;
00899        mod_idx++;
00900    }
00901    if (ga_idx != NULL_IDX) {
00902       GAP_FP_IDX(ga_idx)  = file_path_tbl_idx;
00903    }
00904    name_idx   = AT_NAME_IDX(module_attr_idx);
00905    wd_len   = WORD_LEN(AT_NAME_LEN(module_attr_idx));
00906    mod_idx    = MD_NAME_LONG;
00907    MD_NAME_LEN    = AT_NAME_LEN(module_attr_idx);
00908 
00909    TBL_REALLOC_CK(str_pool, wd_len);
00910 
00911    for (idx = FP_NAME_IDX(file_path_tbl_idx); idx <= str_pool_idx; idx++) {
00912       *mod_idx      = name_pool[name_idx].name_long;
00913       str_pool[idx].name_long = name_pool[name_idx].name_long;
00914       name_idx++;
00915       mod_idx++;
00916    }
00917 
00918    SCP_FILE_PATH_IDX(curr_scp_idx)  = fp_idx;
00919 
00920    TRACE (Func_Exit, "create_mod_info_file", NULL);
00921 
00922 #ifdef KEY /* Bug 3477 */
00923    return TRUE;
00924 #else
00925    return;
00926 #endif /* KEY Bug 3477 */
00927 
00928 }  /* create_mod_info_file */
00929 
00930 /******************************************************************************\
00931 |*                        *|
00932 |* Description:                     *|
00933 |*  Create the module link table, which is used to output the module      *|
00934 |*  information table.                                                    *|
00935 |*                        *|
00936 |* Input parameters:                    *|
00937 |*  NONE                      *|
00938 |*                        *|
00939 |* Output parameters:                   *|
00940 |*  NONE                      *|
00941 |*                        *|
00942 |* Returns:                     *|
00943 |*  NOTHING                     *|
00944 |*                        *|
00945 \******************************************************************************/
00946 void  create_mod_info_tbl(void)
00947 
00948 {
00949    int    attr_idx;
00950    int    name_idx;
00951 
00952 
00953    TRACE (Func_Entry, "create_mod_info_tbl", NULL);
00954 
00955    if (dump_flags.preinline && num_prog_unit_errors > 0) {
00956 
00957       /* Do not write out any tables.  Just the mod header. */
00958 
00959       return;
00960    }
00961 
00962    allocate_mod_link_tbl(0);  /* Determine size from longest table. */
00963 
00964    /* global flag used to tell set_mod_link_tbl_for_attr */
00965    /* that it should check all attrs for duplicates.     */
00966 
00967    search_for_duplicate_attrs = FALSE;  /* Do not search */
00968 
00969    for (name_idx = SCP_LN_FW_IDX(MAIN_SCP_IDX) + 1;
00970         name_idx < SCP_LN_LW_IDX(MAIN_SCP_IDX); 
00971         name_idx++) {
00972 
00973       attr_idx = LN_ATTR_IDX(name_idx);
00974 
00975       if (attr_idx == SCP_ATTR_IDX(MAIN_SCP_IDX)) {
00976          KEEP_ATTR(attr_idx);
00977          ML_LN_KEEP_ME(name_idx)  =  TRUE;
00978          ML_LN_IDX(name_idx)    =  name_idx;
00979       }
00980       else if (AT_PRIVATE(attr_idx) || AT_OBJ_CLASS(attr_idx) == Label) {
00981 
00982          /* If object is PRIVATE, the name must not go into the name table.  */
00983          /* Also, Labels do not go out for the module itself.                */
00984 
00985       }
00986       else if (IS_STMT_ENTITY(attr_idx)) {
00987 
00988          /* This item is only used as the loop control variable in    */
00989          /* an implied-do.  It is only in the scope of the implied-do */
00990          /* and should not be written out to the module file.         */
00991       }
00992       else if (AT_OBJ_CLASS(attr_idx) == Data_Obj &&
00993                ATD_SYMBOLIC_CONSTANT(attr_idx) &&
00994                ATD_CLASS(attr_idx) == Constant) {
00995 
00996          /* N$PES was specified as a constant.  Do not output the actual     */
00997          /* constant to the module.  It should have been replaced all over.  */
00998       }
00999       else if (AT_USE_ASSOCIATED(attr_idx) &&
01000                AT_OBJ_CLASS(attr_idx) == Pgm_Unit &&
01001                ATP_PGM_UNIT(attr_idx) == Module) {
01002 
01003          /* This module has been use associated into this scope.  We do not */
01004          /* want the name in the local name table, although we do want to   */
01005          /* have the attribute entry for the module go out.                 */
01006       }
01007       else if (!ML_AT_KEEP_ME(attr_idx)) {
01008 
01009          /* if ML_AT_KEEP_ME is set, this attr entry has been processed. */
01010          /* It got processed because it was indexed to by another attr.  */
01011          /* (For example:  A derived type.)  Check to see if we need to  */
01012          /* keep the local name or not in the next else clause.          */
01013 
01014          if (AT_OBJ_CLASS(attr_idx) == Pgm_Unit &&
01015              ATP_PROC(attr_idx) == Module_Proc &&
01016              !AT_USE_ASSOCIATED(attr_idx)) {
01017 
01018             /* This is a module procedure declared during this       */
01019             /* compilation.  We need to resolve out any duplicate    */
01020             /* attrs that were used to describe the interface for    */
01021             /* the module procedure.  An example of a duplicate is   */
01022             /* if the same module is USEd in the module and the      */
01023             /* module procedure.  If a type from the module is used  */
01024             /* to describe the module procedure interface, then      */
01025             /* there will be duplicate attrs for the derived type.   */
01026             /* This mechanism resolves them to the same attr.        */
01027 
01028             search_for_duplicate_attrs  = TRUE;
01029          }
01030 
01031          KEEP_ATTR(attr_idx);
01032          ML_LN_KEEP_ME(name_idx)  = TRUE;
01033          ML_LN_IDX(name_idx)    = name_idx;
01034          search_for_duplicate_attrs = FALSE;
01035       }
01036       else {
01037          ML_LN_KEEP_ME(name_idx)  = TRUE;
01038          ML_LN_IDX(name_idx)    = name_idx;
01039 
01040          /* This name gets included because of a link with another attr. */
01041          /* Can be a derived type, function result, CRI pointee, ect...  */
01042          /* Its attr_idx has already been marked as being needed.        */
01043       }
01044    }
01045 
01046    TRACE (Func_Exit, "create_mod_info_tbl", NULL);
01047 
01048    return;
01049 
01050 }   /* create_mod_info_tbl */
01051 
01052 /******************************************************************************\
01053 |*                        *|
01054 |* Description:                     *|
01055 |*  Clear these fields in the attr entry, before it is written out to the *|
01056 |*  module file.                                                          *|
01057 |*                        *|
01058 |* Input parameters:                    *|
01059 |*  NONE                      *|
01060 |*                        *|
01061 |* Output parameters:                   *|
01062 |*  NONE                      *|
01063 |*                        *|
01064 |* Returns:                     *|
01065 |*  NOTHING                     *|
01066 |*                        *|
01067 \******************************************************************************/
01068 static void  set_attr_flds_for_output()
01069 
01070 {
01071    int    attr_idx;
01072 
01073 
01074    TRACE (Func_Entry, "set_attr_flds_for_output", NULL);
01075 
01076    for (attr_idx = 1; attr_idx <= attr_tbl_idx; attr_idx++) {
01077 
01078       if (AT_ORIG_NAME_IDX(attr_idx) == NULL_IDX) {
01079          AT_ORIG_NAME_IDX(attr_idx) = AT_NAME_IDX(attr_idx);
01080          AT_ORIG_NAME_LEN(attr_idx) = AT_NAME_LEN(attr_idx);
01081       }
01082 
01083       switch (AT_OBJ_CLASS(attr_idx)) {
01084       case Data_Obj:
01085 
01086          if (ATD_CLASS(attr_idx) == Compiler_Tmp) {
01087             ATD_TMP_GEN_ZERO(attr_idx)    = FALSE;
01088          }
01089 
01090          if (ATD_CLASS(attr_idx) == Dummy_Argument && ATD_SF_DARG(attr_idx)) {
01091             ATD_SF_ARG_IDX(attr_idx)  = NULL_IDX;
01092             ATD_SF_LINK(attr_idx) = NULL_IDX;
01093          }
01094          break;
01095 
01096       case Pgm_Unit:
01097          ATP_SCP_IDX(attr_idx)      = NULL_IDX;
01098 
01099          if (ATP_PGM_UNIT(attr_idx) == Module) {
01100             ATP_MODULE_STR_IDX(attr_idx)  = NULL_IDX;
01101          }
01102          else if (ATP_PROC(attr_idx) == Intrin_Proc) {
01103             ATP_INTERFACE_IDX(attr_idx)   = NULL_IDX;
01104          }
01105          break;
01106 
01107       case Derived_Type:
01108          AT_DEFINED(attr_idx)     = FALSE;
01109          ATT_CIF_DT_ID(attr_idx)    = 0;
01110          ATT_SCP_IDX(attr_idx)      = NULL_IDX;
01111          break;
01112 
01113       case Label:  /* Do not clear AT_DEFINED here. */
01114          break;
01115 
01116       case Interface:
01117          ATI_HAS_NON_MOD_PROC(attr_idx)   = FALSE;
01118          break;
01119 
01120       case Stmt_Func:
01121       case Namelist_Grp:
01122          break;
01123 
01124       }  /* End switch */
01125    }  /* End for */
01126 
01127 
01128    TRACE (Func_Exit, "set_attr_flds_for_output", NULL);
01129 
01130    return;
01131 
01132 }   /* set_attr_flds_for_output */
01133 
01134 /******************************************************************************\
01135 |*                        *|
01136 |* Description:                     *|
01137 |*  All these attr entries must be included in the entries that will be   *|
01138 |*  compressed.  Mark this attr and everything it links to, as being      *|
01139 |*  saved during the compression.                                         *|
01140 |*                        *|
01141 |* Input parameters:                    *|
01142 |*  attr_idx   -> Index of attribute to process.                          *|
01143 |*                        *|
01144 |* Output parameters:                   *|
01145 |*  NONE                      *|
01146 |*                        *|
01147 |* Returns:                     *|
01148 |*  NOTHING                     *|
01149 |*                        *|
01150 \******************************************************************************/
01151 static  void  set_mod_link_tbl_for_attr(int attr_idx)
01152 
01153 {
01154    int    bd_idx;
01155    int    il_idx;
01156    int    save_duplicate_attr_flag;
01157    int    sb_idx;
01158    int    sh_idx;
01159    int    sn_idx;
01160 
01161 
01162    TRACE (Func_Entry, "set_mod_link_tbl_for_attr", NULL);
01163 
01164    if (ML_AT_KEEP_ME(attr_idx)) {
01165 
01166       /* All the links for this attr have been set, plus */
01167       /* resolve_attr has been called, if need be.       */
01168 
01169       return;
01170    }
01171 
01172    if ((ML_AT_SEARCH_ME(attr_idx) ||
01173        search_for_duplicate_attrs) && !ML_AT_SEARCHED(attr_idx)) {
01174 
01175       if (AT_MODULE_IDX(attr_idx) != NULL_IDX) {
01176          AT_REFERENCED(AT_MODULE_IDX(attr_idx)) = Referenced;
01177       }
01178 
01179       if (resolve_attr(attr_idx)) {
01180 
01181          /* If resolve_attr returns TRUE, this object is in this scope  */
01182          /* already.  Do not set any links for this attr.  We will use  */
01183          /* the attr that is already in this scope.  Mark the attr      */
01184          /* resolved to, so that it gets kept.                          */
01185        
01186          KEEP_ATTR(ML_AT_IDX(attr_idx));
01187          return;
01188       }
01189    }
01190 
01191    if (ML_AT_IDX(attr_idx) != NULL_IDX && ML_AT_IDX(attr_idx) != attr_idx) {
01192 
01193       /* This attr is being replaced by the attr in ML_AT_IDX.  */
01194       /* Keep the attr in ML_AT_IDX.                            */
01195 
01196       KEEP_ATTR(ML_AT_IDX(attr_idx));
01197       return;
01198    }
01199 
01200    ML_AT_KEEP_ME(attr_idx)    = TRUE;
01201    ML_AT_IDX(attr_idx)      = attr_idx;
01202    ML_NP_KEEP_ME(AT_NAME_IDX(attr_idx)) = TRUE;
01203    ML_NP_IDX(AT_NAME_IDX(attr_idx)) = AT_NAME_IDX(attr_idx);
01204    ML_NP_LEN(AT_NAME_IDX(attr_idx)) = AT_NAME_LEN(attr_idx);
01205 
01206    if (AT_ORIG_NAME_IDX(attr_idx) != NULL_IDX) {
01207       ML_NP_KEEP_ME(AT_ORIG_NAME_IDX(attr_idx)) = TRUE;
01208       ML_NP_IDX(AT_ORIG_NAME_IDX(attr_idx)) = AT_ORIG_NAME_IDX(attr_idx);
01209       ML_NP_LEN(AT_ORIG_NAME_IDX(attr_idx)) = AT_ORIG_NAME_LEN(attr_idx);
01210    }
01211 
01212    if (AT_ATTR_LINK(attr_idx) != NULL_IDX && !AT_IGNORE_ATTR_LINK(attr_idx)) {
01213       KEEP_ATTR(AT_ATTR_LINK(attr_idx));
01214    }
01215 
01216    if (AT_MODULE_IDX(attr_idx) != NULL_IDX) {
01217       KEEP_ATTR(AT_MODULE_IDX(attr_idx));
01218    }
01219 
01220    switch (AT_OBJ_CLASS(attr_idx)) {
01221    case Data_Obj:
01222 
01223 # if defined(_F_MINUS_MINUS)
01224       bd_idx  = ATD_PE_ARRAY_IDX(attr_idx);
01225 
01226       if (bd_idx != NULL_IDX && !ML_BD_KEEP_ME(bd_idx)) {
01227          set_mod_link_tbl_for_bd(bd_idx);
01228       }
01229 # endif
01230 
01231       bd_idx  = ATD_RESHAPE_ARRAY_IDX(attr_idx);
01232 
01233       if (bd_idx != NULL_IDX && !ML_BD_KEEP_ME(bd_idx)) {
01234          set_mod_link_tbl_for_bd(bd_idx);
01235       }
01236 
01237       bd_idx  = ATD_ARRAY_IDX(attr_idx);
01238       sb_idx  = ATD_STOR_BLK_IDX(attr_idx);
01239 
01240       if (bd_idx != NULL_IDX && !ML_BD_KEEP_ME(bd_idx)) {
01241          set_mod_link_tbl_for_bd(bd_idx);
01242       }
01243 
01244       bd_idx  = ATD_DISTRIBUTION_IDX(attr_idx);
01245 
01246       if (bd_idx != NULL_IDX && !ML_BD_KEEP_ME(bd_idx)) {
01247          set_mod_link_tbl_for_bd(bd_idx);
01248       }
01249 
01250       if (sb_idx != NULL_IDX) {
01251          ML_SB_KEEP_ME(sb_idx)      = TRUE;
01252          ML_SB_IDX(sb_idx)      = sb_idx;
01253          ML_NP_KEEP_ME(SB_NAME_IDX(sb_idx)) = TRUE;
01254          ML_NP_IDX(SB_NAME_IDX(sb_idx))   = SB_NAME_IDX(sb_idx);
01255          ML_NP_LEN(SB_NAME_IDX(sb_idx))   = SB_NAME_LEN(sb_idx);
01256 #ifdef KEY /* Bug 14150 */
01257    int sb_ext_name_idx = SB_EXT_NAME_IDX(sb_idx);
01258    if (sb_ext_name_idx) {
01259      ML_NP_KEEP_ME(sb_ext_name_idx) = TRUE;
01260      ML_NP_IDX(sb_ext_name_idx) = sb_ext_name_idx;
01261      ML_NP_LEN(sb_ext_name_idx) = SB_EXT_NAME_LEN(sb_idx);
01262    }
01263 #endif /* KEY Bug 14150 */
01264 
01265          if (SB_FIRST_ATTR_IDX(sb_idx) != NULL_IDX) {
01266             KEEP_ATTR(SB_FIRST_ATTR_IDX(sb_idx));
01267          }
01268 
01269          switch (SB_LEN_FLD(sb_idx)) {
01270          case AT_Tbl_Idx:
01271             KEEP_ATTR(SB_LEN_IDX(sb_idx));
01272             break;
01273 
01274          case CN_Tbl_Idx:
01275             KEEP_CN(SB_LEN_IDX(sb_idx));
01276             break;
01277 
01278          case IR_Tbl_Idx:
01279             KEEP_IR(SB_LEN_IDX(sb_idx));
01280             break;
01281 
01282          case IL_Tbl_Idx:
01283             set_mod_link_tbl_for_il(SB_LEN_IDX(sb_idx));
01284             break;
01285          }
01286 
01287          if (SB_MODULE_IDX(sb_idx) != NULL_IDX) {
01288             KEEP_ATTR(SB_MODULE_IDX(sb_idx));
01289          }
01290       }
01291 
01292       switch (ATD_CLASS(attr_idx)) {
01293       case CRI__Pointee:
01294          set_mod_link_tbl_for_typ(ATD_TYPE_IDX(attr_idx));
01295          KEEP_ATTR(ATD_PTR_IDX(attr_idx));
01296          break;
01297 
01298       case Dummy_Argument:
01299 
01300          if (!ATD_INTRIN_DARG(attr_idx)) {
01301             set_mod_link_tbl_for_typ(ATD_TYPE_IDX(attr_idx));
01302          }
01303          break;
01304 
01305       case Constant:
01306          set_mod_link_tbl_for_typ(ATD_TYPE_IDX(attr_idx));
01307 
01308          if (ATD_FLD(attr_idx) == CN_Tbl_Idx) {
01309             KEEP_CN(ATD_CONST_IDX(attr_idx));
01310          }
01311          else {
01312 
01313             /* If we are resolving attrs, we do not search for this tmp   */
01314             /* attr because its name is the same as the constant.  These  */
01315             /* two are a pair so we do not need to do a seperate search.  */
01316 
01317             ML_AT_SEARCHED(ATD_CONST_IDX(attr_idx)) = TRUE;
01318             KEEP_ATTR(ATD_CONST_IDX(attr_idx));
01319          }
01320          break;
01321 
01322       case Compiler_Tmp:
01323 
01324          if (ATD_NEXT_MEMBER_IDX(attr_idx) != NULL_IDX) {
01325             KEEP_ATTR(ATD_NEXT_MEMBER_IDX(attr_idx));
01326          }
01327 
01328          if (ATD_DEFINING_ATTR_IDX(attr_idx) != NULL_IDX) {
01329             KEEP_ATTR(ATD_DEFINING_ATTR_IDX(attr_idx));
01330          }
01331 
01332          if (ATD_AUTOMATIC(attr_idx)) {
01333             KEEP_ATTR(ATD_AUTO_BASE_IDX(attr_idx));
01334          }
01335          else if (ATD_OFFSET_ASSIGNED(attr_idx)) {
01336 
01337             switch (ATD_OFFSET_FLD(attr_idx)) {
01338             case AT_Tbl_Idx:
01339                KEEP_ATTR(ATD_OFFSET_IDX(attr_idx));
01340                break;
01341             case CN_Tbl_Idx:
01342                KEEP_CN(ATD_OFFSET_IDX(attr_idx));
01343                break;
01344             case IR_Tbl_Idx:
01345                KEEP_IR(ATD_OFFSET_IDX(attr_idx));
01346                break;
01347             case IL_Tbl_Idx:
01348                set_mod_link_tbl_for_il(ATD_OFFSET_IDX(attr_idx));
01349                break;
01350             }
01351          }
01352 
01353          set_mod_link_tbl_for_typ(ATD_TYPE_IDX(attr_idx));
01354 
01355          switch (ATD_FLD(attr_idx)) {
01356          case CN_Tbl_Idx:
01357             KEEP_CN(ATD_TMP_IDX(attr_idx));
01358             break;
01359 
01360          case AT_Tbl_Idx:
01361             KEEP_ATTR(ATD_TMP_IDX(attr_idx));
01362             break;
01363 
01364          case IL_Tbl_Idx:
01365             set_mod_link_tbl_for_il(ATD_TMP_IDX(attr_idx));
01366             break;
01367 
01368          case IR_Tbl_Idx:
01369             KEEP_IR(ATD_TMP_IDX(attr_idx));
01370             break;
01371          }
01372          break;
01373 
01374       case Function_Result:
01375 
01376          if (ATD_OFFSET_ASSIGNED(attr_idx)) {
01377 
01378             switch (ATD_OFFSET_FLD(attr_idx)) {
01379             case AT_Tbl_Idx:
01380                KEEP_ATTR(ATD_OFFSET_IDX(attr_idx));
01381                break;
01382             case CN_Tbl_Idx:
01383                KEEP_CN(ATD_OFFSET_IDX(attr_idx));
01384                break;
01385             case IR_Tbl_Idx:
01386                KEEP_IR(ATD_OFFSET_IDX(attr_idx));
01387                break;
01388             case IL_Tbl_Idx:
01389                set_mod_link_tbl_for_il(ATD_OFFSET_IDX(attr_idx));
01390                break;
01391             }
01392          }
01393          set_mod_link_tbl_for_typ(ATD_TYPE_IDX(attr_idx));
01394          break;
01395         
01396 
01397       case Struct_Component:
01398 
01399          switch (ATD_OFFSET_FLD(attr_idx)) {
01400          case AT_Tbl_Idx:
01401             KEEP_ATTR(ATD_CPNT_OFFSET_IDX(attr_idx));
01402             break;
01403          case CN_Tbl_Idx:
01404             KEEP_CN(ATD_CPNT_OFFSET_IDX(attr_idx));
01405             break;
01406          case IR_Tbl_Idx:
01407             KEEP_IR(ATD_CPNT_OFFSET_IDX(attr_idx));
01408             break;
01409          case IL_Tbl_Idx:
01410             set_mod_link_tbl_for_il(ATD_CPNT_OFFSET_IDX(attr_idx));
01411             break;
01412          }
01413 
01414          if (ATD_CPNT_INIT_IDX(attr_idx) != NULL_IDX) {
01415 
01416             switch (ATD_FLD(attr_idx)) {
01417             case AT_Tbl_Idx:
01418                KEEP_ATTR(ATD_CPNT_INIT_IDX(attr_idx));
01419                break;
01420             case CN_Tbl_Idx:
01421                KEEP_CN(ATD_CPNT_INIT_IDX(attr_idx));
01422                break;
01423             case IR_Tbl_Idx:
01424                KEEP_IR(ATD_CPNT_INIT_IDX(attr_idx));
01425                break;
01426             case IL_Tbl_Idx:
01427                set_mod_link_tbl_for_il(ATD_CPNT_INIT_IDX(attr_idx));
01428                break;
01429             }
01430          }
01431 
01432          set_mod_link_tbl_for_typ(ATD_TYPE_IDX(attr_idx));
01433          KEEP_ATTR(ATD_DERIVED_TYPE_IDX(attr_idx));
01434          break;
01435 
01436       case Variable:
01437 
01438          if (ATD_DATA_INIT(attr_idx)) {
01439 
01440             if (ATD_FLD(attr_idx) == NO_Tbl_Idx) {
01441                /* Intentionally blank */
01442             }
01443             else if (ATD_FLD(attr_idx) == AT_Tbl_Idx) {
01444 
01445                /* If we are resolving attrs, we do not search for this tmp   */
01446                /* attr because its name is the same as the variable.  These  */
01447                /* two are a pair so we do not need to do a seperate search.  */
01448 
01449                ML_AT_SEARCHED(ATD_VARIABLE_TMP_IDX(attr_idx)) = TRUE;
01450                KEEP_ATTR(ATD_VARIABLE_TMP_IDX(attr_idx));
01451             }
01452             else if (ATD_FLD(attr_idx) == IL_Tbl_Idx) {
01453 
01454                /* See previous note. */
01455 
01456                il_idx = ATD_VARIABLE_TMP_IDX(attr_idx);
01457 
01458                while (il_idx != NULL_IDX) {
01459    
01460                   if (IL_FLD(il_idx) == AT_Tbl_Idx) {
01461                      ML_AT_SEARCHED(IL_IDX(il_idx)) = TRUE;
01462                   }
01463                   il_idx = IL_NEXT_LIST_IDX(il_idx);
01464                }
01465 
01466                set_mod_link_tbl_for_il(ATD_VARIABLE_TMP_IDX(attr_idx));
01467             }
01468          }
01469          else if (ATD_FLD(attr_idx) == AT_Tbl_Idx) {
01470             KEEP_ATTR(ATD_VARIABLE_TMP_IDX(attr_idx));
01471          }
01472 
01473          if (ATD_NEXT_MEMBER_IDX(attr_idx) != NULL_IDX) {
01474             KEEP_ATTR(ATD_NEXT_MEMBER_IDX(attr_idx));
01475          }
01476 
01477          if (ATD_ASSIGN_TMP_IDX(attr_idx) != NULL_IDX) {
01478             KEEP_ATTR(ATD_ASSIGN_TMP_IDX(attr_idx));
01479          }
01480 
01481          if (ATD_AUTOMATIC(attr_idx)) {
01482             KEEP_ATTR(ATD_AUTO_BASE_IDX(attr_idx));
01483          }
01484          else if (ATD_OFFSET_ASSIGNED(attr_idx)) {
01485 
01486             switch (ATD_OFFSET_FLD(attr_idx)) {
01487             case AT_Tbl_Idx:
01488                KEEP_ATTR(ATD_OFFSET_IDX(attr_idx));
01489                break;
01490             case CN_Tbl_Idx:
01491                KEEP_CN(ATD_OFFSET_IDX(attr_idx));
01492                break;
01493             case IR_Tbl_Idx:
01494                KEEP_IR(ATD_OFFSET_IDX(attr_idx));
01495                break;
01496             case IL_Tbl_Idx:
01497                set_mod_link_tbl_for_il(ATD_OFFSET_IDX(attr_idx));
01498                break;
01499             }
01500          }
01501 
01502          /* Intentional fall through */
01503 
01504       default:
01505 
01506          set_mod_link_tbl_for_typ(ATD_TYPE_IDX(attr_idx));
01507          break;
01508       }
01509       break;
01510 
01511 
01512    case Pgm_Unit:
01513 
01514       ML_NP_KEEP_ME(ATP_EXT_NAME_IDX(attr_idx)) = TRUE;
01515       ML_NP_IDX(ATP_EXT_NAME_IDX(attr_idx)) = ATP_EXT_NAME_IDX(attr_idx);
01516       ML_NP_LEN(ATP_EXT_NAME_IDX(attr_idx)) = ATP_EXT_NAME_LEN(attr_idx);
01517 
01518       if (ATP_PGM_UNIT(attr_idx) == Module) {
01519 
01520          if (ATP_MOD_PATH_LEN(attr_idx) > 0) {
01521             ML_NP_KEEP_ME(ATP_MOD_PATH_IDX(attr_idx)) = TRUE;
01522             ML_NP_IDX(ATP_MOD_PATH_IDX(attr_idx)) = ATP_MOD_PATH_IDX(attr_idx);
01523             ML_NP_LEN(ATP_MOD_PATH_IDX(attr_idx)) = ATP_MOD_PATH_LEN(attr_idx);
01524          }
01525       }
01526       else {
01527 
01528          if (ATP_RSLT_IDX(attr_idx) != NULL_IDX) {
01529             KEEP_ATTR(ATP_RSLT_IDX(attr_idx));
01530          }
01531 
01532          if (ATP_NUM_DARGS(attr_idx) > 0) {
01533 
01534             for (sn_idx = ATP_FIRST_IDX(attr_idx); 
01535                  sn_idx < (ATP_FIRST_IDX(attr_idx) + ATP_NUM_DARGS(attr_idx));
01536                  sn_idx++) {
01537 
01538                ML_SN_KEEP_ME(sn_idx)  = TRUE;
01539                ML_SN_IDX(sn_idx)  = sn_idx;
01540 
01541                KEEP_ATTR(SN_ATTR_IDX(sn_idx));
01542             }
01543          }
01544 
01545          /* This flag works for all 3 uses of this routine.             */
01546 
01547          /* 1) It is called when a use statement is processed.          */
01548          /*    ATP_MAY_INLINE will be set for all procedures            */
01549          /*    coming from the module that carry IR/SH with them.       */
01550          /* 2) During interface processing, if there are any use        */
01551          /*    associated procedures, they will have the mod            */
01552          /*    inlinable flag set correctly.  If they are not, they     */
01553          /*    will not have the mod inlinable flag set.                */
01554          /* 3) During processing, to send module info out, only those   */
01555          /*    procedures that have the mod inlinable flag set, go out. */
01556 
01557          if (ATP_MAY_INLINE(attr_idx)) {
01558 
01559             /* This is the body of the module/internal procedure.  We   */
01560             /* do not want to search for duplicate attrs here.  If we   */
01561             /* do, we get things confused because of host association.  */
01562 
01563             save_duplicate_attr_flag  = search_for_duplicate_attrs;
01564             search_for_duplicate_attrs  = FALSE;
01565             sh_idx      = ATP_FIRST_SH_IDX(attr_idx);
01566 
01567             while (sh_idx != NULL_IDX) {
01568                ML_SH_KEEP_ME(sh_idx)  = TRUE;
01569                ML_SH_IDX(sh_idx)  = sh_idx;
01570 
01571                if (SH_IR_IDX(sh_idx) != NULL_IDX) {
01572                   KEEP_IR(SH_IR_IDX(sh_idx));
01573                }
01574                sh_idx     = SH_NEXT_IDX(sh_idx);
01575             }
01576 
01577             if (ATP_PROC(attr_idx) != Dummy_Proc &&
01578                 ATP_PROC(attr_idx) != Intrin_Proc) {
01579 
01580                if (ATP_PARENT_IDX(attr_idx) != NULL_IDX) {
01581                   KEEP_ATTR(ATP_PARENT_IDX(attr_idx));
01582                }
01583             }
01584             search_for_duplicate_attrs  = save_duplicate_attr_flag;
01585          }
01586          else if (ATP_PROC(attr_idx) != Intrin_Proc) {
01587             ATP_FIRST_SH_IDX(attr_idx)  = NULL_IDX;
01588          }
01589       }
01590       break;
01591 
01592    case Label:
01593 
01594       if (ATL_CLASS(attr_idx) == Lbl_Format) {
01595          KEEP_ATTR(ATL_PP_FORMAT_TMP(attr_idx));
01596          KEEP_ATTR(ATL_FORMAT_TMP(attr_idx));
01597       }
01598       else if (ATL_DIRECTIVE_LIST(attr_idx) != NULL_IDX) {
01599          set_mod_link_tbl_for_il(ATL_DIRECTIVE_LIST(attr_idx));
01600       }
01601 
01602       if (ATL_NEXT_ASG_LBL_IDX(attr_idx) != NULL_IDX) {
01603          KEEP_ATTR(ATL_NEXT_ASG_LBL_IDX(attr_idx));
01604       }
01605       break;
01606 
01607    case Interface:
01608       set_mod_link_tbl_for_typ(ATD_TYPE_IDX(attr_idx));
01609 
01610       /* During resolve_attrs we do not search for interface names.  */
01611       /* We cannot gurantee they are the same because of merging.    */
01612 
01613       if (ATI_PROC_IDX(attr_idx) != NULL_IDX) {
01614 
01615          /* If we are resolving attrs, we do not search for this proc */
01616          /* attr because it has the same name as the interface name.  */
01617 
01618          ML_AT_SEARCHED(ATI_PROC_IDX(attr_idx)) = TRUE;
01619       }
01620 
01621       sn_idx = ATI_FIRST_SPECIFIC_IDX(attr_idx);
01622 
01623       while (sn_idx != NULL_IDX) {
01624          ML_SN_KEEP_ME(sn_idx)  = TRUE;
01625          ML_SN_IDX(sn_idx)  = sn_idx;
01626          KEEP_ATTR(SN_ATTR_IDX(sn_idx));
01627          sn_idx     = SN_SIBLING_LINK(sn_idx);
01628       }
01629       break;
01630 
01631    case Derived_Type:
01632 
01633       switch (ATT_STRUCT_BIT_LEN_FLD(attr_idx)) {
01634       case AT_Tbl_Idx:
01635          KEEP_ATTR(ATT_STRUCT_BIT_LEN_IDX(attr_idx));
01636          break;
01637 
01638       case CN_Tbl_Idx:
01639          KEEP_CN(ATT_STRUCT_BIT_LEN_IDX(attr_idx));
01640          break;
01641 
01642       case IR_Tbl_Idx:
01643          KEEP_IR(ATT_STRUCT_BIT_LEN_IDX(attr_idx));
01644          break;
01645 
01646       case IL_Tbl_Idx:
01647          set_mod_link_tbl_for_il(ATT_STRUCT_BIT_LEN_IDX(attr_idx));
01648          break;
01649       }
01650 
01651       sn_idx      = ATT_FIRST_CPNT_IDX(attr_idx);
01652 
01653       while (sn_idx != NULL_IDX) {
01654          ML_SN_KEEP_ME(sn_idx)  = TRUE;
01655          ML_SN_IDX(sn_idx)  = sn_idx;
01656 
01657          /* We do not resolve components, because the name are not unique. */
01658 
01659          ML_AT_SEARCHED(SN_ATTR_IDX(sn_idx)) = TRUE;
01660          KEEP_ATTR(SN_ATTR_IDX(sn_idx));
01661          sn_idx = SN_SIBLING_LINK(sn_idx);
01662       }
01663       break;
01664 
01665    case Namelist_Grp:
01666       sn_idx = ATN_FIRST_NAMELIST_IDX(attr_idx);
01667 
01668       while (sn_idx != NULL_IDX) {
01669          ML_SN_KEEP_ME(sn_idx)  = TRUE;
01670          ML_SN_IDX(sn_idx)  = sn_idx;
01671          KEEP_ATTR (SN_ATTR_IDX(sn_idx));
01672          sn_idx     = SN_SIBLING_LINK(sn_idx);
01673       }
01674 
01675       if (ATN_NAMELIST_DESC(attr_idx) != NULL_IDX) {
01676          KEEP_ATTR(ATN_NAMELIST_DESC(attr_idx));
01677       }
01678       break;
01679 
01680 
01681    case Stmt_Func:
01682       set_mod_link_tbl_for_typ(ATD_TYPE_IDX(attr_idx));
01683 
01684       if (ATP_NUM_DARGS(attr_idx) > 0) {
01685 
01686          for (sn_idx = ATP_FIRST_IDX(attr_idx); 
01687               sn_idx < (ATP_FIRST_IDX(attr_idx) +ATP_NUM_DARGS(attr_idx));
01688               sn_idx++) {
01689 
01690             ML_SN_KEEP_ME(sn_idx) = TRUE;
01691             ML_SN_IDX(sn_idx)   = sn_idx;
01692             KEEP_ATTR(SN_ATTR_IDX(sn_idx));
01693          }
01694       }
01695 
01696       switch (ATS_SF_FLD(attr_idx)) {
01697       case CN_Tbl_Idx:
01698          KEEP_CN(ATS_SF_IDX(attr_idx));
01699          break;
01700 
01701       case AT_Tbl_Idx:
01702          KEEP_ATTR(ATS_SF_IDX(attr_idx));
01703          break;
01704 
01705       case IL_Tbl_Idx:
01706          set_mod_link_tbl_for_il(ATS_SF_IDX(attr_idx));
01707          break;
01708 
01709       case IR_Tbl_Idx:
01710          KEEP_IR(ATS_SF_IDX(attr_idx));
01711          break;
01712       }
01713       break;
01714 
01715    }  /* End switch */
01716 
01717    TRACE (Func_Exit, "set_mod_link_tbl_for_attr ", NULL);
01718 
01719    return;
01720 
01721 }   /* set_mod_link_tbl_for_attr  */
01722 
01723 /******************************************************************************\
01724 |*                        *|
01725 |* Description:                     *|
01726 |*  Set fields in the module link table for BD.                           *|
01727 |*                        *|
01728 |* Input parameters:                    *|
01729 |*  bd_idx      => Index to set link fields for.                          *|
01730 |*                        *|
01731 |* Output parameters:                   *|
01732 |*  NONE                      *|
01733 |*                        *|
01734 |* Returns:                     *|
01735 |*  NOTHING                     *|
01736 |*                        *|
01737 \******************************************************************************/
01738 static  void  set_mod_link_tbl_for_bd(int bd_idx)
01739 
01740 {
01741    int    dim;
01742 
01743 
01744    TRACE (Func_Entry, "set_mod_link_tbl_for_bd ", NULL);
01745 
01746    ML_BD_KEEP_ME(bd_idx)  = TRUE;
01747    ML_BD_IDX(bd_idx)    = bd_idx;
01748 
01749    if (BD_DIST_NTRY(bd_idx)) {
01750 
01751       for (dim = 1; dim <= BD_RANK(bd_idx); dim++) {
01752 
01753          if (BD_CYCLIC_FLD(bd_idx, dim) == CN_Tbl_Idx) {
01754             KEEP_CN(BD_CYCLIC_IDX(bd_idx, dim));
01755          }
01756          else if (BD_CYCLIC_FLD(bd_idx, dim) == AT_Tbl_Idx) {
01757             KEEP_ATTR(BD_CYCLIC_IDX(bd_idx, dim));
01758          }
01759 
01760          if (BD_ONTO_FLD(bd_idx, dim) == CN_Tbl_Idx) {
01761             KEEP_CN(BD_ONTO_IDX(bd_idx, dim));
01762          }
01763          else if (BD_ONTO_FLD(bd_idx, dim) == AT_Tbl_Idx) {
01764             KEEP_ATTR(BD_ONTO_IDX(bd_idx, dim));
01765          }
01766       }
01767    }
01768    else if (BD_ARRAY_CLASS(bd_idx) != Deferred_Shape) {
01769 
01770       if (BD_LEN_FLD(bd_idx) == CN_Tbl_Idx) {
01771          KEEP_CN(BD_LEN_IDX(bd_idx));
01772       }
01773       else if (BD_LEN_FLD(bd_idx) == AT_Tbl_Idx) {
01774          KEEP_ATTR(BD_LEN_IDX(bd_idx));
01775       }
01776 
01777       for (dim = 1; dim <= BD_RANK(bd_idx); dim++) {
01778 
01779          if (BD_LB_FLD(bd_idx, dim) == CN_Tbl_Idx) {
01780             KEEP_CN(BD_LB_IDX(bd_idx, dim));
01781          }
01782          else if (BD_LB_FLD(bd_idx, dim) == AT_Tbl_Idx) {
01783             KEEP_ATTR(BD_LB_IDX(bd_idx, dim));
01784          }
01785 
01786          if (BD_UB_FLD(bd_idx, dim) == CN_Tbl_Idx) {
01787             KEEP_CN(BD_UB_IDX(bd_idx, dim));
01788          }
01789          else if (BD_UB_FLD(bd_idx, dim) == AT_Tbl_Idx) {
01790             KEEP_ATTR(BD_UB_IDX(bd_idx, dim));
01791          }
01792 
01793          if (BD_XT_FLD(bd_idx, dim) == CN_Tbl_Idx) {
01794             KEEP_CN(BD_XT_IDX(bd_idx, dim));
01795          }
01796          else if (BD_XT_FLD(bd_idx, dim) == AT_Tbl_Idx) {
01797             KEEP_ATTR(BD_XT_IDX(bd_idx, dim));
01798          }
01799 
01800          if (BD_SM_FLD(bd_idx, dim) == CN_Tbl_Idx) {
01801             KEEP_CN(BD_SM_IDX(bd_idx, dim));
01802          }
01803          else if (BD_SM_FLD(bd_idx, dim) == AT_Tbl_Idx) {
01804             KEEP_ATTR(BD_SM_IDX(bd_idx, dim));
01805          }
01806       }
01807    }
01808 
01809    TRACE (Func_Exit, "set_mod_link_tbl_for_bd ", NULL);
01810 
01811    return;
01812 
01813 }   /* set_mod_link_tbl_for_bd  */
01814 
01815 /******************************************************************************\
01816 |*                        *|
01817 |* Description:                     *|
01818 |*  Set fields in the module link table for IR.                           *|
01819 |*                        *|
01820 |* Input parameters:                    *|
01821 |*  ir_idx      => Index to set link fields for.                          *|
01822 |*                        *|
01823 |* Output parameters:                   *|
01824 |*  NONE                      *|
01825 |*                        *|
01826 |* Returns:                     *|
01827 |*  NOTHING                     *|
01828 |*                        *|
01829 \******************************************************************************/
01830 static  void  set_mod_link_tbl_for_ir(int ir_idx)
01831 
01832 {
01833 
01834    TRACE (Func_Entry, "set_mod_link_tbl_for_ir", NULL);
01835 
01836    if (ML_IR_KEEP_ME(ir_idx)) {
01837       return;
01838    }
01839 
01840    ML_IR_KEEP_ME(ir_idx)  = TRUE;
01841    ML_IR_IDX(ir_idx)    = ir_idx;
01842 
01843    set_mod_link_tbl_for_typ(IR_TYPE_IDX(ir_idx));
01844 
01845    switch (IR_FLD_L(ir_idx)) {
01846    case CN_Tbl_Idx:
01847       KEEP_CN(IR_IDX_L(ir_idx));
01848       break;
01849 
01850    case AT_Tbl_Idx:
01851       KEEP_ATTR(IR_IDX_L(ir_idx));
01852       break;
01853 
01854    case IR_Tbl_Idx:
01855       KEEP_IR(IR_IDX_L(ir_idx));
01856       break;
01857 
01858    case IL_Tbl_Idx:
01859       set_mod_link_tbl_for_il(IR_IDX_L(ir_idx));
01860       break;
01861 
01862    case NO_Tbl_Idx:
01863    case SH_Tbl_Idx:
01864       break;
01865    }
01866 
01867    switch (IR_FLD_R(ir_idx)) {
01868    case CN_Tbl_Idx:
01869       KEEP_CN(IR_IDX_R(ir_idx));
01870       break;
01871 
01872    case AT_Tbl_Idx:
01873       KEEP_ATTR(IR_IDX_R(ir_idx));
01874       break;
01875 
01876    case IR_Tbl_Idx:
01877       KEEP_IR(IR_IDX_R(ir_idx));
01878       break;
01879 
01880    case IL_Tbl_Idx:
01881       set_mod_link_tbl_for_il(IR_IDX_R(ir_idx));
01882       break;
01883 
01884    case NO_Tbl_Idx:
01885    case SH_Tbl_Idx:
01886       break;
01887    }
01888    
01889    TRACE (Func_Exit, "set_mod_link_tbl_for_ir", NULL);
01890 
01891    return;
01892 
01893 }   /* set_mod_link_tbl_for_ir */
01894 
01895 /******************************************************************************\
01896 |*                        *|
01897 |* Description:                     *|
01898 |*  Set fields in the module link table for IL.                           *|
01899 |*                        *|
01900 |* Input parameters:                    *|
01901 |*  list_idx    => Index to set link fields for.                          *|
01902 |*                        *|
01903 |* Output parameters:                   *|
01904 |*  NONE                      *|
01905 |*                        *|
01906 |* Returns:                     *|
01907 |*  NOTHING                     *|
01908 |*                        *|
01909 \******************************************************************************/
01910 static  void  set_mod_link_tbl_for_il(int list_idx)
01911 
01912 {
01913 
01914    TRACE (Func_Entry, "set_mod_link_tbl_for_il", NULL);
01915 
01916    if (ML_IL_KEEP_ME(list_idx)) {
01917       return;
01918    }
01919 
01920    while (list_idx != NULL_IDX) {
01921       ML_IL_KEEP_ME(list_idx) = TRUE;
01922       ML_IL_IDX(list_idx) = list_idx;
01923 
01924       switch (IL_FLD(list_idx)) {
01925          case CN_Tbl_Idx:
01926             KEEP_CN(IL_IDX(list_idx));
01927             break;
01928 
01929          case AT_Tbl_Idx:
01930             KEEP_ATTR(IL_IDX(list_idx));
01931             break;
01932 
01933          case IR_Tbl_Idx:
01934             KEEP_IR(IL_IDX(list_idx));
01935             break;
01936 
01937          case IL_Tbl_Idx:
01938             set_mod_link_tbl_for_il(IL_IDX(list_idx));
01939             break;
01940 
01941          case NO_Tbl_Idx:
01942          case SH_Tbl_Idx:
01943             break;
01944       }
01945       list_idx = IL_NEXT_LIST_IDX(list_idx);
01946    }
01947    
01948    TRACE (Func_Exit, "set_mod_link_tbl_for_il", NULL);
01949 
01950    return;
01951 
01952 }   /* set_mod_link_tbl_for_il */
01953 
01954 /******************************************************************************\
01955 |*                        *|
01956 |* Description:                     *|
01957 |*  Set fields in the module link table for a constant table entry.       *|
01958 |*                        *|
01959 |* Input parameters:                    *|
01960 |*  cn_idx => Index of constant table entry to have links set.            *|
01961 |*                        *|
01962 |* Output parameters:                   *|
01963 |*  NONE                      *|
01964 |*                        *|
01965 |* Returns:                     *|
01966 |*  NOTHING                     *|
01967 |*                        *|
01968 \******************************************************************************/
01969 static  void  set_mod_link_tbl_for_cn(int cn_idx)
01970 
01971 {
01972    size_offset_type len;
01973    long     length;
01974    int      type_idx;
01975 
01976 
01977    TRACE (Func_Entry, "set_mod_link_tbl_for_cn", NULL);
01978 
01979    /* KAY - TEMPORARY - REPLACE WITH INTERNAL ERROR               */
01980    /*       If cn_idx is NULL, it should be an internal situation */
01981 
01982    if (cn_idx == NULL_IDX) {
01983       PRINTMSG(stmt_start_line, 626, Internal, stmt_start_col,
01984                "non zero cn_idx",
01985                "set_mod_link_tbl_for_cn");
01986    }
01987 
01988    if (!ML_CN_KEEP_ME(cn_idx)) {
01989       ML_CN_KEEP_ME(cn_idx) = TRUE;
01990       ML_CN_IDX(cn_idx)   = cn_idx;
01991       type_idx      = CN_TYPE_IDX(cn_idx);
01992 
01993       set_mod_link_tbl_for_typ(type_idx);
01994 
01995       switch (TYP_TYPE(type_idx)) {
01996       case Typeless:
01997          length = (long) (CN_EXTRA_ZERO_WORD(cn_idx) ?
01998                               STORAGE_WORD_SIZE(TYP_BIT_LEN(type_idx)) + 1 :
01999                               STORAGE_WORD_SIZE(TYP_BIT_LEN(type_idx)));
02000          break;
02001 
02002       case Character:
02003          len.idx  = TYP_IDX(type_idx);
02004          len.fld  = CN_Tbl_Idx;
02005 
02006          BYTES_TO_WORDS(len, TARGET_BITS_PER_WORD);
02007 
02008          if (len.fld == CN_Tbl_Idx) {
02009             length = (long) CN_INT_TO_C(len.idx);  /* KAYKAY */
02010          }
02011          else {
02012             length = (long) F_INT_TO_C(len.constant, TYP_LINEAR(len.type_idx));
02013          }
02014          length = CN_EXTRA_ZERO_WORD(cn_idx) ? length + 1: length;
02015          break;
02016 
02017 # if defined(_TARGET_OS_MAX)
02018       case Complex:
02019          if (TYP_LINEAR(type_idx) == Complex_4) {
02020 
02021             /* Complex_4 constants are stored in two words on t3e */
02022 
02023             length = 2;
02024          }
02025          else {
02026             length = TARGET_BITS_TO_WORDS(
02027                   storage_bit_size_tbl[TYP_LINEAR(CN_TYPE_IDX(cn_idx))]);
02028          }
02029          break;
02030 # endif
02031 
02032       default:
02033          length = TARGET_BITS_TO_WORDS(
02034                   storage_bit_size_tbl[TYP_LINEAR(CN_TYPE_IDX(cn_idx))]);
02035          break;
02036       }
02037 
02038       ML_CP_LEN(CN_POOL_IDX(cn_idx))    = length;
02039       ML_CP_KEEP_ME(CN_POOL_IDX(cn_idx))  = TRUE;
02040       ML_CP_IDX(CN_POOL_IDX(cn_idx))    = CN_POOL_IDX(cn_idx);
02041 
02042 # if defined(_HOST32) 
02043 
02044       if (DALIGN_TEST_CONDITION(type_idx)) {
02045           ML_CP_DALIGN_ME(CN_POOL_IDX(cn_idx))  = TRUE;
02046       }
02047 
02048 # endif
02049    }
02050 
02051    TRACE (Func_Exit, "set_mod_link_tbl_for_cn", NULL);
02052 
02053    return;
02054 
02055 }   /* set_mod_link_tbl_for_cn */
02056 
02057 /******************************************************************************\
02058 |*                        *|
02059 |* Description:                     *|
02060 |*  Set fields in the module link table for TYP.                          *|
02061 |*                        *|
02062 |* Input parameters:                    *|
02063 |*  typ_idx     => Index to set link fields for.                          *|
02064 |*                        *|
02065 |* Output parameters:                   *|
02066 |*  NONE                      *|
02067 |*                        *|
02068 |* Returns:                     *|
02069 |*  NOTHING                     *|
02070 |*                        *|
02071 \******************************************************************************/
02072 static  void  set_mod_link_tbl_for_typ(int  typ_idx)
02073 
02074 {
02075    int    attr_idx;
02076 
02077 
02078    TRACE (Func_Entry, "set_mod_link_tbl_for_typ", NULL);
02079 
02080    if (typ_idx != NULL_IDX && !ML_TYP_KEEP_ME(typ_idx)) {
02081       ML_TYP_KEEP_ME(typ_idx) = TRUE;
02082       ML_TYP_IDX(typ_idx) = typ_idx;
02083 
02084       if (TYP_TYPE(typ_idx) == Character) {
02085 
02086          if (TYP_FLD(typ_idx) == CN_Tbl_Idx) {
02087             KEEP_CN(TYP_IDX(typ_idx));
02088          }
02089          else if (TYP_FLD(typ_idx) == AT_Tbl_Idx) {
02090             KEEP_ATTR(TYP_IDX(typ_idx));
02091          }
02092       }
02093       else if (TYP_TYPE(typ_idx) == Structure) {
02094          attr_idx = TYP_IDX(typ_idx);
02095    
02096          while (AT_ATTR_LINK(attr_idx) != NULL_IDX) {
02097             attr_idx = AT_ATTR_LINK(attr_idx);
02098          }
02099    
02100          TYP_IDX(typ_idx) = attr_idx;
02101 
02102          KEEP_ATTR(attr_idx);
02103       }
02104    }
02105 
02106    TRACE (Func_Exit, "set_mod_link_tbl_for_typ", NULL);
02107 
02108    return;
02109 
02110 }  /* set_mod_link_tbl_for_typ */
02111 
02112 /******************************************************************************\
02113 |*                        *|
02114 |* Description:                     *|
02115 |*  Go through the module link table, assigning new indexes to all        *|
02116 |*      entries that must be left in the compressed tables.                   *|
02117 |*  The zeroth entry of the mod link table contains the index to start    *|
02118 |*      for each of the tables.  This is the mod link index to start with     *|
02119 |*  and the tbl index to start assigning with.            *|
02120 |*                        *|
02121 |* Input parameters:                    *|
02122 |*  NONE                      *|
02123 |*                        *|
02124 |* Output parameters:                   *|
02125 |*  NONE                      *|
02126 |*                        *|
02127 |* Returns:                     *|
02128 |*  NOTHING                     *|
02129 |*                        *|
02130 \******************************************************************************/
02131 static void  assign_new_idxs(boolean  resolving_duplicates)
02132 
02133 {
02134    int    at_new_tbl_idx  = ML_AT_IDX(0) + 1;
02135    int    bd_new_tbl_idx  = ML_BD_IDX(0) + 1;
02136    int    cn_new_tbl_idx  = ML_CN_IDX(0) + 1;
02137    int    cp_new_tbl_idx  = ML_CP_IDX(0) + 1;
02138    int    end_idx;
02139    int    idx;
02140    int    il_new_tbl_idx  = ML_IL_IDX(0) + 1;
02141    int    ir_new_tbl_idx  = ML_IR_IDX(0) + 1;
02142    int    ln_new_tbl_idx  = ML_LN_IDX(0) + 1;
02143    int    mod_idx;
02144    int    new_idx;
02145    int    np_new_tbl_idx  = ML_NP_IDX(0) + 1;
02146    int    sb_new_tbl_idx  = ML_SB_IDX(0) + 1;
02147    int    sh_new_tbl_idx  = ML_SH_IDX(0) + 1;
02148    int    sn_new_tbl_idx  = ML_SN_IDX(0) + 1;
02149    int    typ_new_tbl_idx = ML_TYP_IDX(0)+ 1;
02150 
02151 
02152    /* All the ML_xx_IDX(0) are the last used indexes for the tables */
02153 
02154 
02155    TRACE (Func_Entry, "assign_new_idxs", NULL);
02156 
02157    if (save_const_tbl_idx != NULL_IDX) {
02158 
02159       /* We are processing an incoming module.  We have left room */
02160       /* for a copy of the full constant table and constant pool. */
02161 
02162       end_idx   = const_tbl_idx;
02163       const_tbl_idx = save_const_tbl_idx;
02164       const_pool_idx  = save_const_pool_idx;
02165 
02166   Pragma("_CRI ivdep")        
02167 
02168       for (mod_idx = 1; mod_idx < cn_new_tbl_idx; mod_idx++) {
02169          ML_CN_IDX(mod_idx) = mod_idx;
02170       }
02171 
02172   Pragma("_CRI ivdep")        
02173 
02174       for (mod_idx = 1; mod_idx < cp_new_tbl_idx; mod_idx++) {
02175          ML_CP_IDX(mod_idx) = mod_idx;
02176       }
02177 
02178       for (mod_idx = cn_new_tbl_idx; mod_idx <= end_idx; mod_idx++) {
02179 
02180          if (ML_CN_KEEP_ME(mod_idx)) {
02181             new_idx   = ntr_const_tbl(CN_TYPE_IDX(mod_idx),
02182                                                 CN_EXTRA_ZERO_WORD(mod_idx),
02183                                                 &CN_CONST(mod_idx));
02184             ML_CN_IDX(mod_idx)  = new_idx;
02185          }
02186       }
02187 
02188       ML_CN_IDX(0)  = const_tbl_idx;
02189       ML_CP_IDX(0)  = const_pool_idx;
02190    }
02191 
02192   Pragma("_CRI ivdep")        
02193    for (mod_idx = 1; mod_idx < at_new_tbl_idx; mod_idx++) {
02194       ML_AT_IDX(mod_idx)    = mod_idx;
02195       ML_AT_COMPRESSED_IDX(mod_idx) = TRUE;
02196       ML_AT_KEEP_ME(mod_idx)    = TRUE;
02197    }
02198 
02199    if (resolving_duplicates) {
02200 
02201       for (mod_idx = at_new_tbl_idx; mod_idx <= attr_tbl_idx; mod_idx++) {
02202 
02203          if (ML_AT_KEEP_ME(mod_idx)) {
02204             ML_AT_IDX(mod_idx)      = at_new_tbl_idx;
02205             ML_AT_COMPRESSED_IDX(mod_idx) = TRUE;
02206             at_new_tbl_idx++;
02207          }
02208          else if (ML_AT_IDX(mod_idx) != mod_idx && 
02209                   ML_AT_IDX(mod_idx) != NULL_IDX) {
02210 
02211             /* This attr has been resolved to another attr.  Find out if    */
02212             /* any attr in this chain needs to be kept.  If the attr does   */
02213             /* not need to be kept, just skip to the next attr.             */
02214 
02215             idx = mod_idx;
02216 
02217             /* Search until we find the attr that gets kept in this chain.  */
02218             /* If ML_AT_KEEP_ME is set, we've found the attr that gets kept */
02219             /* in the chain.  If ML_AT_COMPRESSED_IDX is set, this attr in  */
02220             /* the chain has already been changed to index to its new       */
02221             /* compressed index.  Following is an example of how this can   */
02222             /* happen:     ML_AT_IDX(344) = 1268.  ML_AT_KEEP_ME(1268) = T  */
02223             /* We enter this code with 344.  After this code sequence,      */
02224             /* ML_AT_IDX(1268) = 344, ML_AT_KEEP_ME(1268) = FALSE.          */
02225             /* ML_AT_IDX(344) = 20 (The new compressed index.)              */
02226             /* ML_AT_KEEP_ME(344) = TRUE.  ML_AT_COMPRESSED_IDX(344) = TRUE.*/
02227             /*                    */
02228             /* We enter this code with 1268.  After this code sequence,     */
02229             /* ML_AT_IDX(1268) = 20 and ML_AT_COMPRESSED_IDX(1268) = TRUE.  */
02230             /*                    */
02231             /* Now, suppose we also have ML_AT_IDX(3000) = 1268.            */
02232             /* We enter this code with 3000.  We will do the following loop,*/
02233             /* but will stop at 1268, because it already has its compressed */
02234             /* index.  We will then use that index.  So in conclusion,      */
02235             /* attrs 3000, 1268 and 344 are all the same.  What we want is  */
02236             /* just one copy of this attr at index 20, when compression is  */
02237             /* finished.                                                    */
02238 
02239             while (idx != NULL_IDX &&
02240                    !ML_AT_KEEP_ME(idx) &&
02241                    !ML_AT_COMPRESSED_IDX(idx)) {
02242                idx = ML_AT_IDX(idx);
02243             }
02244 
02245             if (idx > mod_idx) {
02246 
02247                /* The duplicate attr being kept has not been assigned a new */
02248                /* index yet.  Switch the attrs that are being kept, since   */
02249                /* we are ready to assign a new index to this attr.          */
02250 
02251                /* Since these are the same thing - switch the actual info   */
02252                /* in the attr, so that all information about which entries  */
02253                /* in which tables should be kept will remain okay.          */
02254 
02255                COPY_ATTR_NTRY(AT_WORK_IDX, mod_idx);
02256                COPY_ATTR_NTRY(mod_idx, idx);
02257                COPY_ATTR_NTRY(idx, AT_WORK_IDX);
02258 
02259                ML_AT_KEEP_ME(idx) = FALSE;
02260                ML_AT_KEEP_ME(mod_idx) = TRUE;
02261 
02262                /* Set the higher duplicate attr ML_AT_IDX to lower duplicate */
02263                /* attr index.  When the higher duplicate attr comes up, it   */
02264                /* will fall through here but take the else clause instead of */
02265                /* this clause.  That will get its ML_AT_IDX set correctly.   */
02266                /* We cannot set ML_AT_IDX directly, because when the higher  */
02267                /* attr comes through, it won't know that its ML_AT_IDX has   */
02268                /* already been adjusted.                                     */
02269 
02270                ML_AT_IDX(idx)     = mod_idx;
02271                ML_AT_IDX(mod_idx)   = at_new_tbl_idx;
02272                ML_AT_COMPRESSED_IDX(mod_idx)  = TRUE;
02273                at_new_tbl_idx++;
02274             }
02275             else if (idx != NULL_IDX) {
02276                ML_AT_IDX(mod_idx)   = ML_AT_IDX(idx);
02277                ML_AT_COMPRESSED_IDX(mod_idx)  = TRUE;
02278             }
02279          }
02280       }
02281    }
02282    else {
02283 
02284   Pragma("_CRI ivdep")        
02285       for (mod_idx = at_new_tbl_idx; mod_idx <= attr_tbl_idx; mod_idx++) {
02286 
02287          if (ML_AT_KEEP_ME(mod_idx)) {
02288             ML_AT_IDX(mod_idx)  = at_new_tbl_idx;
02289             at_new_tbl_idx++;
02290          }
02291       }
02292    }
02293 
02294   Pragma("_CRI ivdep")        
02295    for (mod_idx = 1; mod_idx < bd_new_tbl_idx; mod_idx++) {
02296       ML_BD_IDX(mod_idx)  = mod_idx;
02297    }
02298 
02299   Pragma("_CRI ivdep")        
02300    for (mod_idx = bd_new_tbl_idx; mod_idx <= bounds_tbl_idx; mod_idx++) {
02301 
02302       if (ML_BD_KEEP_ME(mod_idx)) {
02303          ML_BD_IDX(mod_idx) = bd_new_tbl_idx;
02304          bd_new_tbl_idx   = bd_new_tbl_idx + BD_NTRY_SIZE(mod_idx);
02305       }
02306    }
02307 
02308    if (save_const_tbl_idx == NULL_IDX) {
02309 
02310   Pragma("_CRI ivdep")        
02311       for (mod_idx = 1; mod_idx < cn_new_tbl_idx; mod_idx++) {
02312          ML_CN_IDX(mod_idx) = mod_idx;
02313       }
02314    
02315   Pragma("_CRI ivdep")        
02316       for (mod_idx = cn_new_tbl_idx; mod_idx <= const_tbl_idx; mod_idx++) {
02317    
02318          if (ML_CN_KEEP_ME(mod_idx)) {
02319             ML_CN_IDX(mod_idx)  = cn_new_tbl_idx;
02320             cn_new_tbl_idx++;
02321          }
02322       }
02323 
02324   Pragma("_CRI ivdep")        
02325       for (mod_idx = 1; mod_idx < cp_new_tbl_idx; mod_idx++) {
02326          ML_CP_IDX(mod_idx) = mod_idx;
02327       }
02328 
02329       end_idx = const_pool_idx;
02330 
02331       for (mod_idx = cp_new_tbl_idx; mod_idx <= end_idx; mod_idx++) {
02332 
02333          if (ML_CP_KEEP_ME(mod_idx)) {
02334 
02335 # if defined(_HOST32)
02336    
02337             if (ML_CP_DALIGN_ME(mod_idx)) {
02338 
02339                while ((((long)&const_pool[cp_new_tbl_idx]) % 8) != 0) {
02340                   cp_new_tbl_idx++;
02341                   TBL_REALLOC_CK(const_pool, 1);
02342                }
02343    
02344                if (const_pool_idx > mod_link_tbl_idx) {
02345                   idx = mod_link_tbl_idx;
02346                   TBL_REALLOC_CK(mod_link_tbl, const_pool_idx);
02347    
02348                   for (; idx <= mod_link_tbl_idx; idx++) {
02349                      CLEAR_TBL_NTRY(mod_link_tbl, idx);
02350                   }
02351                }
02352    
02353             }
02354    
02355 # endif
02356             ML_CP_IDX(mod_idx)  = cp_new_tbl_idx;
02357             cp_new_tbl_idx    += ML_CP_LEN(mod_idx);
02358          }
02359       }
02360    }
02361 
02362   Pragma("_CRI ivdep")        
02363    for (mod_idx = 1; mod_idx < il_new_tbl_idx; mod_idx++) {
02364       ML_IL_IDX(mod_idx)  = mod_idx;
02365    }
02366 
02367   Pragma("_CRI ivdep")        
02368    for (mod_idx = il_new_tbl_idx; mod_idx <= ir_list_tbl_idx; mod_idx++) {
02369 
02370       if (ML_IL_KEEP_ME(mod_idx)) {
02371          ML_IL_IDX(mod_idx) = il_new_tbl_idx;
02372          il_new_tbl_idx++;
02373       }
02374    }
02375 
02376   Pragma("_CRI ivdep")        
02377    for (mod_idx = 1; mod_idx < ir_new_tbl_idx; mod_idx++) {
02378       ML_IR_IDX(mod_idx)  = mod_idx;
02379    }
02380 
02381   Pragma("_CRI ivdep")        
02382    for (mod_idx = ir_new_tbl_idx; mod_idx <= ir_tbl_idx; mod_idx++) {
02383 
02384       if (ML_IR_KEEP_ME(mod_idx)) {
02385          ML_IR_IDX(mod_idx) = ir_new_tbl_idx;
02386          ir_new_tbl_idx++;
02387       }
02388    }
02389 
02390   Pragma("_CRI ivdep")        
02391    for (mod_idx = 1; mod_idx < ln_new_tbl_idx; mod_idx++) {
02392       ML_LN_IDX(mod_idx)  = mod_idx;
02393    }
02394 
02395   Pragma("_CRI ivdep")        
02396    for (mod_idx = ln_new_tbl_idx; mod_idx <= loc_name_tbl_idx; mod_idx++) {
02397 
02398       if (ML_LN_KEEP_ME(mod_idx)) {
02399          ML_LN_IDX(mod_idx) = ln_new_tbl_idx;
02400          ln_new_tbl_idx++;
02401       }
02402    }
02403 
02404   Pragma("_CRI ivdep")        
02405    for (mod_idx = 1; mod_idx < np_new_tbl_idx; mod_idx++) {
02406       ML_NP_IDX(mod_idx)  = mod_idx;
02407    }
02408 
02409   Pragma("_CRI ivdep")        
02410    for (mod_idx = np_new_tbl_idx; mod_idx <= name_pool_idx; mod_idx++) {
02411 
02412       if (ML_NP_KEEP_ME(mod_idx)) {
02413          ML_NP_IDX(mod_idx) = np_new_tbl_idx;
02414          ML_NP_LEN(mod_idx) = WORD_LEN(ML_NP_LEN(mod_idx));
02415          np_new_tbl_idx   += ML_NP_LEN(mod_idx);
02416       }
02417    }
02418 
02419   Pragma("_CRI ivdep")        
02420    for (mod_idx = 1; mod_idx < sb_new_tbl_idx; mod_idx++) {
02421       ML_SB_IDX(mod_idx)  = mod_idx;
02422    }
02423 
02424   Pragma("_CRI ivdep")        
02425    for (mod_idx = sb_new_tbl_idx; mod_idx <= stor_blk_tbl_idx; mod_idx++) {
02426 
02427       if (ML_SB_KEEP_ME(mod_idx)) {
02428          ML_SB_IDX(mod_idx) = sb_new_tbl_idx;
02429          sb_new_tbl_idx++;
02430       }
02431    }
02432 
02433   Pragma("_CRI ivdep")        
02434    for (mod_idx = 1; mod_idx < sn_new_tbl_idx; mod_idx++) {
02435       ML_SN_IDX(mod_idx)  = mod_idx;
02436    }
02437 
02438   Pragma("_CRI ivdep")        
02439    for (mod_idx = sn_new_tbl_idx; mod_idx <= sec_name_tbl_idx; mod_idx++) {
02440 
02441       if (ML_SN_KEEP_ME(mod_idx)) {
02442          ML_SN_IDX(mod_idx) = sn_new_tbl_idx;
02443          sn_new_tbl_idx++;
02444       }
02445    }
02446 
02447   Pragma("_CRI ivdep")        
02448    for (mod_idx = 1; mod_idx < sh_new_tbl_idx; mod_idx++) {
02449       ML_SH_IDX(mod_idx)  = mod_idx;
02450    }
02451 
02452   Pragma("_CRI ivdep")        
02453    for (mod_idx = sh_new_tbl_idx; mod_idx <= sh_tbl_idx; mod_idx++) {
02454 
02455       if (ML_SH_KEEP_ME(mod_idx)) {
02456          ML_SH_IDX(mod_idx) = sh_new_tbl_idx;
02457          sh_new_tbl_idx++;
02458       }
02459    }
02460 
02461   Pragma("_CRI ivdep")        
02462    for (mod_idx = 1; mod_idx < typ_new_tbl_idx; mod_idx++) {
02463       ML_TYP_IDX(mod_idx) = mod_idx;
02464    }
02465 
02466    /* Assigning typ indexes is handled in compress_typ_table */
02467 
02468    TRACE (Func_Exit, "assign_new_idxs", NULL);
02469 
02470    return;
02471 
02472 }   /* assign_new_idxs */
02473 
02474 /******************************************************************************\
02475 |*                        *|
02476 |* Description:                     *|
02477 |*  This moves the tables, writing over entries that should be compressed *|
02478 |*      out.                                                                  *|
02479 |*                        *|
02480 |* Input parameters:                    *|
02481 |*  al_idx -> Index to start checking attr_list_tbl for updating the      *|
02482 |*            AL_ATTR_IDX.                                                *|
02483 |*                        *|
02484 |* Output parameters:                   *|
02485 |*  NONE                      *|
02486 |*                        *|
02487 |* Returns:                     *|
02488 |*  NOTHING                     *|
02489 |*                        *|
02490 \******************************************************************************/
02491 static void  compress_tbls(int    al_idx,
02492          boolean  from_interface)
02493 {
02494    int    at_idx;
02495    int    bd_idx;
02496    int    cn_idx;
02497    int    cp_idx;
02498    int    dim;
02499    int    end_idx;
02500    int    idx;
02501    int    il_idx;
02502    int    ir_idx;
02503    int    ln_idx;
02504    int    mod_idx;
02505    int    np_idx;
02506    int    sb_idx;
02507    int    sh_idx;
02508    int    sn_idx;
02509    int    start_idx;
02510    int    typ_idx;
02511 
02512 # if 0
02513    int    end_old_idx;
02514    int    start_old_idx;
02515 # endif
02516 
02517 
02518    TRACE (Func_Entry, "compress_tbls", NULL);
02519 
02520    /* The zeroth entry in the module link table contains the starting index   */
02521    /* for each table.  This allows partial compression at the end of tables.  */
02522    /* After this field is saved, clear these entries.  They must be NULL_IDX  */
02523    /* so that if a field has NULL_IDX in it, it will not change.   All other  */
02524    /* fields are required to be set correctly or they will end up NULL.       */
02525 
02526    at_idx = ML_AT_IDX(0);
02527    bd_idx = ML_BD_IDX(0);
02528    cn_idx = ML_CN_IDX(0);
02529    cp_idx = ML_CP_IDX(0);
02530    il_idx = ML_IL_IDX(0);
02531    ir_idx = ML_IR_IDX(0);
02532    ln_idx = ML_LN_IDX(0);
02533    np_idx = ML_NP_IDX(0);
02534    sb_idx = ML_SB_IDX(0);
02535    sh_idx = ML_SH_IDX(0);
02536    sn_idx = ML_SN_IDX(0);
02537    typ_idx= ML_TYP_IDX(0);
02538 
02539    CLEAR_TBL_NTRY(mod_link_tbl, NULL_IDX);
02540 
02541    /* Compresses the type table, by sharing duplicate entries */
02542    /* and collapsing out unneeded type entries.               */
02543 
02544    compress_type_tbl(typ_idx);
02545 
02546    if (!only_update_new_tbl_entries) {
02547       update_idxs_in_attr_entry(1,at_idx);
02548    }
02549 
02550    start_idx  = at_idx+1;
02551 
02552 # if 0
02553    mod_idx  = start_idx;
02554 
02555    do {
02556 
02557       while (mod_idx <= attr_tbl_idx && !ML_AT_KEEP_ME(mod_idx)) {
02558          mod_idx++;
02559       }
02560 
02561       if (mod_idx <= attr_tbl_idx) {
02562          start_old_idx  = mod_idx;
02563 
02564          while (mod_idx <= attr_tbl_idx && ML_AT_KEEP_ME(mod_idx)) {
02565             mod_idx++;
02566          }
02567 
02568          end_old_idx  = mod_idx - 1;
02569          ++at_idx;
02570 
02571          if (start_old_idx != at_idx) {
02572             (void) memmove ((void *) &attr_tbl[at_idx],
02573                             (void *) &attr_tbl[start_old_idx],
02574                             (end_old_idx - start_old_idx +1) * NUM_AT_WDS * 8);
02575          }
02576          at_idx        += end_old_idx - start_old_idx;
02577                          
02578          /* The last one checked is either too high   */
02579          /* or has !ML_AT_KEEP_ME set.  Skip past it. */
02580 
02581          ++mod_idx;
02582       }
02583    }
02584    while (mod_idx <= attr_tbl_idx);
02585 
02586 # endif
02587 
02588    for (mod_idx = start_idx; mod_idx <= attr_tbl_idx; mod_idx++) {
02589 
02590       if (ML_AT_KEEP_ME(mod_idx)) {
02591          ++at_idx;
02592          COPY_ATTR_NTRY(at_idx, mod_idx);
02593       }
02594    }
02595 
02596    update_idxs_in_attr_entry(start_idx, at_idx);
02597 
02598    if (count_derived_types) {
02599 
02600       for (mod_idx = start_idx; mod_idx <= at_idx; mod_idx++) {
02601          if (AT_OBJ_CLASS(mod_idx) == Derived_Type) {
02602             num_module_derived_types++;
02603          }
02604       }
02605    }
02606 
02607    /* mod_idx = (only_update_new_tbl_entries) ? bd_idx + 1 : 1; */
02608    mod_idx  = 1;
02609 
02610    while (mod_idx <= bd_idx) {
02611 
02612       if (!BD_USED_NTRY(mod_idx)) {  /* Entry from the free list */
02613          BD_NEXT_FREE_NTRY(mod_idx) = ML_BD_IDX(BD_NEXT_FREE_NTRY(mod_idx));
02614          mod_idx = mod_idx + BD_NTRY_SIZE(mod_idx);
02615       }
02616       else if (BD_DIST_NTRY(mod_idx)) {
02617 
02618          for (dim = 1; dim <= BD_RANK(mod_idx); dim++) {
02619 
02620             if (BD_CYCLIC_FLD(mod_idx, dim) == CN_Tbl_Idx) {
02621                BD_CYCLIC_IDX(mod_idx, dim) = 
02622                                   ML_CN_IDX(BD_CYCLIC_IDX(mod_idx, dim));
02623             }
02624             else if (BD_CYCLIC_FLD(mod_idx, dim) == AT_Tbl_Idx) {
02625                BD_CYCLIC_IDX(mod_idx, dim) = 
02626                                   ML_AT_IDX(BD_CYCLIC_IDX(mod_idx, dim));
02627             }
02628 
02629             if (BD_ONTO_FLD(mod_idx, dim) == CN_Tbl_Idx) {
02630                BD_ONTO_IDX(mod_idx, dim) = 
02631                                   ML_CN_IDX(BD_ONTO_IDX(mod_idx, dim));
02632             }
02633             else if (BD_ONTO_FLD(mod_idx, dim) == AT_Tbl_Idx) {
02634                BD_ONTO_IDX(mod_idx, dim) = 
02635                                   ML_AT_IDX(BD_ONTO_IDX(mod_idx, dim));
02636             }
02637          }
02638          mod_idx = mod_idx + BD_RANK(mod_idx) + 1;  /* 1 for header */
02639       }
02640       else if (BD_ARRAY_CLASS(mod_idx) != Deferred_Shape) {
02641 
02642          if (BD_LEN_FLD(mod_idx) == CN_Tbl_Idx) {
02643             BD_LEN_IDX(mod_idx) = ML_CN_IDX(BD_LEN_IDX(mod_idx));
02644          }
02645          else if (BD_LEN_FLD(mod_idx) == AT_Tbl_Idx) {
02646             BD_LEN_IDX(mod_idx) = ML_AT_IDX(BD_LEN_IDX(mod_idx));
02647          }
02648 
02649          for (dim = 1; dim <= BD_RANK(mod_idx); dim++) {
02650 
02651             if (BD_LB_FLD(mod_idx, dim) == CN_Tbl_Idx) {
02652                BD_LB_IDX(mod_idx, dim) = ML_CN_IDX(BD_LB_IDX(mod_idx, dim));
02653             }
02654             else if (BD_LB_FLD(mod_idx, dim) == AT_Tbl_Idx) {
02655                BD_LB_IDX(mod_idx, dim) = ML_AT_IDX(BD_LB_IDX(mod_idx, dim));
02656             }
02657 
02658             if (BD_UB_FLD(mod_idx, dim) == CN_Tbl_Idx) {
02659                BD_UB_IDX(mod_idx, dim) = ML_CN_IDX(BD_UB_IDX(mod_idx, dim));
02660             }
02661             else if (BD_UB_FLD(mod_idx, dim) == AT_Tbl_Idx) {
02662                BD_UB_IDX(mod_idx, dim) = ML_AT_IDX(BD_UB_IDX(mod_idx, dim));
02663             }
02664 
02665             if (BD_XT_FLD(mod_idx, dim) == CN_Tbl_Idx) {
02666                BD_XT_IDX(mod_idx, dim) = ML_CN_IDX(BD_XT_IDX(mod_idx, dim));
02667             }
02668             else if (BD_XT_FLD(mod_idx, dim) == AT_Tbl_Idx) {
02669                BD_XT_IDX(mod_idx, dim) = ML_AT_IDX(BD_XT_IDX(mod_idx, dim));
02670             }
02671 
02672             if (BD_SM_FLD(mod_idx, dim) == CN_Tbl_Idx) {
02673                BD_SM_IDX(mod_idx, dim) = ML_CN_IDX(BD_SM_IDX(mod_idx, dim));
02674             }
02675             else if (BD_SM_FLD(mod_idx, dim) == AT_Tbl_Idx) {
02676                BD_SM_IDX(mod_idx, dim) = ML_AT_IDX(BD_SM_IDX(mod_idx, dim));
02677             }
02678          }
02679          mod_idx = mod_idx + BD_RANK(mod_idx) + 1;  /* 1 for header */
02680       }
02681       else {
02682          mod_idx++;
02683       }
02684    }
02685 
02686    start_idx  = bd_idx+1;
02687 
02688    for (mod_idx = start_idx; mod_idx <= bounds_tbl_idx; mod_idx++) {
02689 
02690       if (ML_BD_KEEP_ME(mod_idx)) {
02691          ++bd_idx;
02692          COPY_BD_NTRY(bd_idx, mod_idx);
02693 
02694          if (BD_DIST_NTRY(bd_idx) ||
02695              BD_ARRAY_CLASS(bd_idx) != Deferred_Shape) {
02696 
02697             bd_idx = bd_idx + BD_RANK(bd_idx);
02698          }
02699       }
02700    }
02701 
02702    for (mod_idx = start_idx; mod_idx <= bd_idx; mod_idx++) {
02703 
02704       if (BD_DIST_NTRY(mod_idx)) {
02705 
02706          for (dim = 1; dim <= BD_RANK(mod_idx); dim++) {
02707 
02708             if (BD_CYCLIC_FLD(mod_idx, dim) == CN_Tbl_Idx) {
02709                BD_CYCLIC_IDX(mod_idx, dim) =
02710                                   ML_CN_IDX(BD_CYCLIC_IDX(mod_idx, dim));
02711             }
02712             else if (BD_CYCLIC_FLD(mod_idx, dim) == AT_Tbl_Idx) {
02713                BD_CYCLIC_IDX(mod_idx, dim) =
02714                                   ML_AT_IDX(BD_CYCLIC_IDX(mod_idx, dim));
02715             }
02716 
02717             if (BD_ONTO_FLD(mod_idx, dim) == CN_Tbl_Idx) {
02718                BD_ONTO_IDX(mod_idx, dim) =
02719                                   ML_CN_IDX(BD_ONTO_IDX(mod_idx, dim));
02720             }
02721             else if (BD_ONTO_FLD(mod_idx, dim) == AT_Tbl_Idx) {
02722                BD_ONTO_IDX(mod_idx, dim) =
02723                                   ML_AT_IDX(BD_ONTO_IDX(mod_idx, dim));
02724             }
02725          }
02726          mod_idx = mod_idx + BD_RANK(mod_idx);
02727       }
02728       else if (BD_ARRAY_CLASS(mod_idx) != Deferred_Shape) {
02729 
02730          if (BD_LEN_FLD(mod_idx) == CN_Tbl_Idx) {
02731             BD_LEN_IDX(mod_idx) = ML_CN_IDX(BD_LEN_IDX(mod_idx));
02732          }
02733          else if (BD_LEN_FLD(mod_idx) == AT_Tbl_Idx) {
02734             BD_LEN_IDX(mod_idx) = ML_AT_IDX(BD_LEN_IDX(mod_idx));
02735          }
02736 
02737          for (dim = 1; dim <= BD_RANK(mod_idx); dim++) {
02738 
02739             if (BD_LB_FLD(mod_idx, dim) == CN_Tbl_Idx) {
02740                BD_LB_IDX(mod_idx, dim) = ML_CN_IDX(BD_LB_IDX(mod_idx, dim));
02741             }
02742             else if (BD_LB_FLD(mod_idx, dim) == AT_Tbl_Idx) {
02743                BD_LB_IDX(mod_idx, dim) = ML_AT_IDX(BD_LB_IDX(mod_idx, dim));
02744             }
02745 
02746             if (BD_UB_FLD(mod_idx, dim) == CN_Tbl_Idx) {
02747                BD_UB_IDX(mod_idx, dim) = ML_CN_IDX(BD_UB_IDX(mod_idx, dim));
02748             }
02749             else if (BD_UB_FLD(mod_idx, dim) == AT_Tbl_Idx) {
02750                BD_UB_IDX(mod_idx, dim) = ML_AT_IDX(BD_UB_IDX(mod_idx, dim));
02751             }
02752 
02753             if (BD_XT_FLD(mod_idx, dim) == CN_Tbl_Idx) {
02754                BD_XT_IDX(mod_idx, dim) = ML_CN_IDX(BD_XT_IDX(mod_idx, dim));
02755             }
02756             else if (BD_XT_FLD(mod_idx, dim) == AT_Tbl_Idx) {
02757                BD_XT_IDX(mod_idx, dim) = ML_AT_IDX(BD_XT_IDX(mod_idx, dim));
02758             }
02759 
02760             if (BD_SM_FLD(mod_idx, dim) == CN_Tbl_Idx) {
02761                BD_SM_IDX(mod_idx, dim) = ML_CN_IDX(BD_SM_IDX(mod_idx, dim));
02762             }
02763             else if (BD_SM_FLD(mod_idx, dim) == AT_Tbl_Idx) {
02764                BD_SM_IDX(mod_idx, dim) = ML_AT_IDX(BD_SM_IDX(mod_idx, dim));
02765             }
02766          }
02767          mod_idx = mod_idx + BD_RANK(mod_idx);
02768       }
02769    }
02770 
02771    start_idx  = cn_idx+1;
02772 
02773   Pragma("_CRI ivdep")        
02774    for (mod_idx = cn_idx+1; mod_idx <= const_tbl_idx; mod_idx++) {
02775 
02776       if (ML_CN_KEEP_ME(mod_idx)) {
02777          const_tbl[++cn_idx]  = const_tbl[mod_idx];
02778       }
02779    }
02780 
02781 # if defined(_DEBUG)
02782    for (mod_idx = 1; mod_idx <= const_tbl_idx; mod_idx++) {
02783 
02784       if (CN_POOL_IDX(mod_idx) == NULL_IDX) {
02785          PRINTMSG(stmt_start_line, 1349, Internal, 0, mod_idx);
02786       }
02787    }
02788 # endif
02789 
02790 
02791    for (mod_idx = 1; mod_idx <= cn_idx; mod_idx++) {
02792       CN_TYPE_IDX(mod_idx)  = ML_TYP_IDX(CN_TYPE_IDX(mod_idx));
02793       CN_POOL_IDX(mod_idx)  = ML_CP_IDX(CN_POOL_IDX(mod_idx));
02794    }
02795 
02796    for (mod_idx = cp_idx+1; mod_idx <= const_pool_idx; mod_idx++) {
02797 
02798       if (ML_CP_KEEP_ME(mod_idx)) {
02799 
02800 # if defined(_HOST32) 
02801 
02802          if (ML_CP_DALIGN_ME(mod_idx)) {
02803             cp_idx = ML_CP_IDX(mod_idx) - 1;
02804          }
02805 # endif
02806 
02807          for (idx = 0; idx < ML_CP_LEN(mod_idx); idx++) {
02808             const_pool[++cp_idx]  = const_pool[mod_idx+idx];
02809          }
02810       }
02811    }
02812 
02813    for (mod_idx = (from_interface || !only_update_new_tbl_entries) ?
02814                   1 : (il_idx+1); mod_idx <= il_idx; mod_idx++) {
02815       IL_NEXT_LIST_IDX(mod_idx) = ML_IL_IDX(IL_NEXT_LIST_IDX(mod_idx));
02816 
02817       if (!IL_ARG_DESC_VARIANT(mod_idx)) {
02818          IL_PREV_LIST_IDX(mod_idx) = ML_IL_IDX(IL_PREV_LIST_IDX(mod_idx));
02819       }
02820 
02821       switch (IL_FLD(mod_idx)) {
02822       case CN_Tbl_Idx:
02823          IL_IDX(mod_idx) = ML_CN_IDX(IL_IDX(mod_idx));
02824          break;
02825 
02826       case AT_Tbl_Idx:
02827          IL_IDX(mod_idx) = ML_AT_IDX(IL_IDX(mod_idx));
02828          break;
02829       
02830       case IL_Tbl_Idx:
02831          IL_IDX(mod_idx) = ML_IL_IDX(IL_IDX(mod_idx));
02832          break;
02833 
02834       case IR_Tbl_Idx:
02835          IL_IDX(mod_idx) = ML_IR_IDX(IL_IDX(mod_idx));
02836          break;
02837       }
02838    }
02839 
02840    start_idx  = il_idx + 1;
02841 
02842    for (mod_idx = start_idx; mod_idx <= ir_list_tbl_idx; mod_idx++) {
02843 
02844       if (ML_IL_KEEP_ME(mod_idx)) {
02845          ir_list_tbl[++il_idx]    = ir_list_tbl[mod_idx];
02846       }
02847    }
02848 
02849    for (mod_idx = start_idx; mod_idx <= il_idx; mod_idx++) {
02850       IL_NEXT_LIST_IDX(mod_idx) = ML_IL_IDX(IL_NEXT_LIST_IDX(mod_idx));
02851 
02852       if (!IL_ARG_DESC_VARIANT(mod_idx)) {
02853          IL_PREV_LIST_IDX(mod_idx) = ML_IL_IDX(IL_PREV_LIST_IDX(mod_idx));
02854       }
02855 
02856       switch (IL_FLD(mod_idx)) {
02857       case CN_Tbl_Idx:
02858          IL_IDX(mod_idx) = ML_CN_IDX(IL_IDX(mod_idx));
02859          break;
02860 
02861       case AT_Tbl_Idx:
02862          IL_IDX(mod_idx) = ML_AT_IDX(IL_IDX(mod_idx));
02863          break;
02864       
02865       case IL_Tbl_Idx:
02866          IL_IDX(mod_idx) = ML_IL_IDX(IL_IDX(mod_idx));
02867          break;
02868 
02869       case IR_Tbl_Idx:
02870          IL_IDX(mod_idx) = ML_IR_IDX(IL_IDX(mod_idx));
02871          break;
02872       }
02873    }
02874 
02875    for (mod_idx = (from_interface || !only_update_new_tbl_entries) ?
02876                   1 : (ir_idx + 1); mod_idx <= ir_idx; mod_idx++) {
02877       IR_TYPE_IDX(mod_idx)  = ML_TYP_IDX(IR_TYPE_IDX(mod_idx));
02878 
02879       switch (IR_FLD_L(mod_idx)) {
02880       case CN_Tbl_Idx:
02881          IR_IDX_L(mod_idx) = ML_CN_IDX(IR_IDX_L(mod_idx));
02882          break;
02883 
02884       case AT_Tbl_Idx:
02885          IR_IDX_L(mod_idx) = ML_AT_IDX(IR_IDX_L(mod_idx));
02886          break;
02887          
02888       case IL_Tbl_Idx:
02889          IR_IDX_L(mod_idx) = ML_IL_IDX(IR_IDX_L(mod_idx));
02890          break;
02891 
02892       case IR_Tbl_Idx:
02893          IR_IDX_L(mod_idx) = ML_IR_IDX(IR_IDX_L(mod_idx));
02894          break;
02895       }
02896 
02897       switch (IR_FLD_R(mod_idx)) {
02898       case CN_Tbl_Idx:
02899          IR_IDX_R(mod_idx) = ML_CN_IDX(IR_IDX_R(mod_idx));
02900          break;
02901 
02902       case AT_Tbl_Idx:
02903          IR_IDX_R(mod_idx) = ML_AT_IDX(IR_IDX_R(mod_idx));
02904          break;
02905          
02906       case IL_Tbl_Idx:
02907          IR_IDX_R(mod_idx) = ML_IL_IDX(IR_IDX_R(mod_idx));
02908          break;
02909 
02910       case IR_Tbl_Idx:
02911          IR_IDX_R(mod_idx) = ML_IR_IDX(IR_IDX_R(mod_idx));
02912          break;
02913       }
02914    }
02915 
02916    start_idx = ir_idx+1;
02917 
02918    for (mod_idx = start_idx; mod_idx <= ir_tbl_idx; mod_idx++) {
02919 
02920       if (ML_IR_KEEP_ME(mod_idx)) {
02921          ir_tbl[++ir_idx] = ir_tbl[mod_idx];
02922       }
02923    }
02924 
02925    for (mod_idx = start_idx; mod_idx <= ir_idx; mod_idx++) {
02926       IR_TYPE_IDX(mod_idx)  = ML_TYP_IDX(IR_TYPE_IDX(mod_idx));
02927 
02928       switch (IR_FLD_L(mod_idx)) {
02929       case CN_Tbl_Idx:
02930          IR_IDX_L(mod_idx) = ML_CN_IDX(IR_IDX_L(mod_idx));
02931          break;
02932 
02933       case AT_Tbl_Idx:
02934          IR_IDX_L(mod_idx) = ML_AT_IDX(IR_IDX_L(mod_idx));
02935          break;
02936       
02937       case IL_Tbl_Idx:
02938          IR_IDX_L(mod_idx) = ML_IL_IDX(IR_IDX_L(mod_idx));
02939          break;
02940 
02941       case IR_Tbl_Idx:
02942          IR_IDX_L(mod_idx) = ML_IR_IDX(IR_IDX_L(mod_idx));
02943          break;
02944       }
02945 
02946       switch (IR_FLD_R(mod_idx)) {
02947       case CN_Tbl_Idx:
02948          IR_IDX_R(mod_idx) = ML_CN_IDX(IR_IDX_R(mod_idx));
02949          break;
02950 
02951       case AT_Tbl_Idx:
02952          IR_IDX_R(mod_idx) = ML_AT_IDX(IR_IDX_R(mod_idx));
02953          break;
02954       
02955       case IL_Tbl_Idx:
02956          IR_IDX_R(mod_idx) = ML_IL_IDX(IR_IDX_R(mod_idx));
02957          break;
02958 
02959       case IR_Tbl_Idx:
02960          IR_IDX_R(mod_idx) = ML_IR_IDX(IR_IDX_R(mod_idx));
02961          break;
02962       }
02963    }
02964 
02965    start_idx  = ln_idx+1;
02966 
02967    for (mod_idx = start_idx; mod_idx <= loc_name_tbl_idx; mod_idx++) {
02968 
02969       if (ML_LN_KEEP_ME(mod_idx)) {
02970          loc_name_tbl[++ln_idx] = loc_name_tbl[mod_idx];
02971       }
02972    }
02973 
02974    for (mod_idx = start_idx; mod_idx <= ln_idx; mod_idx++) {
02975 
02976      if (LN_ATTR_IDX(mod_idx) != NULL_IDX) {
02977         LN_ATTR_IDX(mod_idx)  = ML_AT_IDX(LN_ATTR_IDX(mod_idx));
02978         LN_NAME_IDX(mod_idx)  = AT_NAME_IDX(LN_ATTR_IDX(mod_idx));
02979         LN_NAME_LEN(mod_idx)  = AT_NAME_LEN(LN_ATTR_IDX(mod_idx));
02980      }
02981      else {
02982         LN_NAME_IDX(mod_idx)  = ML_NP_IDX(LN_NAME_IDX(mod_idx));
02983      }
02984    }
02985 
02986    for (mod_idx = np_idx+1; mod_idx <= name_pool_idx; mod_idx++) {
02987 
02988       if (ML_NP_KEEP_ME(mod_idx)) {
02989 
02990          for (idx = 0; idx < ML_NP_LEN(mod_idx); idx++) {
02991             name_pool[++np_idx].name_long = name_pool[mod_idx+idx].name_long;
02992          }
02993       }
02994    }
02995 
02996    /* for (mod_idx = (only_update_new_tbl_entries) ? (sb_idx + 1) : 1; */
02997    for (mod_idx = 1; mod_idx <= sb_idx; mod_idx++) {
02998       SB_NAME_IDX(mod_idx)    = ML_NP_IDX(SB_NAME_IDX(mod_idx));
02999       SB_MODULE_IDX(mod_idx)    = ML_AT_IDX(SB_MODULE_IDX(mod_idx));
03000 #ifdef KEY /* Bug 14150 */
03001       int sb_ext_name_idx = SB_EXT_NAME_IDX(mod_idx);
03002       if (sb_ext_name_idx) {
03003   SB_EXT_NAME_IDX(mod_idx)  = ML_NP_IDX(sb_ext_name_idx);
03004       }
03005 #endif /* KEY Bug 14150 */
03006 
03007       if (SB_FIRST_ATTR_IDX(mod_idx) != NULL_IDX) {
03008          SB_FIRST_ATTR_IDX(mod_idx) = ML_AT_IDX(SB_FIRST_ATTR_IDX(mod_idx));
03009       }
03010 
03011       switch (SB_LEN_FLD(mod_idx)) {
03012       case AT_Tbl_Idx:
03013          SB_LEN_IDX(mod_idx)    = ML_AT_IDX(SB_LEN_IDX(mod_idx));
03014          break;
03015      
03016       case CN_Tbl_Idx:
03017          SB_LEN_IDX(mod_idx)    = ML_CN_IDX(SB_LEN_IDX(mod_idx));
03018          break;
03019 
03020       case IL_Tbl_Idx:
03021          SB_LEN_IDX(mod_idx)    = ML_IL_IDX(SB_LEN_IDX(mod_idx));
03022          break;
03023 
03024       case IR_Tbl_Idx:
03025          SB_LEN_IDX(mod_idx)    = ML_IR_IDX(SB_LEN_IDX(mod_idx));
03026          break;
03027       }
03028    }
03029 
03030    start_idx = sb_idx + 1;
03031 
03032    for (mod_idx = start_idx; mod_idx <= stor_blk_tbl_idx; mod_idx++) {
03033 
03034       if (ML_SB_KEEP_ME(mod_idx)) {
03035          stor_blk_tbl[++sb_idx]   = stor_blk_tbl[mod_idx];
03036       }
03037    }
03038 
03039    for (mod_idx = start_idx; mod_idx <= sb_idx; mod_idx++) {
03040       SB_NAME_IDX(mod_idx)    = ML_NP_IDX(SB_NAME_IDX(mod_idx));
03041 #ifdef KEY /* Bug 14150 */
03042       int sb_ext_name_idx = SB_EXT_NAME_IDX(mod_idx);
03043       if (sb_ext_name_idx) {
03044   SB_EXT_NAME_IDX(mod_idx)  = ML_NP_IDX(sb_ext_name_idx);
03045       }
03046 #endif /* KEY Bug 14150 */
03047       SB_MODULE_IDX(mod_idx)    = ML_AT_IDX(SB_MODULE_IDX(mod_idx));
03048 
03049       if (SB_FIRST_ATTR_IDX(mod_idx) != NULL_IDX) {
03050          SB_FIRST_ATTR_IDX(mod_idx) = ML_AT_IDX(SB_FIRST_ATTR_IDX(mod_idx));
03051       }
03052 
03053       switch (SB_LEN_FLD(mod_idx)) {
03054       case AT_Tbl_Idx:
03055          SB_LEN_IDX(mod_idx)    = ML_AT_IDX(SB_LEN_IDX(mod_idx));
03056          break;
03057      
03058       case CN_Tbl_Idx:
03059          SB_LEN_IDX(mod_idx)    = ML_CN_IDX(SB_LEN_IDX(mod_idx));
03060          break;
03061 
03062       case IL_Tbl_Idx:
03063          SB_LEN_IDX(mod_idx)    = ML_IL_IDX(SB_LEN_IDX(mod_idx));
03064          break;
03065 
03066       case IR_Tbl_Idx:
03067          SB_LEN_IDX(mod_idx)    = ML_IR_IDX(SB_LEN_IDX(mod_idx));
03068          break;
03069       }
03070    }
03071 
03072    for (mod_idx = (from_interface || !only_update_new_tbl_entries) ?
03073                   1 : (sh_idx + 1); mod_idx <= sh_idx; mod_idx++) {
03074       SH_NEXT_IDX(mod_idx)    = ML_SH_IDX(SH_NEXT_IDX(mod_idx));
03075       SH_PREV_IDX(mod_idx)    = ML_SH_IDX(SH_PREV_IDX(mod_idx));
03076       SH_IR_IDX(mod_idx)    = ML_IR_IDX(SH_IR_IDX(mod_idx));
03077 
03078       if (SH_STMT_TYPE(mod_idx) != Statement_Num_Stmt) {
03079          SH_PARENT_BLK_IDX(mod_idx) = ML_SH_IDX(SH_PARENT_BLK_IDX(mod_idx));
03080       }
03081    }
03082 
03083    start_idx = sh_idx + 1;
03084 
03085    for (mod_idx = start_idx; mod_idx <= sh_tbl_idx; mod_idx++) {
03086 
03087       if (ML_SH_KEEP_ME(mod_idx)) {
03088          sh_tbl[++sh_idx]   = sh_tbl[mod_idx];
03089       }
03090    }
03091 
03092 
03093    for (mod_idx = start_idx; mod_idx <= sh_idx; mod_idx++) {
03094       SH_NEXT_IDX(mod_idx)    = ML_SH_IDX(SH_NEXT_IDX(mod_idx));
03095       SH_PREV_IDX(mod_idx)    = ML_SH_IDX(SH_PREV_IDX(mod_idx));
03096       SH_IR_IDX(mod_idx)    = ML_IR_IDX(SH_IR_IDX(mod_idx));
03097 
03098       if (SH_STMT_TYPE(mod_idx) != Statement_Num_Stmt) {
03099          SH_PARENT_BLK_IDX(mod_idx) = ML_SH_IDX(SH_PARENT_BLK_IDX(mod_idx));
03100       }
03101    }
03102 
03103    /* Need SN_NAME_LEN because of renames situations. */
03104 
03105    /* for (mod_idx = (only_update_new_tbl_entries) ? (sn_idx+1) : 1;  */
03106    for (mod_idx = 1; mod_idx <= sn_idx; mod_idx++) {
03107       SN_ATTR_IDX(mod_idx)  = ML_AT_IDX(SN_ATTR_IDX(mod_idx));
03108       SN_NAME_IDX(mod_idx)  = AT_NAME_IDX(SN_ATTR_IDX(mod_idx));
03109       SN_NAME_LEN(mod_idx)  = AT_NAME_LEN(SN_ATTR_IDX(mod_idx));
03110       SN_SIBLING_LINK(mod_idx)  = ML_SN_IDX(SN_SIBLING_LINK(mod_idx));
03111    }
03112 
03113    start_idx = sn_idx + 1;
03114 
03115    for (mod_idx = start_idx; mod_idx <= sec_name_tbl_idx; mod_idx++) {
03116 
03117       if (ML_SN_KEEP_ME(mod_idx)) {
03118          sec_name_tbl[++sn_idx]   = sec_name_tbl[mod_idx];
03119       }
03120    }
03121 
03122    for (mod_idx = start_idx; mod_idx <= sec_name_tbl_idx; mod_idx++) {
03123       SN_ATTR_IDX(mod_idx)    = ML_AT_IDX(SN_ATTR_IDX(mod_idx));
03124       SN_NAME_IDX(mod_idx)    = AT_NAME_IDX(SN_ATTR_IDX(mod_idx));
03125       SN_NAME_LEN(mod_idx)    = AT_NAME_LEN(SN_ATTR_IDX(mod_idx));
03126       SN_SIBLING_LINK(mod_idx)    = ML_SN_IDX(SN_SIBLING_LINK(mod_idx));
03127    }
03128 
03129    attr_tbl_idx   = at_idx;
03130    attr_aux_tbl_idx = at_idx;
03131    bounds_tbl_idx = bd_idx;
03132    const_tbl_idx  = cn_idx;
03133    const_pool_idx = cp_idx;
03134    loc_name_tbl_idx = ln_idx;
03135    ir_list_tbl_idx  = il_idx;
03136    ir_tbl_idx   = ir_idx;
03137    name_pool_idx  = np_idx;
03138    stor_blk_tbl_idx = sb_idx;
03139    sec_name_tbl_idx = sn_idx;
03140    sh_tbl_idx   = sh_idx;
03141 
03142    /* If this is a partial compression, the only entries added to the */
03143    /* attr_list_tbl must point to new attributes coming in during USE */
03144    /* processing.                                                     */
03145 
03146    for (mod_idx = al_idx+1; mod_idx <= attr_list_tbl_idx; mod_idx++) {
03147       
03148 # if defined(_DEBUG)
03149      end_idx  = ML_AT_IDX(AL_ATTR_IDX(mod_idx));
03150 
03151      if (!AL_FREE(mod_idx) &&
03152           AL_ATTR_IDX(mod_idx) != NULL_IDX &&
03153          !ML_AT_KEEP_ME(AL_ATTR_IDX(mod_idx)) &&
03154          !ML_AT_COMPRESSED_IDX(AL_ATTR_IDX(mod_idx))) {
03155 
03156 
03157         /* This attr is not being kept.  It should have been cleared. */
03158 
03159         PRINTMSG(stmt_start_line, 1321, Internal, 0, mod_idx, 
03160                  AL_ATTR_IDX(mod_idx));
03161      }
03162 
03163 # endif
03164 
03165       AL_ATTR_IDX(mod_idx) = ML_AT_IDX(AL_ATTR_IDX(mod_idx));
03166    }
03167 
03168    mod_idx = SCP_HN_FW_IDX(curr_scp_idx) + 1;
03169    end_idx = SCP_HN_LW_IDX(curr_scp_idx);
03170 
03171    while (mod_idx < end_idx) {
03172 
03173       if (!ML_AT_KEEP_ME(HN_ATTR_IDX(mod_idx))) {
03174 
03175          if (!ML_AT_COMPRESSED_IDX(HN_ATTR_IDX(mod_idx))) {
03176             remove_hidden_name_ntry(mod_idx);
03177             end_idx = SCP_HN_LW_IDX(curr_scp_idx);
03178          }
03179       }
03180       mod_idx++;
03181    }
03182 
03183 
03184    for (mod_idx = SCP_HN_FW_IDX(curr_scp_idx) + 1;
03185         mod_idx < SCP_HN_LW_IDX(curr_scp_idx); mod_idx++) {
03186       HN_ATTR_IDX(mod_idx)  = ML_AT_IDX(HN_ATTR_IDX(mod_idx));
03187       HN_NAME_IDX(mod_idx)  = ML_NP_IDX(HN_NAME_IDX(mod_idx));
03188    }
03189 
03190    /* This updates the scp attr index, but be careful, because        */
03191    /* everything else in the scope table could be bad pointers.       */
03192 
03193    SCP_ATTR_IDX(curr_scp_idx) = ML_AT_IDX(SCP_ATTR_IDX(curr_scp_idx));
03194 
03195    TRACE (Func_Exit, "compress_tbls", NULL);
03196 
03197    return;
03198 
03199 }   /* compress_tbls */
03200 
03201 /******************************************************************************\
03202 |*                        *|
03203 |* Description:                     *|
03204 |*                        *|
03205 |* Input parameters:                    *|
03206 |*  NONE                      *|
03207 |*                        *|
03208 |* Output parameters:                   *|
03209 |*  NONE                      *|
03210 |*                        *|
03211 |* Returns:                     *|
03212 |*  NOTHING                     *|
03213 |*                        *|
03214 \******************************************************************************/
03215 static  void  update_idxs_in_attr_entry(int start_idx,
03216           int end_idx)
03217 {
03218    int    at_idx;
03219 
03220 
03221    TRACE (Func_Entry, "update_idxs_in_attr_entry", NULL);
03222 
03223    for (at_idx  = start_idx; at_idx <= end_idx; at_idx++) {
03224 
03225    if (!AT_IGNORE_ATTR_LINK(at_idx)) {
03226        AT_ATTR_LINK(at_idx) = ML_AT_IDX(AT_ATTR_LINK(at_idx));
03227    }
03228 
03229    AT_NAME_IDX(at_idx)    = ML_NP_IDX(AT_NAME_IDX(at_idx));
03230    AT_ORIG_NAME_IDX(at_idx) = ML_NP_IDX(AT_ORIG_NAME_IDX(at_idx));
03231    AT_MODULE_IDX(at_idx)  = ML_AT_IDX(AT_MODULE_IDX(at_idx));
03232 
03233    switch (AT_OBJ_CLASS(at_idx)) {
03234    case Data_Obj:
03235       ATD_ARRAY_IDX(at_idx)    = ML_BD_IDX(ATD_ARRAY_IDX(at_idx));
03236       ATD_DISTRIBUTION_IDX(at_idx) = ML_BD_IDX(ATD_DISTRIBUTION_IDX(at_idx));
03237       ATD_STOR_BLK_IDX(at_idx)     = ML_SB_IDX(ATD_STOR_BLK_IDX(at_idx));
03238       ATD_RESHAPE_ARRAY_IDX(at_idx)= ML_BD_IDX(ATD_RESHAPE_ARRAY_IDX(at_idx));
03239 
03240 # if defined(_F_MINUS_MINUS)
03241       ATD_PE_ARRAY_IDX(at_idx)     = ML_BD_IDX(ATD_PE_ARRAY_IDX(at_idx));
03242 # endif
03243 
03244       switch (ATD_CLASS(at_idx)) {
03245       case Function_Result:
03246 
03247          if (ATD_OFFSET_ASSIGNED(at_idx)) {
03248 
03249             switch (ATD_OFFSET_FLD(at_idx)) {
03250             case AT_Tbl_Idx:
03251                ATD_OFFSET_IDX(at_idx) = ML_AT_IDX(ATD_OFFSET_IDX(at_idx));
03252                break;
03253 
03254             case CN_Tbl_Idx:
03255                ATD_OFFSET_IDX(at_idx) = ML_CN_IDX(ATD_OFFSET_IDX(at_idx));
03256                break;
03257 
03258             case IR_Tbl_Idx:
03259                ATD_OFFSET_IDX(at_idx) = ML_IR_IDX(ATD_OFFSET_IDX(at_idx));
03260                break;
03261 
03262             case IL_Tbl_Idx:
03263                ATD_OFFSET_IDX(at_idx) = ML_IL_IDX(ATD_OFFSET_IDX(at_idx));
03264                break;
03265             }
03266          }
03267 
03268          ATD_TYPE_IDX(at_idx) = ML_TYP_IDX(ATD_TYPE_IDX(at_idx));
03269          ATD_FUNC_IDX(at_idx) = ML_AT_IDX(ATD_FUNC_IDX(at_idx));
03270          break;
03271 
03272 
03273       case Constant:
03274 
03275          ATD_TYPE_IDX(at_idx) = ML_TYP_IDX(ATD_TYPE_IDX(at_idx));
03276 
03277          switch (ATD_FLD(at_idx)) {
03278          case AT_Tbl_Idx:
03279             ATD_CONST_IDX(at_idx) = ML_AT_IDX(ATD_CONST_IDX(at_idx));
03280             break;
03281  
03282          default:
03283             ATD_CONST_IDX(at_idx) = ML_CN_IDX(ATD_CONST_IDX(at_idx));
03284             break;
03285          }
03286          break;
03287 
03288 
03289       case CRI__Pointee:
03290          ATD_TYPE_IDX(at_idx) = ML_TYP_IDX(ATD_TYPE_IDX(at_idx));
03291          ATD_PTR_IDX(at_idx)  = ML_AT_IDX(ATD_PTR_IDX(at_idx));
03292          break;
03293 
03294       case Compiler_Tmp:
03295 
03296          ATD_NEXT_MEMBER_IDX(at_idx)  = ML_AT_IDX(ATD_NEXT_MEMBER_IDX(at_idx));
03297          ATD_DEFINING_ATTR_IDX(at_idx)=ML_AT_IDX(ATD_DEFINING_ATTR_IDX(at_idx));
03298 
03299          if (ATD_AUTOMATIC(at_idx)) {
03300             ATD_AUTO_BASE_IDX(at_idx) = ML_AT_IDX(ATD_AUTO_BASE_IDX(at_idx));
03301          }
03302          else if (ATD_OFFSET_ASSIGNED(at_idx)) {
03303 
03304             switch (ATD_OFFSET_FLD(at_idx)) {
03305             case AT_Tbl_Idx:
03306                ATD_OFFSET_IDX(at_idx) = ML_AT_IDX(ATD_OFFSET_IDX(at_idx));
03307                break;
03308 
03309             case CN_Tbl_Idx:
03310                ATD_OFFSET_IDX(at_idx) = ML_CN_IDX(ATD_OFFSET_IDX(at_idx));
03311                break;
03312 
03313             case IR_Tbl_Idx:
03314                ATD_OFFSET_IDX(at_idx) = ML_IR_IDX(ATD_OFFSET_IDX(at_idx));
03315                break;
03316 
03317             case IL_Tbl_Idx:
03318                ATD_OFFSET_IDX(at_idx) = ML_IL_IDX(ATD_OFFSET_IDX(at_idx));
03319                break;
03320             }
03321          }
03322 
03323          ATD_TYPE_IDX(at_idx) = ML_TYP_IDX(ATD_TYPE_IDX(at_idx));
03324 
03325          switch (ATD_FLD(at_idx)) {
03326          case CN_Tbl_Idx:
03327             ATD_TMP_IDX(at_idx)   = ML_CN_IDX(ATD_TMP_IDX(at_idx));
03328             break;
03329 
03330          case AT_Tbl_Idx:
03331             ATD_TMP_IDX(at_idx)   = ML_AT_IDX(ATD_TMP_IDX(at_idx));
03332             break;
03333 
03334          case IR_Tbl_Idx:
03335             ATD_TMP_IDX(at_idx)   = ML_IR_IDX(ATD_TMP_IDX(at_idx));
03336             break;
03337 
03338          case IL_Tbl_Idx:
03339             ATD_TMP_IDX(at_idx)   = ML_IL_IDX(ATD_TMP_IDX(at_idx));
03340             break;
03341          }
03342          break;
03343 
03344 
03345       case Dummy_Argument:
03346 
03347          if (!ATD_INTRIN_DARG(at_idx)) {
03348             ATD_TYPE_IDX(at_idx)  = ML_TYP_IDX(ATD_TYPE_IDX(at_idx));
03349          }
03350          break;
03351 
03352 
03353       case Struct_Component:
03354 
03355          switch (ATD_OFFSET_FLD(at_idx)) {
03356          case AT_Tbl_Idx:
03357             ATD_CPNT_OFFSET_IDX(at_idx) =ML_AT_IDX(ATD_CPNT_OFFSET_IDX(at_idx));
03358             break;
03359 
03360          case CN_Tbl_Idx:
03361             ATD_CPNT_OFFSET_IDX(at_idx) =ML_CN_IDX(ATD_CPNT_OFFSET_IDX(at_idx));
03362             break;
03363 
03364          case IR_Tbl_Idx:
03365             ATD_CPNT_OFFSET_IDX(at_idx) =ML_IR_IDX(ATD_CPNT_OFFSET_IDX(at_idx));
03366             break;
03367 
03368          case IL_Tbl_Idx:
03369             ATD_CPNT_OFFSET_IDX(at_idx) =ML_IL_IDX(ATD_CPNT_OFFSET_IDX(at_idx));
03370             break;
03371          }
03372 
03373          switch (ATD_FLD(at_idx)) {
03374          case AT_Tbl_Idx:
03375             ATD_CPNT_INIT_IDX(at_idx) = ML_AT_IDX(ATD_CPNT_INIT_IDX(at_idx));
03376             break;
03377 
03378          case CN_Tbl_Idx:
03379             ATD_CPNT_INIT_IDX(at_idx) = ML_CN_IDX(ATD_CPNT_INIT_IDX(at_idx));
03380             break;
03381 
03382          case IR_Tbl_Idx:
03383             ATD_CPNT_INIT_IDX(at_idx) = ML_IR_IDX(ATD_CPNT_INIT_IDX(at_idx));
03384             break;
03385 
03386          case IL_Tbl_Idx:
03387             ATD_CPNT_INIT_IDX(at_idx) = ML_IL_IDX(ATD_CPNT_INIT_IDX(at_idx));
03388             break;
03389          }
03390          ATD_TYPE_IDX(at_idx)       = ML_TYP_IDX(ATD_TYPE_IDX(at_idx));
03391          ATD_DERIVED_TYPE_IDX(at_idx) = ML_AT_IDX(ATD_DERIVED_TYPE_IDX(at_idx));
03392          break;
03393 
03394 
03395       case Variable:
03396 
03397          switch (ATD_FLD(at_idx)) {
03398          case AT_Tbl_Idx:
03399             ATD_VARIABLE_TMP_IDX(at_idx) =
03400                          ML_AT_IDX(ATD_VARIABLE_TMP_IDX(at_idx));
03401             break;
03402 
03403          case IL_Tbl_Idx:
03404             ATD_VARIABLE_TMP_IDX(at_idx) =
03405                          ML_IL_IDX(ATD_VARIABLE_TMP_IDX(at_idx));
03406             break;
03407          }
03408 
03409          ATD_ASSIGN_TMP_IDX(at_idx)   = ML_AT_IDX(ATD_ASSIGN_TMP_IDX(at_idx));
03410          ATD_NEXT_MEMBER_IDX(at_idx)  = ML_AT_IDX(ATD_NEXT_MEMBER_IDX(at_idx));
03411 
03412          if (ATD_AUTOMATIC(at_idx)) {
03413             ATD_AUTO_BASE_IDX(at_idx) = ML_AT_IDX(ATD_AUTO_BASE_IDX(at_idx));
03414          }
03415          else if (ATD_OFFSET_ASSIGNED(at_idx)) {
03416 
03417             switch (ATD_OFFSET_FLD(at_idx)) {
03418             case AT_Tbl_Idx:
03419                ATD_OFFSET_IDX(at_idx) = ML_AT_IDX(ATD_OFFSET_IDX(at_idx));
03420                break;
03421 
03422             case CN_Tbl_Idx:
03423                ATD_OFFSET_IDX(at_idx) = ML_CN_IDX(ATD_OFFSET_IDX(at_idx));
03424                break;
03425 
03426             case IR_Tbl_Idx:
03427                ATD_OFFSET_IDX(at_idx) = ML_IR_IDX(ATD_OFFSET_IDX(at_idx));
03428                break;
03429 
03430             case IL_Tbl_Idx:
03431                ATD_OFFSET_IDX(at_idx) = ML_IL_IDX(ATD_OFFSET_IDX(at_idx));
03432                break;
03433             }
03434          }
03435 
03436          /* Intentional fall through */
03437 
03438       default:
03439          ATD_TYPE_IDX(at_idx) = ML_TYP_IDX(ATD_TYPE_IDX(at_idx));
03440          break;
03441 
03442       }  /* End switch */
03443       break;
03444 
03445    case Pgm_Unit:
03446 
03447       if (ATP_PGM_UNIT(at_idx) == Module) {
03448          ATP_MOD_PATH_IDX(at_idx) = ML_NP_IDX(ATP_MOD_PATH_IDX(at_idx));
03449       }
03450       else {
03451          ATP_RSLT_IDX(at_idx) = ML_AT_IDX(ATP_RSLT_IDX(at_idx));
03452          ATP_FIRST_IDX(at_idx)  = ML_SN_IDX(ATP_FIRST_IDX(at_idx));
03453 
03454          if (ATP_PROC(at_idx) != Intrin_Proc && ATP_PROC(at_idx) != Dummy_Proc){
03455             ATP_FIRST_SH_IDX(at_idx)= ML_SH_IDX(ATP_FIRST_SH_IDX(at_idx));
03456             ATP_PARENT_IDX(at_idx)  = ML_AT_IDX(ATP_PARENT_IDX(at_idx));
03457          }
03458       }
03459 
03460       ATP_EXT_NAME_IDX(at_idx)  = ML_NP_IDX(ATP_EXT_NAME_IDX(at_idx));
03461       break;
03462 
03463    case Label:
03464 
03465       ATL_NEXT_ASG_LBL_IDX(at_idx) = ML_AT_IDX(ATL_NEXT_ASG_LBL_IDX(at_idx));
03466 
03467       if (AT_DEFINED(at_idx)) {
03468          ATL_DEF_STMT_IDX(at_idx)  = ML_SH_IDX(ATL_DEF_STMT_IDX(at_idx));
03469       }
03470 
03471       if (ATL_CLASS(at_idx) == Lbl_Format) {
03472          ATL_PP_FORMAT_TMP(at_idx) = ML_AT_IDX(ATL_PP_FORMAT_TMP(at_idx));
03473          ATL_FORMAT_TMP(at_idx)    = ML_AT_IDX(ATL_FORMAT_TMP(at_idx));
03474       }
03475       else {
03476          ATL_DIRECTIVE_LIST(at_idx)= ML_IL_IDX(ATL_DIRECTIVE_LIST(at_idx));
03477 
03478          if (ATL_CLASS(at_idx) == Lbl_User) {
03479             ATL_BLK_STMT_IDX(at_idx)  = ML_SH_IDX(ATL_BLK_STMT_IDX(at_idx));
03480          }
03481       }
03482       break;
03483 
03484 
03485    case Derived_Type:
03486 
03487       if (ATT_STRUCT_BIT_LEN_IDX(at_idx) != NULL_IDX) {
03488 
03489          switch (ATT_STRUCT_BIT_LEN_FLD(at_idx)) {
03490          case CN_Tbl_Idx:
03491             ATT_STRUCT_BIT_LEN_IDX(at_idx) = 
03492                                  ML_CN_IDX(ATT_STRUCT_BIT_LEN_IDX(at_idx));
03493             break;
03494 
03495          case AT_Tbl_Idx:
03496             ATT_STRUCT_BIT_LEN_IDX(at_idx) = 
03497                                  ML_AT_IDX(ATT_STRUCT_BIT_LEN_IDX(at_idx));
03498             break;
03499 
03500          case IL_Tbl_Idx:
03501             ATT_STRUCT_BIT_LEN_IDX(at_idx) = 
03502                                  ML_IL_IDX(ATT_STRUCT_BIT_LEN_IDX(at_idx));
03503             break;
03504 
03505          case IR_Tbl_Idx:
03506             ATT_STRUCT_BIT_LEN_IDX(at_idx) = 
03507                                  ML_IR_IDX(ATT_STRUCT_BIT_LEN_IDX(at_idx));
03508             break;
03509 
03510          case NO_Tbl_Idx:
03511             ATT_STRUCT_BIT_LEN_FLD(at_idx) = CN_Tbl_Idx;
03512             ATT_STRUCT_BIT_LEN_IDX(at_idx) = 
03513                                  ML_CN_IDX(ATT_STRUCT_BIT_LEN_IDX(at_idx));
03514             break;
03515          }
03516       }
03517 
03518       ATT_FIRST_CPNT_IDX(at_idx)  = ML_SN_IDX(ATT_FIRST_CPNT_IDX(at_idx));
03519       break;
03520 
03521    case Interface:
03522 
03523       ATI_FIRST_SPECIFIC_IDX(at_idx) =ML_SN_IDX(ATI_FIRST_SPECIFIC_IDX(at_idx));
03524       ATI_PROC_IDX(at_idx)    = ML_AT_IDX(ATI_PROC_IDX(at_idx));
03525       ATD_TYPE_IDX(at_idx)    = ML_TYP_IDX(ATD_TYPE_IDX(at_idx));
03526       break;
03527 
03528    case Namelist_Grp:
03529 
03530       ATN_FIRST_NAMELIST_IDX(at_idx) =ML_SN_IDX(ATN_FIRST_NAMELIST_IDX(at_idx));
03531       ATN_LAST_NAMELIST_IDX(at_idx)  = ML_SN_IDX(ATN_LAST_NAMELIST_IDX(at_idx));
03532 
03533       if (ATN_NAMELIST_DESC(at_idx) != NULL_IDX) {
03534          ATN_NAMELIST_DESC(at_idx)   = ML_AT_IDX(ATN_NAMELIST_DESC(at_idx));
03535       }
03536       break;
03537 
03538    case Stmt_Func:
03539 
03540       ATD_TYPE_IDX(at_idx) = ML_TYP_IDX(ATD_TYPE_IDX(at_idx));
03541       ATP_FIRST_IDX(at_idx) = ML_SN_IDX(ATP_FIRST_IDX(at_idx));
03542 
03543       switch (ATS_SF_FLD(at_idx)) {
03544       case CN_Tbl_Idx:
03545          ATS_SF_IDX(at_idx) = ML_CN_IDX(ATS_SF_IDX(at_idx));
03546          break;
03547 
03548       case AT_Tbl_Idx:
03549          ATS_SF_IDX(at_idx) = ML_AT_IDX(ATS_SF_IDX(at_idx));
03550          break;
03551 
03552       case IR_Tbl_Idx:
03553          ATS_SF_IDX(at_idx) = ML_IR_IDX(ATS_SF_IDX(at_idx));
03554          break;
03555 
03556       case IL_Tbl_Idx:
03557          ATS_SF_IDX(at_idx) = ML_IL_IDX(ATS_SF_IDX(at_idx));
03558          break;
03559       }
03560       break;
03561    }  /* End switch */
03562    }  /* End For */
03563 
03564    TRACE (Func_Exit, "update_idxs_in_attr_entry", NULL);
03565 
03566    return;
03567 
03568 }   /* update_idxs_in_attr_entry */
03569 
03570 /******************************************************************************\
03571 |*                        *|
03572 |* Description:                     *|
03573 |*                        *|
03574 |* Input parameters:                    *|
03575 |*  NONE                      *|
03576 |*                        *|
03577 |* Output parameters:                   *|
03578 |*  NONE                      *|
03579 |*                        *|
03580 |* Returns:                     *|
03581 |*  NOTHING                     *|
03582 |*                        *|
03583 \******************************************************************************/
03584 extern  void  output_mod_info_file(void)
03585 
03586 {
03587    int     al_idx;
03588    int     idx;
03589    int     module_attr_idx;
03590    FILE   *mod_file_ptr   = NULL;
03591    long   *mod_idx;
03592    int     name_idx;
03593    int     sb_idx;
03594    int     wd_len;
03595 
03596 
03597    TRACE (Func_Entry, "output_mod_info_file", NULL);
03598 
03599    module_attr_idx  = SCP_ATTR_IDX(curr_scp_idx);
03600 
03601    if (dump_flags.preinline) {  /* Append these files */
03602       mod_file_ptr = fopen(FP_NAME_PTR(SCP_FILE_PATH_IDX(curr_scp_idx)), "ab");
03603    }
03604    else if (on_off_flags.module_to_mod) {
03605       mod_file_ptr = fopen(FP_NAME_PTR(SCP_FILE_PATH_IDX(curr_scp_idx)), "wb");
03606    }
03607    else {
03608 
03609 #     if defined(_MODULE_TO_DOT_M)      /* These are all appended */
03610          mod_file_ptr = fopen(FP_NAME_PTR(SCP_FILE_PATH_IDX(curr_scp_idx)),
03611                               "ab");
03612 #     else
03613          mod_file_ptr = fopen(FP_NAME_PTR(SCP_FILE_PATH_IDX(curr_scp_idx)),
03614                               "wb");
03615 #     endif
03616    }
03617 
03618 #ifdef KEY /* Bug 3474 */
03619    Uint save_file_idx = SCP_FILE_PATH_IDX(curr_scp_idx);
03620 #endif /* KEY Bug 3474 */
03621    SCP_FILE_PATH_IDX(curr_scp_idx) = NULL_IDX;
03622 
03623    if (ATP_PGM_UNIT(module_attr_idx) == Module) {
03624       ATP_MOD_PATH_IDX(module_attr_idx) = NULL_IDX;
03625       ATP_MOD_PATH_LEN(module_attr_idx) = 0;
03626    }
03627 
03628    if (mod_file_ptr == NULL) {
03629 #ifdef KEY /* Bug 3474 */
03630       PRINTMSG(AT_DEF_LINE(module_attr_idx), 1665, Error,
03631                AT_DEF_COLUMN(module_attr_idx),
03632                AT_OBJ_NAME_PTR(module_attr_idx),
03633                FP_NAME_PTR(save_file_idx),
03634          strerror(errno));
03635 #else
03636       PRINTMSG(AT_DEF_LINE(module_attr_idx), 1665, Error,
03637                AT_DEF_COLUMN(module_attr_idx),
03638                AT_OBJ_NAME_PTR(module_attr_idx),
03639                FP_NAME_PTR(SCP_FILE_PATH_IDX(curr_scp_idx)));
03640 #endif /* KEY Bug 3474 */
03641       goto EXIT;
03642    }
03643 
03644    MD_PDT_HDR_TYPE    = COMPILER_INFO_TABLE_TYPE;
03645    MD_VERSION_NUM   = MD_CURRENT_VERSION;
03646    MD_TARGET      = target_os;
03647    MD_ENABLE_DOUBLE_PRECISION = on_off_flags.enable_double_precision;
03648    MD_DEFAULT_INTEGER_TYPE  = INTEGER_DEFAULT_TYPE;
03649    MD_HAS_ERRORS    = (num_prog_unit_errors > 0);
03650    MD_DALIGN      = cmd_line_flags.dalign;
03651    MD_CF77TYPES     = cmd_line_flags.s_cf77types;
03652    MD_DEFAULT32     = cmd_line_flags.s_default32;
03653    MD_DEFAULT64     = cmd_line_flags.s_default64;
03654    MD_FLOAT64     = cmd_line_flags.s_float64;
03655 
03656    MD_NEW_CONST_TBL   = TRUE;
03657 
03658    /* At this point, if we're outputing for inlining we need to check for   */
03659    /* alternate entries.  If they exist, an md_header_descriptor is written */
03660    /* out for each.  The actual tables for the alternate entry follow in    */
03661    /* main entry and can can be found by reading the 026 table until the    */
03662    /* next main entry is found.                                             */
03663 
03664    if (ATP_MAY_INLINE(SCP_ATTR_IDX(MAIN_SCP_IDX)) && 
03665        SCP_ENTRY_IDX(MAIN_SCP_IDX) != NULL_IDX) {
03666       al_idx    = SCP_ENTRY_IDX(MAIN_SCP_IDX);
03667       MD_ALTERNATE_ENTRY= TRUE;
03668       MD_PDT_HDR_LEN  = sizeof(mit_header_type)/TARGET_BYTES_PER_WORD;
03669 
03670 # if defined(_HOST32) && defined(_TARGET64)
03671 
03672       /* PDT size must be in 64 bit increment sizes. */
03673 
03674       MD_PDT_HDR_LEN = (MD_PDT_HDR_LEN + 1) / 2;
03675 # endif
03676 
03677       while (al_idx != NULL_IDX) {
03678          name_idx = AT_NAME_IDX(AL_ATTR_IDX(al_idx));
03679          MD_NAME_LEN  = AT_NAME_LEN(AL_ATTR_IDX(al_idx));
03680          wd_len   = WORD_LEN(MD_NAME_LEN);
03681          mod_idx  = MD_NAME_LONG;
03682 
03683          for (idx = 0; idx < wd_len; idx++) {
03684             *mod_idx  = name_pool[name_idx].name_long;
03685             name_idx++;
03686             mod_idx++;
03687          }
03688 
03689          fwrite(&mit_header, sizeof(mit_header_type), 1, mod_file_ptr);
03690          al_idx   = AL_NEXT_IDX(al_idx);
03691       }
03692 
03693       /* Reset the original name in the header. */
03694 
03695       name_idx    = AT_NAME_IDX(module_attr_idx);
03696       MD_NAME_LEN = AT_NAME_LEN(module_attr_idx);
03697       wd_len    = WORD_LEN(MD_NAME_LEN);
03698       mod_idx   = MD_NAME_LONG;
03699 
03700       for (idx = 0; idx < wd_len; idx++) {
03701          *mod_idx = name_pool[name_idx].name_long;
03702          name_idx++;
03703          mod_idx++;
03704       }
03705    }
03706 
03707    MD_ALTERNATE_ENTRY   = FALSE;
03708 
03709    if (dump_flags.preinline && num_prog_unit_errors > 0) {
03710 
03711       /* Do not write out any tables.  Just a header with error set. */
03712 
03713       attr_tbl_idx  = NULL_IDX;
03714       attr_aux_tbl_idx  = NULL_IDX;
03715       bounds_tbl_idx  = NULL_IDX;
03716       const_tbl_idx = NULL_IDX;
03717       const_pool_idx  = NULL_IDX;
03718       ir_tbl_idx  = NULL_IDX;
03719       ir_list_tbl_idx = NULL_IDX;
03720       loc_name_tbl_idx  = NULL_IDX;
03721       name_pool_idx = NULL_IDX;
03722       sec_name_tbl_idx  = NULL_IDX;
03723       stor_blk_tbl_idx  = NULL_IDX;
03724       type_tbl_idx  = NULL_IDX;
03725       sh_tbl_idx  = NULL_IDX;
03726    }
03727    else {
03728 
03729       /* Do not write out any tables.  Just the mod header. */
03730 
03731       /* In error situations, module_attr_idx may not be in the local name    */
03732       /* table so it has to be specifically included for output.  This module */
03733       /* output is only used to finish this compilation because of errors.    */
03734 
03735       ML_AT_IDX(module_attr_idx)  = module_attr_idx;
03736 
03737       /* assign_new_idxs needs to have ML_AT_IDX(0) = NULL_IDX, ML_BD_IDX(0)  */
03738       /* = NULL_IDX -  ect..  The zeroth entry of the mod link table contains */
03739       /* the index to start compression at for each table.  When compressing  */
03740       /* tables for module output, everything gets compressed, so the zeroth  */
03741       /* entry should be all zeros to signify that everything gets compressed.*/
03742       /* The zeroth entry is set to all NULL_IDX's when the table is allocated*/
03743 
03744       /* Resolve duplicate attr idxs in mod link table.         */
03745 
03746       save_const_pool_idx = NULL_IDX;
03747       save_const_tbl_idx  = NULL_IDX;
03748 
03749       /* If we're not creating a preinline file and if MODINLINE is not on    */
03750       /* for this module, then we will not be writing out the SH table, so    */
03751       /* set ML_SH_IDX equal to sh_tbl_idx, so we do nothing in assign_new..  */
03752       /* Then clear sh_tbl_idx and ML_SH_IDX so we do nothing in compress_..  */
03753 
03754       if (!ATP_MAY_INLINE(SCP_ATTR_IDX(MAIN_SCP_IDX))) {
03755          ML_SH_IDX(0) = sh_tbl_idx;  /* SH table not needed.  */
03756          assign_new_idxs(TRUE);
03757          ML_SH_IDX(0) = NULL_IDX;
03758          sh_tbl_idx = NULL_IDX;
03759       }
03760       else {
03761          assign_new_idxs(TRUE);
03762       }
03763 
03764       /* Do table compression, but do not update the attribute entries in the */
03765       /* attr_list_tbl.  Stop updating from happening, by passing the last    */
03766       /* used index in attr_list_tbl.  compress_tbls goes through the attr    */
03767       /* list table starting at the entry past the entry passed in.           */
03768 
03769       num_module_derived_types  = 0;  /* Not used - clear to prevent overflow */
03770       count_derived_types = FALSE;
03771       compress_tbls(attr_list_tbl_idx, FALSE); 
03772 
03773       /* module_attr_idx may have been moved during compression. */
03774 
03775       module_attr_idx   = ML_AT_IDX(module_attr_idx);
03776 
03777       /* Certain flds in the attr table need to be cleared, such as line      */
03778       /* numbers cif ids, the referenced flag ect..                           */
03779       /* Also, if alternate entries, reset ATP_FIRST_SH_IDX to the main       */
03780       /* entry's ATP_FIRST                                                    */
03781 
03782       set_attr_flds_for_output();
03783 
03784       /* Any bounds table free list is destroyed. */
03785 
03786       BD_NEXT_FREE_NTRY(BD_FREE_LIST_IDX) = NULL_IDX;
03787 
03788       /* Set ATP_SCP_ALIVE for the module attr, so that it can be recognized  */
03789       /* when the module is read in again.  ATP_SCP_ALIVE is turned off for   */
03790       /* everything after the semantic pass in s_driver.                      */
03791 
03792       ATP_SCP_ALIVE(module_attr_idx)  = TRUE;
03793 
03794       for (sb_idx = 1; sb_idx <= stor_blk_tbl_idx; sb_idx++) {
03795          SB_CIF_SYMBOL_ID(sb_idx)    = NULL_IDX;
03796       }
03797    }
03798 
03799    /* Note on table sizes.  tbl_idx is the last used item in the table.       */
03800    /* The 0th entry should not be written out to the module info table,       */
03801    /* so using tbl_idx as the size of the table to write out is correct.      */
03802    /* That is also why when the tables are written they start at [1].         */
03803 
03804    MD_TBL_TYPE(Attr_Tbl)  = Attr_Tbl;
03805    MD_NUM_ENTRIES(Attr_Tbl) = attr_tbl_idx;
03806    MD_TBL_TYPE(Bounds_Tbl)  = Bounds_Tbl;
03807    MD_NUM_ENTRIES(Bounds_Tbl) = bounds_tbl_idx;
03808    MD_TBL_TYPE(Const_Tbl) = Const_Tbl;
03809    MD_NUM_ENTRIES(Const_Tbl)  = const_tbl_idx;
03810    MD_TBL_TYPE(Const_Pool)  = Const_Pool;
03811    MD_NUM_ENTRIES(Const_Pool) = const_pool_idx;
03812    MD_TBL_TYPE(Ir_Tbl)    = Ir_Tbl;
03813    MD_NUM_ENTRIES(Ir_Tbl) = ir_tbl_idx;
03814    MD_TBL_TYPE(Ir_List_Tbl) = Ir_List_Tbl;
03815    MD_NUM_ENTRIES(Ir_List_Tbl)  = ir_list_tbl_idx;
03816    MD_TBL_TYPE(Loc_Name_Tbl)  = Loc_Name_Tbl;
03817    MD_NUM_ENTRIES(Loc_Name_Tbl) = loc_name_tbl_idx;
03818    MD_TBL_TYPE(Name_Pool) = Name_Pool;
03819    MD_NUM_ENTRIES(Name_Pool)  = name_pool_idx;
03820    MD_TBL_TYPE(Sec_Name_Tbl)  = Sec_Name_Tbl;
03821    MD_NUM_ENTRIES(Sec_Name_Tbl) = sec_name_tbl_idx;
03822    MD_TBL_TYPE(Stor_Blk_Tbl)  = Stor_Blk_Tbl;
03823    MD_NUM_ENTRIES(Stor_Blk_Tbl) = stor_blk_tbl_idx;
03824    MD_TBL_TYPE(Type_Tbl)  = Type_Tbl;
03825    MD_NUM_ENTRIES(Type_Tbl) = type_tbl_idx;
03826    MD_TBL_TYPE(Sh_Tbl)    = Sh_Tbl;
03827    MD_NUM_ENTRIES(Sh_Tbl) = sh_tbl_idx;
03828 
03829    MD_PDT_HDR_LEN   = (attr_tbl_idx * NUM_AT_WDS) +
03830                 (bounds_tbl_idx * NUM_BD_WDS) +
03831                 (const_tbl_idx * NUM_CN_WDS) +
03832                 (const_pool_idx * NUM_CP_WDS) +
03833                 (ir_list_tbl_idx * NUM_IL_WDS) +
03834                 (ir_tbl_idx * NUM_IR_WDS) +
03835                 (loc_name_tbl_idx * NUM_LN_WDS) +
03836                 (name_pool_idx * NUM_NP_WDS) +
03837                 (sec_name_tbl_idx * NUM_SN_WDS) +
03838                 (stor_blk_tbl_idx * NUM_SB_WDS) +
03839                 (type_tbl_idx * NUM_TYP_WDS) +
03840                 (sh_tbl_idx * NUM_SH_WDS) +
03841                 (MD_TBL_BYTE_SIZE/TARGET_BYTES_PER_WORD) +
03842                 ((sizeof(mit_descriptor_type) / 
03843                                       TARGET_BYTES_PER_WORD) * Num_Of_Tbls);
03844 
03845 /* KAY */
03846 
03847    /* PDT size must be in 64 bit increment sizes. */
03848 
03849 # if defined(_HOST32) && defined(_TARGET64)
03850    MD_PDT_HDR_LEN = (MD_PDT_HDR_LEN + 1) / 2;
03851 # endif
03852 
03853    fwrite(&mit_header, sizeof(mit_header_type), 1, mod_file_ptr);
03854 
03855    fwrite(&mit_descriptor[1], 
03856           sizeof(mit_descriptor_type),
03857           Num_Of_Tbls,
03858           mod_file_ptr);
03859 
03860    OUTPUT_TBL_TO_MODULE(mod_file_ptr, module_attr_idx, name_pool);
03861    OUTPUT_TBL_TO_MODULE(mod_file_ptr, module_attr_idx, loc_name_tbl);
03862    OUTPUT_TBL_TO_MODULE(mod_file_ptr, module_attr_idx, attr_tbl);
03863    OUTPUT_TBL_TO_MODULE(mod_file_ptr, module_attr_idx, bounds_tbl);
03864    OUTPUT_TBL_TO_MODULE(mod_file_ptr, module_attr_idx, const_tbl);
03865    OUTPUT_TBL_TO_MODULE(mod_file_ptr, module_attr_idx, const_pool);
03866    OUTPUT_TBL_TO_MODULE(mod_file_ptr, module_attr_idx, sec_name_tbl);
03867    OUTPUT_TBL_TO_MODULE(mod_file_ptr, module_attr_idx, stor_blk_tbl);
03868    OUTPUT_TBL_TO_MODULE(mod_file_ptr, module_attr_idx, type_tbl);
03869    OUTPUT_TBL_TO_MODULE(mod_file_ptr, module_attr_idx, ir_tbl);
03870    OUTPUT_TBL_TO_MODULE(mod_file_ptr, module_attr_idx, ir_list_tbl);
03871    OUTPUT_TBL_TO_MODULE(mod_file_ptr, module_attr_idx, sh_tbl);
03872 
03873    fflush(mod_file_ptr);
03874    fclose(mod_file_ptr);
03875 
03876    const_tbl_idx++;  /* Adjust so it is set to next available index */
03877 
03878 EXIT:
03879 
03880    TBL_FREE(mod_link_tbl);
03881 
03882    TRACE (Func_Exit, "output_mod_info_file", NULL);
03883 
03884    return;
03885 
03886 }  /* output_mod_info_file */
03887 
03888 #ifdef KEY /* Bug 5089 */
03889 /*
03890  * module_attr_idx  AT_Tbl_Idx for a module
03891  * return   TRUE if that module is intrinsic ieee_features,
03892  *      ieee_exceptions, or ieee_arithmetic
03893  */
03894 static boolean
03895 is_ieee(int module_attr_idx) {
03896   extern boolean LANG_IEEE_Save;
03897   return AT_IS_INTRIN(module_attr_idx) &&
03898     LANG_IEEE_Save &&
03899     0 == strncmp(AT_OBJ_NAME_PTR(module_attr_idx), "IEEE", 4);
03900 }
03901 #endif /* KEY Bug 5089 */
03902 /******************************************************************************\
03903 |*                        *|
03904 |* Description:                     *|
03905 |*                        *|
03906 |* Input parameters:                    *|
03907 |*  NONE                      *|
03908 |*                        *|
03909 |* Output parameters:                   *|
03910 |*  NONE                      *|
03911 |*                        *|
03912 |* Returns:                     *|
03913 |*  NOTHING                     *|
03914 |*                        *|
03915 \******************************************************************************/
03916 void  use_stmt_semantics(void)
03917         
03918 {
03919    int     al_idx;
03920    int     attr_idx;
03921    int     attr_list_free_list;
03922    int     bd_idx;
03923    int     host_attr_idx;
03924    int     host_name_idx;
03925    int     interface_list;
03926    int     ln_idx;  
03927    int     match;
03928    int     module_attr_idx;
03929    int     module_list_idx;
03930    int     name_idx;
03931    int     new_name_idx;
03932    int     new_sn_idx;
03933    int     save_attr_list_tbl_idx;
03934    int     srch_attr_idx;
03935    int     start_ln_idx;
03936    boolean   use_only;
03937    int     use_ir_idx;
03938 
03939 
03940    TRACE (Func_Entry, "use_stmt_semantics", NULL);
03941 
03942    /* global flag used to tell set_mod_link_tbl_for_attr */
03943    /* that it should check all attrs for duplicates.     */
03944    /* This refers to search_for_duplicate_attrs          */
03945 
03946    list_of_modules_in_module  = NULL_IDX;
03947    module_list_idx      = SCP_USED_MODULE_LIST(curr_scp_idx);
03948    attr_list_free_list    = AL_NEXT_IDX(NULL_IDX);
03949    interface_list   = NULL_IDX;
03950 
03951    keep_module_procs = (opt_flags.inline_lvl > Inline_Lvl_0) ||
03952                         ATP_MAY_INLINE(SCP_ATTR_IDX(MAIN_SCP_IDX));
03953 
03954    /* Find the last module on the list.  This is really the first module   */
03955    /* specified on a USE list.  This way we get the ordering correct, plus */
03956    /* since we are backing up the list and the list is extended at the     */
03957    /* bottom, we don't end up trying to process the newly added indirectly */
03958    /* referenced modules.  The list is extended in resolve_used_modules.   */
03959    /* All modules that are indirectly brought in during USE association    */
03960    /* are added to this list.  This helps get messages issued correctly    */
03961    /* and keeps CIF happy.  See resolve_used_modules for more details.     */
03962    /* All the modules specified on the USE statement are specifed on this  */
03963    /* list first, because these are the attr indexes we want to use.       */
03964 
03965    while (AL_NEXT_IDX(module_list_idx) != NULL_IDX) {
03966       module_list_idx = AL_NEXT_IDX(module_list_idx);
03967    }
03968 
03969    while (module_list_idx != NULL_IDX) {
03970       module_attr_idx     = AL_ATTR_IDX(module_list_idx);
03971       only_update_new_tbl_entries = TRUE;
03972 
03973       /* For next iteration */
03974 
03975       module_list_idx = AL_PREV_MODULE_IDX(module_list_idx); 
03976 
03977       if (ATP_IMPLICIT_USE_MODULE(module_attr_idx)) {
03978 
03979          /* Need to generate the Use_Opr - Have a curr_stmt_sh - use it */
03980 
03981         /* Generate IR for this USE statement.  Need to keep the attr so that */
03982         /* it can be passed thru the PDGCS interface during IR conversion.    */
03983         /* Do not need pass2 semantics for this statement.                    */
03984 
03985         NTR_IR_TBL(use_ir_idx);
03986         IR_OPR(use_ir_idx)    = Use_Opr;
03987         IR_TYPE_IDX(use_ir_idx)   = TYPELESS_DEFAULT_TYPE;
03988         IR_LINE_NUM(use_ir_idx)   = stmt_start_line;
03989         IR_COL_NUM(use_ir_idx)    = stmt_start_col;
03990         IR_IDX_L(use_ir_idx)    = module_attr_idx;
03991         IR_FLD_L(use_ir_idx)    = AT_Tbl_Idx;
03992         IR_LINE_NUM_L(use_ir_idx) = stmt_start_line;
03993         IR_COL_NUM_L(use_ir_idx)  = stmt_start_col;
03994 
03995         gen_sh(Before,
03996                Use_Stmt,
03997                stmt_start_line,
03998                stmt_start_col,
03999                FALSE,
04000                FALSE,
04001                TRUE); /* Compiler gen'd */
04002 
04003         SH_P2_SKIP_ME(SH_PREV_IDX(curr_stmt_sh_idx))  = TRUE;
04004         SH_IR_IDX(SH_PREV_IDX(curr_stmt_sh_idx))  = use_ir_idx;
04005       }
04006 
04007       if (on_off_flags.issue_ansi_messages ||
04008           GET_MESSAGE_TBL(message_warning_tbl, 953) ||
04009           GET_MESSAGE_TBL(message_error_tbl, 953)) {
04010 
04011          /* Non standard to let a module have the same name as a local */
04012          /* entity in a parent scope.  Don't issue if the entity in    */
04013          /* parent scope is a module.  This means we are using the     */
04014          /* module in several scopes and is legal and standard.        */
04015 
04016          srch_attr_idx = srch_host_sym_tbl(AT_OBJ_NAME_PTR(module_attr_idx),
04017                                            AT_NAME_LEN(module_attr_idx),
04018                                            &name_idx,
04019                                            FALSE);
04020 
04021          if (srch_attr_idx != NULL_IDX && 
04022              (AT_OBJ_CLASS(srch_attr_idx) != Pgm_Unit ||
04023               ATP_PGM_UNIT(srch_attr_idx) != Module)) {
04024             PRINTMSG(AT_DEF_LINE(module_attr_idx), 953, Ansi,
04025                      AT_DEF_COLUMN(module_attr_idx),
04026                      AT_OBJ_NAME_PTR(module_attr_idx));
04027          }
04028       }
04029 
04030       save_attr_list_tbl_idx  = attr_list_tbl_idx;
04031 
04032       /* Force all new attr list table entries to the end so we can */
04033       /* find the new ones for compression.                         */
04034 
04035       AL_NEXT_IDX(NULL_IDX) = NULL_IDX;
04036       use_only      = ATP_USE_TYPE(module_attr_idx) == Use_Only;
04037 
04038       if (!find_prog_unit_tbl(module_attr_idx)) {
04039 
04040          /* Couldn't find the module or bad reads */
04041 
04042          goto EXIT;
04043       }
04044 
04045 #ifdef KEY /* Bug 5089 */
04046       int intrinsic_module = AT_IS_INTRIN(module_attr_idx);
04047       /* F2003: Scope which accesses ieee_* intrinsic modules must save FPU
04048        * state on entry and restore it (ORing flags) on exit.
04049        * decl_semantics_driver() takes care of access by host association. */
04050       if (is_ieee(module_attr_idx)) {
04051   SCP_USES_IEEE(curr_scp_idx) = TRUE;
04052       }
04053 #endif /* KEY Bug 5089 */
04054 
04055       start_ln_idx  = loc_name_tbl_idx - MD_NUM_ENTRIES(Loc_Name_Tbl) + 1;
04056       attr_idx    = attr_tbl_idx - MD_NUM_ENTRIES(Attr_Tbl) + 1;
04057 
04058 # ifdef _DEBUG
04059       if (start_ln_idx <= 0) {
04060          PRINTMSG(1, 626, Internal, 0, "positive start_ln_idx",
04061                   "use_stmt_semantics");
04062       }
04063       if (attr_idx <= 0) {
04064          PRINTMSG(1, 626, Internal, 0, "positive attr_idx",
04065                   "use_stmt_semantics");
04066       }
04067 # endif
04068 
04069       if (ATP_USE_LIST(module_attr_idx) != NULL_IDX) {
04070          rename_only_semantics(module_attr_idx, use_only);
04071       }
04072 
04073       /* Go through all new entries in the local name table.  Decide which */
04074       /* ones to keep and which to toss.  This merges the new entries into */
04075       /* the old local name table as it goes through.  Since the new       */
04076       /* entries follow the old, as the old table grows the new table      */
04077       /* shrinks.  Both tables are in alphabetical order and we start at   */
04078       /* the top of the new table.  If we are keeping the new entry we     */
04079       /* move it up to its proper position in the old table.  We enter it  */
04080       /* by moving everything down in the old table after its proper       */
04081       /* position.  One entry of space has been left between the old and   */
04082       /* new tables to make sure that as the old table grows it does not   */
04083       /* write over the current entry being processed from the new table.  */
04084 
04085       ln_idx    = SCP_LN_FW_IDX(curr_scp_idx) + 1;
04086 
04087       for (new_name_idx = start_ln_idx;
04088            new_name_idx <= loc_name_tbl_idx; 
04089            new_name_idx++) {
04090 
04091          if (use_only) {
04092 
04093             /* This module is brought in with an ONLY.  Throw out       */
04094             /* everything that is not specified on the ONLY statement.  */
04095             /* If this is a renamed item from an ONLY list, LN_NEW_NAME */
04096             /* will be set, but LN_IN_ONLY_LIST will not be set, unless */
04097             /* the name itself is specified in the only list.           */
04098 
04099             if (!LN_IN_ONLY_LIST(new_name_idx) && 
04100                 !LN_NEW_NAME(new_name_idx)) {
04101                continue;
04102             }
04103 
04104             ML_LN_KEEP_ME(new_name_idx)   = TRUE;
04105             LN_IN_ONLY_LIST(new_name_idx) = FALSE;
04106             LN_NEW_NAME(new_name_idx)   = FALSE;
04107             LN_RENAMED(new_name_idx)    = FALSE;
04108          }
04109          else {  /* Possible renames */
04110 
04111             if (LN_RENAMED(new_name_idx)) {
04112                continue;   /* This has been renamed.  Throw out. */
04113             }
04114 
04115             ML_LN_KEEP_ME(new_name_idx) = TRUE;
04116             LN_NEW_NAME(new_name_idx) = FALSE;
04117          }
04118 
04119          attr_idx = LN_ATTR_IDX(new_name_idx);
04120 
04121 #ifdef KEY /* Bug 5089 */
04122          /* Look up the original name of this entity in the
04123     * intrinsic_module_table. If we find it, change the attr_tbl_entry
04124     * so that a call to it will be replaced by intrinsic code. */
04125          if (intrinsic_module && NULL_IDX != AT_ORIG_NAME_IDX(attr_idx)) {
04126      intrinsic_module_lookup(attr_idx);
04127    }
04128 #endif /* KEY Bug 5089 */
04129 
04130          /* Find the new entries position in the old local name table. */
04131 
04132          do {
04133 
04134             if (ln_idx >= SCP_LN_LW_IDX(curr_scp_idx)) {
04135                ln_idx = SCP_LN_LW_IDX(curr_scp_idx);
04136                match  = -1;
04137             }
04138             else {
04139                match = compare_names(LN_NAME_LONG(new_name_idx),
04140                                      LN_NAME_LEN(new_name_idx),
04141                                      LN_NAME_LONG(ln_idx),
04142                                      LN_NAME_LEN(ln_idx));
04143 
04144                if (match > 0) {
04145                   ln_idx++;
04146                } 
04147             } 
04148          } 
04149          while (match > 0);
04150 
04151          if (match == 0) {
04152             not_visible_semantics(attr_idx,          /* new attr index  */
04153                                   ln_idx,            /* Old name index  */
04154                                   module_attr_idx);
04155             AT_REFERENCED(AT_MODULE_IDX(attr_idx)) = Referenced;
04156          }
04157          else {
04158             (SCP_LN_LW_IDX(curr_scp_idx))++;
04159 
04160             NTR_NAME_IN_LN_TBL(ln_idx, new_name_idx);
04161 
04162             LN_DEF_LOC(new_name_idx)  = TRUE;
04163 
04164             if (!ML_AT_SEARCHED(attr_idx) && resolve_attr(attr_idx)) {
04165 
04166                /* If resolve attr is TRUE, we are not keeping the attr */
04167                /* entry, because the same object is already in this    */
04168                /* scope and we are going to use that attr entry.       */
04169 
04170                KEEP_ATTR(ML_AT_IDX(attr_idx));
04171             }
04172             else {
04173 
04174                /* If we are keeping this attr, set_mod_link_tbl_for_attr */
04175                /* will call resolve_attr for all the dependent attrs.    */
04176 
04177                AT_REFERENCED(AT_MODULE_IDX(attr_idx)) = Referenced;
04178 
04179                KEEP_ATTR(attr_idx);
04180 
04181                if (AT_OBJ_CLASS(attr_idx) == Interface &&
04182                    !AT_IS_INTRIN(attr_idx) &&
04183                    SCP_PARENT_IDX(curr_scp_idx) != NULL_IDX &&
04184                    !SCP_IS_INTERFACE(curr_scp_idx)) {
04185 
04186                   /* Add to the top of the interface list. */
04187 
04188                   /* The following code implements interp 99                */
04189                   /* If two or more generic interfaces that are accessible  */
04190                   /* in a scoping unit have the same name, ..., they are    */
04191                   /* interpreted as a single generic interface.             */
04192 
04193                   /* We actually do the host association after all the use  */
04194                   /* statements for this scope are processed.  If we don't  */
04195                   /* wait, we end up putting new scopes after the current   */
04196                   /* scopes.                                                */
04197 
04198                   NTR_ATTR_LIST_TBL(al_idx);
04199                   AL_ATTR_IDX(al_idx) = attr_idx;
04200                   AL_NEXT_IDX(al_idx) = interface_list;
04201                   interface_list  = al_idx;
04202                }
04203             }
04204          }
04205 
04206          if (AT_NAME_IDX(attr_idx) != AT_ORIG_NAME_IDX(attr_idx)) { /* Renamed*/
04207 
04208             if (AT_OBJ_CLASS(attr_idx) == Data_Obj) {
04209 
04210                if (ATD_STOR_BLK_IDX(attr_idx) != NULL_IDX) {
04211                   SB_HAS_RENAMES(ATD_STOR_BLK_IDX(attr_idx)) = TRUE;
04212                }
04213             }
04214             else if (AT_OBJ_CLASS(attr_idx) == Pgm_Unit &&
04215                      ATP_PROC(attr_idx) == Function &&
04216                      !ATP_RSLT_NAME(attr_idx)  &&
04217                      ATD_STOR_BLK_IDX(ATP_RSLT_IDX(attr_idx)) != NULL_IDX) {
04218                SB_HAS_RENAMES(ATD_STOR_BLK_IDX(ATP_RSLT_IDX(attr_idx))) = TRUE;
04219             }
04220          }
04221       }
04222 
04223       /* At this point, all new attribute entries have been checked to see */
04224       /* if they already exist in this scope, because of a previous use    */
04225       /* statement.  If the attr will get put into the new local name      */
04226       /* table, it has not been checked yet for not visible semantics.     */
04227       /* That is done as the old an new entries are merged.  If the attr   */
04228       /* will not go in the new local name table, both the local name tbl  */
04229       /* and the hidden name table were searched for the attr entry.  If   */
04230       /* it was found already in either table, the attr is marked so that  */
04231       /* the new attr idx becomes the old.  Any new attrs are entered into */
04232       /* the hidden name table.                                            */
04233 
04234 
04235       /* resolve_used_modules will issue CIF records and messages where    */
04236       /* necessary for all the modules brought in via this USE statement.  */
04237 
04238       resolve_used_modules(module_attr_idx);
04239 
04240       loc_name_tbl_idx = SCP_LN_LW_IDX(curr_scp_idx);
04241 
04242       /* The compression is a partial compression.  It only compresses the */
04243       /* tables just read in from the module table.  It is compressing out */
04244       /* entries not needed after the ONLY list(s) have been processed.    */
04245       /* These entries may point into the section of the tables not being  */
04246       /* compressed.  The compression algorithm handles this, but entries  */
04247       /* that are being kept cannot index to entries that are being        */
04248       /* compressed out.                                                   */
04249 
04250 
04251       /* At this point the local name table does not contain anything that */
04252       /* needs to be compressed out.  Do not compress the ln table.        */
04253 
04254       ML_LN_IDX(0) = SCP_LN_LW_IDX(curr_scp_idx);
04255 
04256       /* Keep everything on the bounds table free list.  It's easier to    */
04257       /* keep it, than to attempt to collapse it out, because we do not    */
04258       /* know if the free entries are in the area being collapsed or in    */
04259       /* the area being left alone.                                        */
04260 
04261       bd_idx       = BD_NEXT_FREE_NTRY(BD_FREE_LIST_IDX);
04262 
04263       while (bd_idx != NULL_IDX) {
04264          ML_BD_KEEP_ME(bd_idx)  = TRUE;
04265          bd_idx     = BD_NEXT_FREE_NTRY(bd_idx);
04266       }
04267 
04268       /* Resolve duplicate entries and share constant table entries. */
04269 
04270       assign_new_idxs(TRUE);
04271 
04272       save_const_pool_idx = NULL_IDX;
04273       save_const_tbl_idx  = NULL_IDX;
04274       num_module_derived_types  = 0;
04275       count_derived_types = TRUE;
04276 
04277       compress_tbls(save_attr_list_tbl_idx, FALSE);
04278 
04279       if (CURR_BLK != Interface_Body_Blk) {
04280 
04281          /* Interface_Body_Blk stuff is counted during interface collapse. */
04282 
04283          num_of_derived_types   += num_module_derived_types;
04284       }
04285 
04286       num_module_derived_types  = 0;
04287 
04288       BD_NEXT_FREE_NTRY(BD_FREE_LIST_IDX) = 
04289                                 ML_BD_IDX(BD_NEXT_FREE_NTRY(BD_FREE_LIST_IDX));
04290 
04291       for (new_name_idx = SCP_LN_FW_IDX(curr_scp_idx) + 1;
04292            new_name_idx < SCP_LN_LW_IDX(curr_scp_idx); new_name_idx++) {
04293          LN_ATTR_IDX(new_name_idx) = ML_AT_IDX(LN_ATTR_IDX(new_name_idx));
04294          LN_NAME_IDX(new_name_idx) = AT_NAME_IDX(LN_ATTR_IDX(new_name_idx));
04295          LN_NAME_LEN(new_name_idx) = AT_NAME_LEN(LN_ATTR_IDX(new_name_idx));
04296       }
04297 
04298 EXIT:
04299       ATP_SCP_ALIVE(module_attr_idx)  = FALSE;
04300       ATP_USE_LIST(module_attr_idx) = NULL_IDX;
04301       TBL_FREE(mod_link_tbl);
04302    }
04303 
04304    al_idx = interface_list;
04305 
04306    while (al_idx != NULL_IDX) {
04307       attr_idx    = AL_ATTR_IDX(al_idx);
04308       host_attr_idx = srch_host_sym_tbl(AT_OBJ_NAME_PTR(attr_idx),
04309                                             AT_NAME_LEN(attr_idx),
04310                                             &host_name_idx,
04311                                             TRUE);
04312 
04313       if (host_attr_idx != NULL_IDX &&
04314           !AT_NOT_VISIBLE(host_attr_idx) &&
04315            AT_OBJ_CLASS(host_attr_idx) == Interface) {
04316 
04317          /* Found this in a host scope.  Just concatenate the */
04318          /* hosted one following the new one from the module. */
04319          /* Based on concatenation rules we do not check for  */
04320          /* duplicates.  Duplicates should get errors.        */
04321          /* Duplicates that are actually from the same module */
04322          /* are ignored during semantic checking of the block.*/
04323 
04324          new_sn_idx = ATI_FIRST_SPECIFIC_IDX(attr_idx);
04325 
04326          while (SN_SIBLING_LINK(new_sn_idx) != NULL_IDX) {
04327             new_sn_idx  = SN_SIBLING_LINK(new_sn_idx);
04328          }
04329 
04330          SN_SIBLING_LINK(new_sn_idx) = ATI_FIRST_SPECIFIC_IDX(host_attr_idx);
04331          ATI_NUM_SPECIFICS(attr_idx) = ATI_NUM_SPECIFICS(attr_idx) +
04332                                        ATI_NUM_SPECIFICS(host_attr_idx); 
04333       }
04334       al_idx  = AL_NEXT_IDX(al_idx);
04335    }
04336 
04337    al_idx = SCP_USED_MODULE_LIST(curr_scp_idx);
04338 
04339    while (al_idx != NULL_IDX) {
04340 
04341       if (ATP_INDIRECT_MODULE(AL_ATTR_IDX(al_idx))) {
04342          ADD_ATTR_TO_LOCAL_LIST(AL_ATTR_IDX(al_idx));
04343 #ifdef KEY /* Bug 5089 */
04344    if (is_ieee(AL_ATTR_IDX(al_idx))) {
04345      SCP_USES_IEEE(curr_scp_idx) = TRUE;
04346    }
04347 #endif /* KEY Bug 5089 */
04348       }
04349       al_idx  = AL_NEXT_IDX(al_idx);
04350    }
04351 
04352    free_attr_list(interface_list);
04353    free_attr_list(attr_list_free_list);
04354    free_attr_list(SCP_USED_MODULE_LIST(curr_scp_idx));
04355 
04356    SCP_USED_MODULE_LIST(curr_scp_idx) = NULL_IDX;
04357 
04358    TBL_FREE(rename_only_tbl);
04359 
04360    keep_module_procs      = FALSE;
04361 
04362    TRACE (Func_Exit, "use_stmt_semantics", NULL);
04363 
04364    return;
04365 
04366 }   /* use_stmt_semantics */
04367 
04368 /******************************************************************************\
04369 |*                        *|
04370 |* Description:                     *|
04371 |*  This routine processes the rename only list.  It checks to make sure  *|
04372 |*  all the specified names are in the incoming module and marks them if  *|
04373 |*  they are specified in an ONLY list.  If they are renamed, it adds a   *|
04374 |*  new entry for the new name to the incoming local name table.          *|
04375 |*                        *|
04376 |* Input parameters:                    *|
04377 |*  module_attr_idx -> The module being processed.            *|
04378 |*                        *|
04379 |* Output parameters:                   *|
04380 |*  NONE                      *|
04381 |*                        *|
04382 |* Returns:                     *|
04383 |*  NOTHING                     *|
04384 |*                        *|
04385 \******************************************************************************/
04386 static  boolean rename_only_semantics(int module_attr_idx,
04387               boolean use_only)
04388 {
04389    int     attr_idx;
04390    int     begin_idx;
04391 #ifdef KEY /* Bug 10177 */
04392    int     cif_symbol_id = 0;
04393 #else /* KEY Bug 10177 */
04394    int     cif_symbol_id;
04395 #endif /* KEY Bug 10177 */
04396    int     end_idx;
04397    int     func_idx;
04398    boolean   has_renames    = FALSE;
04399    int     i;
04400    int     idx;
04401    int     length;
04402    int     ln_idx;
04403    int     match;
04404 #ifdef KEY /* Bug 10177 */
04405    int     name_idx = 0;
04406 #else /* KEY Bug 10177 */
04407    int     name_idx;
04408 #endif /* KEY Bug 10177 */
04409    int     new_attr_idx;
04410    int     new_name_idx;
04411    int     np_idx;
04412    int     rename_idx;
04413    int     ro_idx;
04414 
04415 # if defined(_HOST64) && !defined(_WHIRL_HOST64_TARGET64)
04416    long   *name_tbl_base;   /* name table base address */
04417 # endif
04418 
04419 
04420    TRACE (Func_Entry, "rename_only_semantics", NULL);
04421 
04422    ro_idx = ATP_USE_LIST(module_attr_idx);
04423    ln_idx = loc_name_tbl_idx - MD_NUM_ENTRIES(Loc_Name_Tbl) + 1;
04424    begin_idx  = SCP_LN_FW_IDX(curr_scp_idx);
04425    end_idx  = SCP_LN_LW_IDX(curr_scp_idx);
04426 
04427    /* Add a word for the all 1's word for table searches.  A word  */
04428    /* was left for the all 0's word, when the modules was read in. */
04429 
04430    TBL_REALLOC_CK(loc_name_tbl, 1);
04431 
04432    /* Set the current scope to the incoming local name table. */
04433 
04434    SCP_LN_FW_IDX(curr_scp_idx)    = ln_idx - 1;
04435    SCP_LN_LW_IDX(curr_scp_idx)    = loc_name_tbl_idx;
04436    loc_name_tbl[ln_idx-1]   = loc_name_tbl[begin_idx];
04437    loc_name_tbl[loc_name_tbl_idx] = loc_name_tbl[end_idx];
04438 
04439    while (ro_idx != NULL_IDX) {
04440       rename_idx  = RO_RENAME_IDX(ro_idx);
04441       attr_idx    = NULL_IDX;
04442    
04443       /* This WHILE finds the specified name in the local */
04444       /* name table of the module being read in.          */
04445 
04446       for (;;) {
04447 
04448          if (ln_idx >= loc_name_tbl_idx) {
04449 
04450             /* The name in the ONLY/rename list is larger than the last */
04451             /* name in the USEd module list.  This means it won't be    */
04452             /* found.  Set match to not found and take the error path.  */
04453 
04454             ln_idx = loc_name_tbl_idx;
04455             match  = -1;
04456             break;
04457          }
04458 
04459          match = compare_names(RO_NAME_LONG(ro_idx),
04460                                RO_NAME_LEN(ro_idx),
04461                                LN_NAME_LONG(ln_idx),
04462                                LN_NAME_LEN(ln_idx));
04463 
04464          if (match > 0) {
04465 
04466             /* The name in the ONLY/rename list is larger than the name */
04467             /* in the USEd module list.  Clear ML_AT_LN_NAME in case    */
04468             /* this attr gets used indirectly. (ie:  It's a type attr.) */
04469             /* Keep looping and looking.                                */
04470 
04471             ML_AT_LN_NAME(LN_ATTR_IDX(ln_idx)) = !use_only;
04472 
04473             ln_idx++;
04474 
04475          } 
04476          else if (LN_NEW_NAME(ln_idx)) {
04477 
04478             /* This is a new name added during this while processing    */
04479             /* from a rename list.  Keep looping and looking.           */
04480 
04481             ln_idx++;
04482          } 
04483          else {
04484             break;
04485          } 
04486       }  /* end for - match is always <= 0 */ 
04487 
04488 
04489       if (match == 0) {  /* Found the name in the module */
04490          attr_idx = LN_ATTR_IDX(ln_idx);
04491          name_idx = ln_idx;
04492 
04493          /* If the name is a USE'd module, then the name was NOT found.    */
04494          /* We keep any USE'd modules in the attribute table for           */
04495          /* bookkeeping purposes, but the module name cannot be specified  */
04496          /* on a rename or ONLY list.                                      */
04497 
04498          if (AT_OBJ_CLASS(attr_idx) == Pgm_Unit &&
04499              ATP_PGM_UNIT(attr_idx) == Module) {
04500              match = -1;
04501          }
04502       }
04503          
04504       if (match < 0) {  /* Didn't find the name in the module */
04505          name_idx = ln_idx;
04506 
04507          if (attr_idx != NULL_IDX) {  /* Module name */
04508             AT_DCL_ERR(attr_idx)  = TRUE;
04509 
04510             if (AT_OBJ_CLASS(attr_idx) == Pgm_Unit &&
04511                 ATP_PGM_UNIT(attr_idx) == Module && ATP_SCP_ALIVE(attr_idx)) {
04512 
04513                /* Cannot specify the module name in a rename only list     */
04514                /* Continue to the next item in the ro list.  If we renamed */
04515                /* the current module, it would just cause problems.        */
04516 
04517                PRINTMSG(RO_LINE_NUM(ro_idx), 1098, Error,
04518                         RO_COLUMN_NUM(ro_idx),
04519                         RO_NAME_PTR(ro_idx));
04520                ro_idx = RO_NEXT_IDX(ro_idx);
04521                continue;
04522             }
04523             else {
04524                PRINTMSG(RO_LINE_NUM(ro_idx), 732, Error,
04525                         RO_COLUMN_NUM(ro_idx),
04526                         RO_NAME_PTR(ro_idx),
04527                         AT_OBJ_NAME_PTR(module_attr_idx));
04528 
04529 
04530                /* This module is a hidden module.  (indirectly used.)     */
04531                /* Make a new attr for the rename name for error recovery. */
04532 
04533                NTR_ATTR_TBL(attr_idx);
04534 
04535                idx  = attr_tbl_idx;
04536 
04537                if (idx > mod_link_tbl_idx) {
04538                   length = idx - mod_link_tbl_idx;
04539                   idx    = mod_link_tbl_idx + 1;
04540                   TBL_REALLOC_CK(mod_link_tbl, length);
04541 
04542                   for (; idx <= mod_link_tbl_idx; idx++) {
04543                      CLEAR_TBL_NTRY(mod_link_tbl, idx);
04544                   }
04545                }
04546 
04547                ML_AT_LN_NAME(attr_idx)    = TRUE;
04548                AT_DCL_ERR(attr_idx)   = TRUE;
04549                AT_NAME_IDX(attr_idx)    = RO_NAME_IDX(ro_idx);
04550                AT_NAME_LEN(attr_idx)    = RO_NAME_LEN(ro_idx);
04551                AT_ORIG_NAME_IDX(attr_idx) = RO_NAME_IDX(ro_idx);
04552                AT_ORIG_NAME_LEN(attr_idx) = RO_NAME_LEN(ro_idx);
04553 
04554                /* Need to set this as USE ASSOCIATED from the module */
04555                /* to prevent bad error recovery problems.            */
04556 
04557                AT_USE_ASSOCIATED(attr_idx)  = TRUE;
04558                AT_MODULE_IDX(attr_idx)    = module_attr_idx;
04559 
04560                /* Give it an intrinsic type */
04561 
04562                SET_IMPL_TYPE(attr_idx);
04563             }
04564          }
04565          else {
04566             PRINTMSG(RO_LINE_NUM(ro_idx), 732, Error,
04567                      RO_COLUMN_NUM(ro_idx),
04568                      RO_NAME_PTR(ro_idx),
04569                      AT_OBJ_NAME_PTR(module_attr_idx));
04570 
04571             NTR_NAME_POOL(RO_NAME_LONG(ro_idx),
04572                           RO_NAME_LEN(ro_idx),
04573                           np_idx);
04574 
04575             /* Make an error entry into the local name table. */
04576 
04577             TBL_REALLOC_CK(loc_name_tbl, 1);
04578 
04579             /* Adding to local name table for last (most recent) scope.  No   */
04580             /* adjusting of other scope local name table entries is necessary.*/
04581 
04582             SCP_LN_LW_IDX(curr_scp_idx) = loc_name_tbl_idx;
04583 # if defined(_HOST64) && !defined(_WHIRL_HOST64_TARGET64)
04584             name_tbl_base   = (long *) loc_name_tbl;
04585 # endif
04586 
04587 #  pragma _CRI ivdep
04588             for (i = loc_name_tbl_idx; i >= name_idx; i--) {
04589 # if defined(_HOST64) && !defined(_WHIRL_HOST64_TARGET64)
04590                name_tbl_base [i] = name_tbl_base [i-1];
04591 # else
04592                loc_name_tbl [i]  = loc_name_tbl [i-1];
04593 # endif
04594             }
04595 
04596             NTR_ATTR_TBL(attr_idx);
04597 
04598             idx = (attr_tbl_idx > name_pool_idx) ? attr_tbl_idx : name_pool_idx;
04599 
04600             if (idx > mod_link_tbl_idx) {
04601                length = idx - mod_link_tbl_idx;
04602                idx    = mod_link_tbl_idx + 1;
04603                TBL_REALLOC_CK(mod_link_tbl, length);
04604 
04605                for (; idx <= mod_link_tbl_idx; idx++) {
04606                   CLEAR_TBL_NTRY(mod_link_tbl, idx);
04607                }
04608             }
04609 
04610             ML_AT_LN_NAME(attr_idx) = TRUE;
04611             LN_ATTR_IDX(name_idx) = attr_idx;
04612             LN_NAME_IDX(name_idx) = np_idx;
04613             LN_NAME_LEN(name_idx) = RO_NAME_LEN(ro_idx);
04614             AT_DCL_ERR(attr_idx)  = TRUE;
04615             AT_NAME_IDX(attr_idx) = np_idx;
04616             AT_NAME_LEN(attr_idx) = RO_NAME_LEN(ro_idx);
04617             AT_ORIG_NAME_IDX(attr_idx)  = np_idx;
04618             AT_ORIG_NAME_LEN(attr_idx)  = RO_NAME_LEN(ro_idx);
04619 
04620             /* Need to set this as USE ASSOCIATED from the module */
04621             /* to prevent bad error recovery problems.            */
04622 
04623             AT_USE_ASSOCIATED(attr_idx) = TRUE;
04624             AT_MODULE_IDX(attr_idx) = module_attr_idx;
04625 
04626             /* Give it an intrinsic type */
04627 
04628             SET_IMPL_TYPE(attr_idx);
04629          }
04630       }
04631 
04632       if (cif_flags & BASIC_RECS) {
04633 
04634          if (!LN_RENAMED(name_idx) && !LN_IN_ONLY_LIST(name_idx)) {
04635 
04636             /* The RO records are alphabetized by name.  If this name has  */
04637             /* been seen in an ONLY list or RENAMED, it already has a CIF  */
04638             /* symbol id, otherwise it needs a new symbol id.  Pass 0 as   */
04639             /* the symbol id, so cif_rename_rec will generate a new symbol */
04640             /* id.                                                        */
04641 
04642             cif_symbol_id = 0;
04643          }
04644       }
04645 
04646 
04647       if (rename_idx == NULL_IDX) {  /* ONLY without a renames. */
04648 
04649          if (LN_RENAMED(name_idx)) {
04650 
04651             /* This has been renamed already.  There are two local name  */
04652             /* entries that point to the same attr.  The original name   */
04653             /* and the renamed name.  Copy the attr entry so that the    */
04654             /* renamed local name gets its own attr.  Need to set        */
04655             /* ATD_EQUIV on both attr entries, because there are now two */
04656             /* objects with different name.  They are effectively        */
04657             /* equivalenced.  Need to reset the name on the attr.  It    */
04658             /* It is set to the new name.                                */
04659 
04660             /* before:                                                   */
04661             /*   name from module => old_attr     (input from module)    */
04662             /*   new_name         => old_attr     (RENAME specified)     */
04663             /* after:                                                    */
04664             /*   name from module => new_attr     (ONLY specified)       */
04665             /*   new_name         => old_attr     (RENAME specified)     */
04666 
04667             NTR_ATTR_TBL(new_attr_idx);
04668 
04669             if (attr_tbl_idx > mod_link_tbl_idx) {
04670                length = attr_tbl_idx - mod_link_tbl_idx;
04671                idx    = mod_link_tbl_idx + 1;
04672                TBL_REALLOC_CK(mod_link_tbl, length);
04673 
04674                for (; idx <= mod_link_tbl_idx; idx++) {
04675                   CLEAR_TBL_NTRY(mod_link_tbl, idx);
04676                }
04677             }
04678 
04679             if (AT_OBJ_CLASS(attr_idx) == Data_Obj) {
04680                ATD_EQUIV(attr_idx)    = TRUE;
04681             }
04682 
04683             COPY_ATTR_NTRY(new_attr_idx, attr_idx);
04684             AT_CIF_SYMBOL_ID(new_attr_idx)  = 0;
04685             AT_NAME_IDX(new_attr_idx)   = LN_NAME_IDX(name_idx);
04686             AT_NAME_LEN(new_attr_idx)   = LN_NAME_LEN(name_idx);
04687             attr_idx        = new_attr_idx;
04688             LN_ATTR_IDX(name_idx)   = attr_idx;
04689             ML_AT_LN_NAME(attr_idx)   = TRUE;
04690          }
04691 
04692          LN_IN_ONLY_LIST(name_idx)  = TRUE;
04693          AT_DEF_LINE(attr_idx)    = RO_LINE_NUM(ro_idx);
04694          AT_DEF_COLUMN(attr_idx)  = RO_COLUMN_NUM(ro_idx);
04695 
04696          if ((cif_flags & XREF_RECS) != 0) {  /* Only */
04697             cif_usage_rec(attr_idx,
04698                           AT_Tbl_Idx,
04699                           RO_LINE_NUM(ro_idx),
04700                           RO_COLUMN_NUM(ro_idx),
04701                           CIF_Symbol_Reference);
04702          }
04703       }
04704       else { /* Put new name into incoming symbol table. */
04705          has_renames  = TRUE;
04706 
04707          if (RO_DUPLICATE_RENAME(rename_idx) &&
04708              AT_OBJ_CLASS(attr_idx) != Interface) {
04709 
04710             /* This rename name has been specified twice in the rename list */
04711 
04712             PRINTMSG(RO_LINE_NUM(rename_idx), 1015, Error,
04713                      RO_COLUMN_NUM(rename_idx),
04714                      RO_NAME_PTR(rename_idx));
04715          }
04716 
04717          if (LN_RENAMED(name_idx) || LN_IN_ONLY_LIST(name_idx)) {
04718 
04719             /* This has been renamed or specified in an ONLY list already.   */
04720             /* Need a new attr entry.  If this is renamed there are two      */
04721             /* local entries pointing to the same attr.  (See comment above).*/
04722             /* If this is specified in an ONLY list we need to make a new    */
04723             /* local name/attr combination because of the different name.    */
04724 
04725             NTR_ATTR_TBL(new_attr_idx);
04726 
04727             if (attr_tbl_idx > mod_link_tbl_idx) {
04728                length = attr_tbl_idx - mod_link_tbl_idx;
04729                idx    = mod_link_tbl_idx + 1;
04730                TBL_REALLOC_CK(mod_link_tbl, length);
04731 
04732                for (; idx <= mod_link_tbl_idx; idx++) {
04733                   CLEAR_TBL_NTRY(mod_link_tbl, idx);
04734                }
04735             }
04736 
04737             if (AT_OBJ_CLASS(attr_idx) == Data_Obj) {
04738                ATD_EQUIV(attr_idx)  = TRUE;
04739             }
04740             COPY_ATTR_NTRY(new_attr_idx, attr_idx);
04741             attr_idx      = new_attr_idx;
04742             AT_CIF_SYMBOL_ID(attr_idx)  = 0;
04743          }
04744 
04745          LN_RENAMED(name_idx)   = TRUE;
04746          ML_AT_LN_NAME(attr_idx)  = TRUE;
04747 
04748          /* The current scopes SCP_LN_FW_IDX and SCP_LN_LW_IDX have been */
04749          /* set to point to the new scope.  It may not be NULL, but that */
04750          /* is okay.  We are just looking for a place to put the name.   */
04751 
04752          new_attr_idx = srch_sym_tbl(RO_NAME_PTR(rename_idx),
04753                                        RO_NAME_LEN(rename_idx),
04754                                        &new_name_idx);
04755 
04756          TBL_REALLOC_CK(loc_name_tbl, 1);
04757 
04758          if (loc_name_tbl_idx > mod_link_tbl_idx) {
04759             length = loc_name_tbl_idx - mod_link_tbl_idx;
04760             idx    = mod_link_tbl_idx + 1;
04761             TBL_REALLOC_CK(mod_link_tbl, length);
04762 
04763             for (; idx <= mod_link_tbl_idx; idx++) {
04764                CLEAR_TBL_NTRY(mod_link_tbl, idx);
04765             }
04766          }
04767 
04768          /* Adding to local name table for last (most recent) scope.  No   */
04769          /* adjusting of other scope local name table entries is necessary.*/
04770 
04771          SCP_LN_LW_IDX(curr_scp_idx)  = loc_name_tbl_idx;
04772 # if defined(_HOST64) && !defined(_WHIRL_HOST64_TARGET64)
04773          name_tbl_base      = (long *) loc_name_tbl;
04774 # endif
04775 
04776 #  pragma _CRI ivdep
04777          for (i = loc_name_tbl_idx; i >= new_name_idx; i--) {
04778 # if defined(_HOST64) && !defined(_WHIRL_HOST64_TARGET64)
04779             name_tbl_base [i] = name_tbl_base [i-1];
04780 # else
04781             loc_name_tbl [i]  = loc_name_tbl [i-1];
04782 # endif
04783          }
04784 
04785          /* Adjust ln_idx from the match loop.  ln_idx is used to search */
04786          /* through this local name table.  Members of the table have    */
04787          /* just shifted, so ln_idx must shift as well.                  */
04788 
04789          if (new_name_idx < ln_idx) {
04790             ln_idx++;
04791          }
04792 
04793          LN_ATTR_IDX(new_name_idx)  = attr_idx;
04794          LN_NAME_IDX(new_name_idx)  = RO_NAME_IDX(rename_idx);
04795          LN_NAME_LEN(new_name_idx)  = RO_NAME_LEN(rename_idx);
04796          LN_DEF_LOC(new_name_idx) = TRUE;
04797          LN_NEW_NAME(new_name_idx)  = TRUE;
04798          LN_RENAMED(new_name_idx) = FALSE;
04799          AT_DEF_LINE(attr_idx)    = RO_LINE_NUM(rename_idx);
04800          AT_DEF_COLUMN(attr_idx)  = RO_COLUMN_NUM(rename_idx);
04801 
04802          if (cif_flags & BASIC_RECS) {
04803             cif_symbol_id = cif_rename_rec(ro_idx,
04804                                            cif_symbol_id,
04805                                            attr_idx,
04806                                            module_attr_idx);
04807 
04808             if ((cif_flags & XREF_RECS) != 0) {
04809                cif_usage_rec(cif_symbol_id,
04810                              NO_Tbl_Idx,
04811                              RO_LINE_NUM(ro_idx),
04812                              RO_COLUMN_NUM(ro_idx),
04813                              CIF_Symbol_Reference);
04814 
04815                cif_usage_rec(attr_idx,
04816                              AT_Tbl_Idx,
04817                              RO_LINE_NUM(rename_idx),
04818                              RO_COLUMN_NUM(rename_idx),
04819                              CIF_Symbol_Declaration);
04820             }
04821          }
04822 
04823          AT_NAME_IDX(attr_idx)    = LN_NAME_IDX(new_name_idx);
04824          AT_NAME_LEN(attr_idx)    = LN_NAME_LEN(new_name_idx);
04825          AT_ORIG_MODULE_IDX(attr_idx) = module_attr_idx;
04826 
04827          if (AT_OBJ_CLASS(attr_idx) == Interface ||
04828              AT_OBJ_CLASS(attr_idx) == Pgm_Unit) {
04829             func_idx  = attr_idx;
04830 
04831             if (AT_OBJ_CLASS(func_idx) == Interface &&
04832                 ATI_PROC_IDX(func_idx) != NULL_IDX) {
04833                func_idx     = ATI_PROC_IDX(func_idx);
04834                AT_NAME_IDX(func_idx)  = LN_NAME_IDX(new_name_idx);
04835                AT_NAME_LEN(func_idx)  = LN_NAME_LEN(new_name_idx);
04836                AT_DEF_LINE(func_idx)  = AT_DEF_LINE(attr_idx);
04837                AT_DEF_COLUMN(func_idx)  = AT_DEF_COLUMN(attr_idx);
04838             }
04839 
04840             if (AT_OBJ_CLASS(func_idx) == Pgm_Unit &&
04841                 !ATP_RSLT_NAME(func_idx) &&
04842                 ATP_PGM_UNIT(func_idx) != Module &&
04843                 ATP_RSLT_IDX(func_idx) != NULL_IDX) {
04844                func_idx     = ATP_RSLT_IDX(func_idx);
04845                AT_NAME_IDX(func_idx)  = LN_NAME_IDX(new_name_idx);
04846                AT_NAME_LEN(func_idx)  = LN_NAME_LEN(new_name_idx);
04847                AT_DEF_LINE(func_idx)  = AT_DEF_LINE(attr_idx);
04848                AT_DEF_COLUMN(func_idx)  = AT_DEF_COLUMN(attr_idx);
04849             }
04850          }
04851          else if (AT_OBJ_CLASS(attr_idx) == Data_Obj &&
04852                   ATD_CLASS(attr_idx) == Constant &&
04853                   ATD_FLD(attr_idx) == AT_Tbl_Idx) {
04854             AT_NAME_IDX(ATD_CONST_IDX(attr_idx)) = LN_NAME_IDX(new_name_idx);
04855             AT_NAME_LEN(ATD_CONST_IDX(attr_idx)) = LN_NAME_LEN(new_name_idx);
04856          }
04857       }
04858       ro_idx      = RO_NEXT_IDX(ro_idx);
04859    }
04860 
04861    SCP_LN_FW_IDX(curr_scp_idx)  = begin_idx;
04862    SCP_LN_LW_IDX(curr_scp_idx)  = end_idx;
04863    loc_name_tbl_idx--;    /* Don't need all ones entry anymore */
04864 
04865    TRACE (Func_Exit, "rename_only_semantics", NULL);
04866 
04867    return(has_renames);
04868 
04869 }   /* rename_only_semantics */
04870 
04871 /*
04872  * On behalf of find_prog_unit_tbl, search for a module in either
04873  * inline_path_idx, module_path_idx (for ordinary modules) or
04874  * intrinsic_module_path_idx (for F2003 intrinsic modules.)
04875  *
04876  * module_attr_idx  module to look for
04877  * fp_file_idx    head of list in which to search (inline_path_idx,
04878  *      module_path_idx, or intrinsic_module_path_idx)
04879  * mod_file_ptr_ptr caller passes mod_file_ptr to us by reference
04880  * output_fp_file_idx value of fp_file_idx changes during this function;
04881  *      we return its final value to the caller via this arg
04882  * returns    true if module found
04883  */
04884 #ifdef KEY /* Bug 5089 */
04885 static boolean look_for_module(int module_attr_idx, int fp_file_idx,
04886    FILE **mod_file_ptr_ptr, int *output_fp_file_idx) {
04887    char   file_name[MAX_FILE_NAME_SIZE];
04888    char        *file_name_ptr;
04889    int    fn_length;
04890    boolean  archive;
04891    FILE *mod_file_ptr = *mod_file_ptr_ptr;
04892 #endif /* KEY Bug 5089 */
04893    if (on_off_flags.module_to_mod && !inline_search) {
04894       strcpy(file_name, AT_OBJ_NAME_PTR(module_attr_idx));
04895       fn_length     = AT_NAME_LEN(module_attr_idx);
04896       file_name[fn_length++]  = '.';
04897       file_name[fn_length++]  = 'm';
04898       file_name[fn_length++]  = 'o';
04899       file_name[fn_length++]  = 'd';
04900    }
04901    else {
04902       fn_length     = 0;
04903    }
04904    file_name[fn_length] = '\0';
04905 
04906    while (fp_file_idx != NULL_IDX) {
04907 #ifdef KEY /* Bug 5089 */
04908       int
04909 #endif /* KEY Bug 5089 */
04910       fp_module_idx   = NULL_IDX;
04911 #ifdef KEY /* Bug 5089 */
04912       int
04913 #endif /* KEY Bug 5089 */
04914       next_fp_module_idx  = FP_MODULE_IDX(fp_file_idx); /* 1st module */
04915 
04916       while (next_fp_module_idx != NULL_IDX) {
04917          fp_module_idx    = next_fp_module_idx;
04918          next_fp_module_idx = FP_MODULE_IDX(fp_module_idx);
04919 
04920          if (compare_names(AT_OBJ_NAME_LONG(module_attr_idx),
04921                            AT_NAME_LEN(module_attr_idx),
04922                            FP_NAME_LONG(fp_module_idx),
04923                            FP_NAME_LEN(fp_module_idx)) == 0) {
04924 
04925             /* Found the matching module.  Open the file and read header. */
04926 
04927             mod_file_ptr = open_module_file(module_attr_idx,
04928                                             fp_file_idx);
04929             
04930 
04931 #ifdef KEY /* Bug 5089 */
04932             boolean
04933 #endif /* KEY Bug 5089 */
04934             found = (mod_file_ptr == NULL) ?
04935                      FALSE : read_module_tbl_header(module_attr_idx,
04936                                                     fp_module_idx,
04937                                                     mod_file_ptr);
04938 #ifdef KEY /* Bug 5089 */
04939       *mod_file_ptr_ptr = mod_file_ptr;
04940       *output_fp_file_idx = fp_file_idx;
04941             return found;
04942 #else /* KEY Bug 5089 */
04943             goto FOUND;
04944 #endif /* KEY Bug 5089 */
04945          }
04946       }  /* End while - looking through module names in same file. */
04947 
04948       if (FP_SRCH_THE_FILE(fp_file_idx)) {
04949 
04950          /* All files specified on the commandline will come through as  */
04951          /* Unknown_Fp.  Here is where we determine what they are.       */
04952 
04953          if (FP_CLASS(fp_file_idx) == Unknown_Fp) {
04954 
04955             /* Determine if this is a directory or a file.  */
04956             /* If directory, convert to list of files.   If */
04957             /* file, they will be marked as Elf files if on */
04958             /* solaris and as regular files if not solaris. */
04959 
04960             find_files_in_directory(fp_file_idx);
04961 
04962             if (FP_CLASS(fp_file_idx) == Directory_Fp) {
04963 
04964                /* Skip the directory and go the next file or dir in the    */
04965                /* file path table.  This is most likely a file specified   */
04966                /* in the directory, but if the directory is empty, then    */
04967                /* this is the file or dir following the directory.         */
04968 
04969                fp_file_idx  = FP_NEXT_FILE_IDX(fp_file_idx);
04970                continue;
04971             }
04972          }
04973 
04974 # if defined(_TARGET_OS_SOLARIS) && defined(_MODULE_TO_DOT_o)
04975 
04976          if (FP_CLASS(fp_file_idx) == Elf_File_Fp ||
04977              FP_CLASS(fp_file_idx) == Unknown_Fp) {
04978 
04979             if (srch_elf_file_for_module_tbl(module_attr_idx, fp_file_idx)) {
04980 #ifdef KEY /* Bug 5089 */
04981          *mod_file_ptr_ptr = mod_file_ptr;
04982          *output_fp_file_idx = fp_file_idx;
04983          return TRUE;
04984 #else /* KEY Bug 5089 */
04985                found  = TRUE;
04986          goto FOUND;
04987 #endif /* KEY Bug 5089 */
04988             }
04989 
04990             /* Either this is not an elf file, or we really didn't find it. */
04991             /* If this is an Elf file, it will be marked as such by routine */
04992             /* srch_elf_file_for_module_tbl.                                */
04993 
04994          }
04995 # endif
04996 
04997          switch (FP_CLASS(fp_file_idx)) {
04998          case Mod_File_Fp:
04999 
05000             if (on_off_flags.module_to_mod && !inline_search) {
05001                file_name_ptr = NULL;
05002                file_name_ptr = strrchr(FP_NAME_PTR(fp_file_idx), SLASH);
05003 
05004                if (file_name_ptr == NULL) {  /* No path before name */
05005                   file_name_ptr = FP_NAME_PTR(fp_file_idx);
05006                }
05007                else {
05008                   ++file_name_ptr;  /* Skip slash */
05009                }
05010 
05011                if (strncmp(file_name, file_name_ptr, fn_length) == 0) {
05012 
05013                   /* Found file_name.mod */
05014 
05015                   mod_file_ptr = open_module_file(module_attr_idx, fp_file_idx);
05016 
05017                   if (mod_file_ptr == NULL) {       /* Not able to open file. */
05018                      continue;                      /* Try the next file.     */
05019                   }
05020 
05021                   if (srch_for_module_tbl(module_attr_idx,
05022                                           &fp_module_idx,
05023                                           fp_file_idx,
05024                                           0,
05025                                           mod_file_ptr)) {
05026 #ifdef KEY /* Bug 5089 */
05027          *mod_file_ptr_ptr = mod_file_ptr;
05028          *output_fp_file_idx = fp_file_idx;
05029          return TRUE;
05030 #else /* KEY Bug 5089 */
05031                      found  = TRUE;
05032          goto FOUND;
05033 #endif /* KEY Bug 5089 */
05034                   }
05035                }
05036             }
05037             break;
05038 
05039          case File_Fp:
05040          case Archive_File_Fp:
05041          case Unknown_Fp:         /* Look for modules in the Non-Elf files. */
05042 
05043             mod_file_ptr = open_module_file(module_attr_idx, fp_file_idx);
05044 
05045             if (mod_file_ptr == NULL) {       /* Not able to open file. */
05046                continue;                      /* Try the next file.     */
05047             }
05048 
05049             if (FP_OFFSET(fp_file_idx) > 0) {
05050 
05051                /* Assume this must be set to File_Fp or Archive_Fp.   */
05052 
05053                archive = (FP_CLASS(fp_file_idx) == Archive_File_Fp);
05054             }
05055             else {  /* we don't know what kind of file this is yet. */
05056 #ifdef KEY /* Bug 5089 */
05057          char ar_string[SARMAG];
05058          int num_recs_read;
05059 #endif /* KEY Bug 5089 */
05060 
05061                for (num_recs_read = 0; num_recs_read < SARMAG; num_recs_read++){
05062                   ar_string[num_recs_read] = '\n';
05063                }
05064 
05065                num_recs_read = fread((char *) ar_string, 
05066                                      sizeof(char),
05067                                      (size_t) SARMAG, 
05068                                      mod_file_ptr);
05069             
05070                if (num_recs_read == (size_t) SARMAG){
05071                    archive = (strncmp(ar_string, ARMAG, (size_t) SARMAG) == 0);
05072                }
05073                else {
05074                   archive = FALSE;
05075                }
05076 
05077                if (archive) {
05078                   FP_CLASS(fp_file_idx) = Archive_File_Fp;
05079                }
05080                else {
05081                   FP_CLASS(fp_file_idx) = File_Fp;
05082 
05083                   if (!FSEEK(mod_file_ptr, 0, SEEK_SET)) {
05084 
05085                      /* Reset to file start failed.  Skip to next file. */
05086 
05087                      fclose(mod_file_ptr);
05088                      fp_file_idx  = FP_NEXT_FILE_IDX(fp_file_idx);
05089                      continue;
05090                   }
05091                }
05092             }
05093 
05094             if (!archive) {
05095 
05096                if (FP_OFFSET(fp_file_idx) > 0 &&
05097                    !FSEEK(mod_file_ptr, FP_OFFSET(fp_file_idx), SEEK_CUR)) {
05098 
05099                   /* Seek failed.  Try the next file. */
05100 
05101                   fclose(mod_file_ptr);
05102                   fp_file_idx = FP_NEXT_FILE_IDX(fp_file_idx);
05103                   continue; 
05104                }
05105 
05106                if (srch_for_module_tbl(module_attr_idx,
05107                                        &fp_module_idx,
05108                                        fp_file_idx,
05109                                        0,
05110                                        mod_file_ptr)) {
05111 #ifdef KEY /* Bug 5089 */
05112       *mod_file_ptr_ptr = mod_file_ptr;
05113       *output_fp_file_idx = fp_file_idx;
05114       return TRUE;
05115 #else /* KEY Bug 5089 */
05116                   found = TRUE;
05117       goto FOUND;
05118 #endif /* KEY Bug 5089 */
05119                }
05120             }
05121             else if (srch_ar_file_for_module_tbl(module_attr_idx,
05122                                                  &fp_module_idx,
05123                                                  fp_file_idx,
05124                                                  mod_file_ptr)) {
05125 #ifdef KEY /* Bug 5089 */
05126          *mod_file_ptr_ptr = mod_file_ptr;
05127          *output_fp_file_idx = fp_file_idx;
05128          return TRUE;
05129 #else /* KEY Bug 5089 */
05130                found  = TRUE;
05131          goto FOUND;
05132 #endif /* KEY Bug 5089 */
05133             }
05134 
05135             fclose(mod_file_ptr);
05136             break;
05137 
05138          default:
05139             break;
05140 
05141          }  /* end switch */
05142       }
05143       fp_file_idx = FP_NEXT_FILE_IDX(fp_file_idx);
05144    }
05145 #ifdef KEY /* Bug 5089 */
05146    *mod_file_ptr_ptr = mod_file_ptr;
05147    *output_fp_file_idx = fp_file_idx;
05148    return FALSE;
05149 }
05150 #endif /* KEY Bug 5089 */
05151 
05152 /******************************************************************************\
05153 |*                        *|
05154 |* Description:                     *|
05155 |*  Open and search the input file looking for a module info table.       *|
05156 |*                        *|
05157 |* Input parameters:                    *|
05158 |*  NONE                      *|
05159 |*                        *|
05160 |* Output parameters:                   *|
05161 |*  NONE                      *|
05162 |*                        *|
05163 |* Returns:                     *|
05164 |*  TRUE if program unit is found.                                        *|
05165 |*                        *|
05166 \******************************************************************************/
05167 boolean find_prog_unit_tbl(int  module_attr_idx)
05168 
05169 {
05170 #ifndef KEY /* Bug 5089 */
05171    boolean  archive;
05172    char   ar_string[SARMAG];
05173 #endif /* KEY Bug 5089 */
05174    boolean  found   = FALSE;
05175 #ifndef KEY /* Bug 5089 */
05176    char   file_name[40];
05177    char        *file_name_ptr;
05178    int    fn_length;
05179 #endif /* KEY Bug 5089 */
05180    int    fp_file_idx;
05181    int    fp_module_idx;
05182    int    ga_idx;
05183    FILE        *mod_file_ptr;
05184    int    name_idx;
05185 #ifndef KEY /* Bug 5089 */
05186    int    next_fp_module_idx;
05187    int    num_recs_read;
05188 #endif /* KEY Bug 5089 */
05189    boolean  save_keep_module_procs;
05190 
05191 
05192    TRACE (Func_Entry, "find_prog_unit_tbl", NULL);
05193 
05194    alternate_entry    = FALSE;
05195    save_keep_module_procs = keep_module_procs;
05196 
05197    if (ATP_PGM_UNIT(module_attr_idx) == Module) {
05198       inline_search = FALSE;
05199    }
05200    else if (ATP_PROC(module_attr_idx) == Module_Proc ||
05201             ATP_PROC(module_attr_idx) == Intern_Proc) {
05202 
05203       /* Don't waste time searching for these.  The Intern_Proc would */
05204       /* be an internal error situation and the module_proc is not    */
05205       /* available because the module was not compiled with modinline */
05206 
05207       goto DONE;
05208    }
05209    else {
05210       inline_search = TRUE;
05211    }
05212 
05213    /* Finding the module shortcut:  Once we see a module or write out */
05214    /* a module, we retain the information as to file name and offset  */
05215    /* into file, so that we can quickly find it again.  We search the */
05216    /* global name table to find the module and then see if we have    */
05217    /* file information about it.                                      */
05218 
05219    if (
05220 #ifdef KEY /* Bug 5089 */
05221       /*
05222        * If we're looking for an intrinsic module, don't search the global
05223        * name table unless -intrinsic_module_gen was set, because ordinarily
05224        * a module defined in the current compilation cannot be intrinsic.
05225        */
05226       (on_off_flags.intrinsic_module_gen || !AT_IS_INTRIN(module_attr_idx)) &&
05227 #endif /* KEY Bug 5089 */
05228       srch_global_name_tbl(AT_OBJ_NAME_PTR(module_attr_idx),
05229                             AT_NAME_LEN(module_attr_idx),
05230                             &name_idx)) {
05231       ga_idx  = GN_ATTR_IDX(name_idx);
05232 
05233       if (GA_OBJ_CLASS(ga_idx) == Common_Block) {
05234          ga_idx = GAC_PGM_UNIT_IDX(ga_idx);
05235       }
05236 
05237       if (ga_idx != NULL_IDX && GAP_FP_IDX(ga_idx) != NULL_IDX) {
05238 
05239          /* The file and the position in that file for this module are known */
05240          /* already, so just open the file and seek to that position.        */
05241 
05242          fp_module_idx  = GAP_FP_IDX(ga_idx);
05243          fp_file_idx  = FP_FILE_IDX(fp_module_idx);
05244          mod_file_ptr = open_module_file(module_attr_idx,fp_file_idx);
05245          found    = (mod_file_ptr == NULL) ? FALSE :
05246                                         read_module_tbl_header(module_attr_idx,
05247                                                                fp_module_idx,
05248                                                                mod_file_ptr);
05249 
05250          if (found) {
05251             ATP_IN_CURRENT_COMPILE(module_attr_idx) = 
05252                            FP_CLASS(fp_module_idx) == Current_Compile_Fp;
05253             goto FOUND;
05254          }
05255          else {
05256 
05257             /* There's a potential file problem here.  If this is supposed */
05258             /* to be in the current compilation, issue a LIMIT.  Something */
05259             /* is wrong.  Otherwise issue a not found error.  We could get */
05260             /* fancy and redo the search again.  Maybe later.  (KAY)       */
05261 
05262             if (FP_CLASS(fp_module_idx) == Current_Compile_Fp &&
05263                 !inline_search) {
05264                PRINTMSG(AT_DEF_LINE(module_attr_idx), 1249, Limit,
05265                         AT_DEF_COLUMN(module_attr_idx),
05266                         AT_OBJ_NAME_PTR(module_attr_idx));
05267             }
05268             else {
05269                goto ERROR;
05270             }
05271          }
05272       }
05273       else if (ATP_PGM_UNIT(module_attr_idx) == GAP_PGM_UNIT(ga_idx) && 
05274                ATP_PGM_UNIT(module_attr_idx) == Module &&
05275                !inline_search && GA_DEFINED(GN_ATTR_IDX(name_idx))) {
05276  
05277          /* Found this name in the global name table.  Check to see if it */
05278          /* is defined.  If so, there must have been scoping problems or  */
05279          /* errors (if not a MODULE), so no program unit was written out. */
05280 
05281          goto ERROR;
05282       }
05283    }
05284 
05285 #ifdef KEY /* Bug 5089 */
05286    if (inline_search) {
05287      (void) look_for_module(module_attr_idx, inline_path_idx, &mod_file_ptr,
05288        &fp_file_idx);
05289    }
05290    else {
05291      /* Normally look first in nonintrinsic directories, then in intrinsic
05292       * directories. But if qualified with "intrinsic" or "non_intrinsic"
05293       * in the "use" statement, look in only the appropriate place.
05294       *
05295       * F2003 C1110 (R1109) says "A scoping unit shall not access an intrinsic
05296       * module and a nonintrinsic module of the same name." This case is
05297       * obviously a violation:
05298       *
05299       *   use, intrinsic :: xyz !sets AT_IS_INTRIN
05300       *   use, non_intrinsic :: xyz !sets ATT_NON_INTRIN
05301       *
05302       * But this case is a violation only if the "use" without either
05303       * "intrinsic" or "non_intrinsic" finds a non-intrinsic module:
05304       *
05305       *   use :: xyz !sets ATT_NO_MODULE_NATURE
05306       *   use, intrinsic :: xyz !sets AT_IS_INTRIN
05307       *
05308       * And this case is a violation only if the "use" without either
05309       * "intrinsic" or "non_intrinsic" finds an intrinsic module:
05310       *
05311       *   use :: xyz !sets ATT_NO_MODULE_NATURE
05312       *   use, non_intrinsic :: xyz !sets AT_IS_INTRIN
05313       */
05314      boolean violation = FALSE;
05315      boolean found_intrinsic = FALSE;
05316      if (AT_IS_INTRIN(module_attr_idx) && ATT_NON_INTRIN(module_attr_idx)) {
05317        violation = TRUE;
05318      }
05319      else if (ATT_NO_MODULE_NATURE(module_attr_idx)) {
05320        found = look_for_module(module_attr_idx, module_path_idx, &mod_file_ptr,
05321          &fp_file_idx);
05322        if (found) {
05323          if (AT_IS_INTRIN(module_attr_idx)) {
05324      violation = TRUE;
05325    }
05326        }
05327        else {
05328    found_intrinsic = found = look_for_module(module_attr_idx,
05329      intrinsic_module_path_idx, &mod_file_ptr, &fp_file_idx);
05330    if (found_intrinsic && ATT_NON_INTRIN(module_attr_idx)) {
05331      violation = TRUE;
05332    }
05333        }
05334      }
05335      else if (ATT_NON_INTRIN(module_attr_idx)) { // non_intrinsic alone
05336        found = look_for_module(module_attr_idx, module_path_idx, &mod_file_ptr,
05337          &fp_file_idx);
05338      }
05339      else if (AT_IS_INTRIN(module_attr_idx)) { // intrinsic alone
05340        found_intrinsic = found = look_for_module(module_attr_idx,
05341          intrinsic_module_path_idx, &mod_file_ptr, &fp_file_idx);
05342      }
05343      else {
05344        PRINTMSG(AT_DEF_LINE(module_attr_idx), 1044, Internal,
05345     AT_DEF_COLUMN(module_attr_idx),
05346     "ATT_NO_MODULE_NATURE should be set");
05347      }
05348 
05349      /* We no longer need to remember which module-nature keywords appeared in
05350       * various "use" statements for this module in this scope; henceforth, we
05351       * need to remember what kind of module we found. If it was intrinsic,
05352       * we must mark it as such, and must use special external (linker) name */
05353      AT_IS_INTRIN(module_attr_idx) = found_intrinsic;
05354      ATT_NON_INTRIN(module_attr_idx) = FALSE;
05355      ATT_NO_MODULE_NATURE(module_attr_idx) = FALSE;
05356      if (found_intrinsic) {
05357        MAKE_EXTERNAL_NAME(module_attr_idx, AT_NAME_IDX(module_attr_idx), 
05358    AT_NAME_LEN(module_attr_idx));
05359      }
05360 
05361      if (violation) {
05362        PRINTMSG(AT_DEF_LINE(module_attr_idx), 1678, Error,
05363    AT_DEF_COLUMN(module_attr_idx), AT_OBJ_NAME_PTR(module_attr_idx));
05364      }
05365    }
05366 
05367    if (found) {
05368      goto FOUND;
05369    }
05370 #else /* KEY Bug 5089 */
05371    fp_file_idx = (inline_search) ? inline_path_idx : module_path_idx;
05372 #endif /* KEY Bug 5089 */
05373 
05374 ERROR:
05375 
05376    /* Program unit is not found.  If this is a MODULE, issue an error.  If   */
05377    /* If we're searching for a program unit for inlining, just return FALSE. */
05378 
05379    if (!AT_DCL_ERR(module_attr_idx) && !inline_search) {
05380       AT_DCL_ERR(module_attr_idx) = TRUE;
05381 
05382       if (compare_names(AT_OBJ_NAME_LONG(module_attr_idx),
05383                         AT_NAME_LEN(module_attr_idx),
05384                         AT_OBJ_NAME_LONG(SCP_ATTR_IDX(MAIN_SCP_IDX)),
05385                         AT_NAME_LEN(SCP_ATTR_IDX(MAIN_SCP_IDX))) == 0) {
05386 
05387          /* Trying to include the current module */
05388 
05389          PRINTMSG(AT_DEF_LINE(module_attr_idx), 1027, Error,
05390                   AT_DEF_COLUMN(module_attr_idx),
05391                   AT_OBJ_NAME_PTR(module_attr_idx));
05392       }
05393       else {
05394          PRINTMSG(AT_DEF_LINE(module_attr_idx), 292, Error,
05395                   AT_DEF_COLUMN(module_attr_idx),
05396                   AT_OBJ_NAME_PTR(module_attr_idx));
05397       }
05398    }
05399 
05400    return(FALSE);
05401 
05402 FOUND:
05403 
05404    if (!inline_search && (cif_flags & BASIC_RECS)) {
05405       cif_use_module_rec(module_attr_idx,
05406                          fp_file_idx,
05407                          FALSE);
05408    }
05409 
05410    if (dump_flags.mod_version) {  /* Print out the module version */
05411 
05412       printf("Module %s is compiled with module version number %d. \n",
05413              AT_OBJ_NAME_PTR(module_attr_idx), MD_VERSION_NUM);
05414 
05415    }
05416 
05417    /* This module is in this compilation unit, but it has compile time errors.*/
05418    /* Issue a not found message - but read in the module for error recovery.  */
05419 
05420    if (MD_HAS_ERRORS) {
05421 
05422       if (!inline_search) {
05423          PRINTMSG(AT_DEF_LINE(module_attr_idx), 894, Error,
05424                   AT_DEF_COLUMN(module_attr_idx),
05425                   AT_OBJ_NAME_PTR(module_attr_idx));
05426          AT_DCL_ERR(module_attr_idx) = TRUE;
05427       }
05428       else {
05429          found = FALSE;
05430       }
05431    }
05432 
05433    if (MD_VERSION_NUM > MD_CURRENT_VERSION) {
05434       PRINTMSG(AT_DEF_LINE(module_attr_idx), 1181, Error,
05435                AT_DEF_COLUMN(module_attr_idx),
05436                FP_NAME_PTR(fp_file_idx));
05437       AT_DCL_ERR(module_attr_idx) = TRUE;
05438       found = FALSE;
05439    }
05440 
05441    if (MD_VERSION_NUM <= MD_LAST_3_0_VERSION) {
05442       PRINTMSG(AT_DEF_LINE(module_attr_idx), 1181, Error,
05443                AT_DEF_COLUMN(module_attr_idx),
05444                FP_NAME_PTR(fp_file_idx));
05445       AT_DCL_ERR(module_attr_idx) = TRUE;
05446       found = FALSE;
05447    }
05448    else if (MD_VERSION_NUM <= MD_LAST_4_0_VERSION) {
05449 
05450       /* Warning that this is an older module version and will not  */
05451       /* be supported in the following release.                     */
05452 
05453       PRINTMSG(AT_DEF_LINE(module_attr_idx), 1157, Warning,
05454                AT_DEF_COLUMN(module_attr_idx),
05455                FP_NAME_PTR(fp_file_idx));
05456    }
05457 
05458 
05459 #if defined(_HOST32) && defined(_TARGET64)
05460 
05461    if (MD_TARGET != target_os) {
05462 
05463       if (ATP_PGM_UNIT(module_attr_idx) == Module) {
05464          PRINTMSG(AT_DEF_LINE(module_attr_idx), 1055, Error,
05465                   AT_DEF_COLUMN(module_attr_idx),
05466                   FP_NAME_PTR(fp_file_idx));
05467          AT_DCL_ERR(module_attr_idx) = TRUE;
05468          found = FALSE;
05469       }
05470       else {
05471          PRINTMSG(AT_DEF_LINE(module_attr_idx), 1246, Error,
05472                   AT_DEF_COLUMN(module_attr_idx),
05473                   FP_NAME_PTR(fp_file_idx));
05474          AT_DCL_ERR(module_attr_idx) = TRUE;
05475          found = FALSE;
05476       }
05477    }
05478 # else
05479 
05480    if (MD_TARGET != target_os) {
05481 
05482       if (ATP_PGM_UNIT(module_attr_idx) == Module) {
05483          PRINTMSG(AT_DEF_LINE(module_attr_idx), 725, Error,
05484                   AT_DEF_COLUMN(module_attr_idx),
05485                   AT_OBJ_NAME_PTR(module_attr_idx));
05486          AT_DCL_ERR(module_attr_idx) = TRUE;
05487       }
05488       else {
05489          PRINTMSG(AT_DEF_LINE(module_attr_idx), 1247, Error,
05490                   AT_DEF_COLUMN(module_attr_idx),
05491                   AT_OBJ_NAME_PTR(module_attr_idx));
05492          AT_DCL_ERR(module_attr_idx) = TRUE;
05493       }
05494    }
05495 # endif
05496 
05497    if (!FP_SYSTEM_FILE(fp_file_idx)) {
05498 
05499       if (MD_CF77TYPES != cmd_line_flags.s_cf77types) {
05500          PRINTMSG(AT_DEF_LINE(module_attr_idx), 1248, Error,
05501                   AT_DEF_COLUMN(module_attr_idx),
05502                   AT_OBJ_NAME_PTR(module_attr_idx),
05503                   "-s i");
05504          AT_DCL_ERR(module_attr_idx) = TRUE;
05505       }
05506       else if (MD_DEFAULT32 != cmd_line_flags.s_default32) {
05507          PRINTMSG(AT_DEF_LINE(module_attr_idx), 1248, Error,
05508                   AT_DEF_COLUMN(module_attr_idx),
05509                   AT_OBJ_NAME_PTR(module_attr_idx),
05510                   "-s default32");
05511          AT_DCL_ERR(module_attr_idx) = TRUE;
05512       }
05513       else if (MD_DEFAULT64 != cmd_line_flags.s_default64) {
05514          PRINTMSG(AT_DEF_LINE(module_attr_idx), 1248, Error,
05515                   AT_DEF_COLUMN(module_attr_idx),
05516                   AT_OBJ_NAME_PTR(module_attr_idx),
05517                   "-s default64");
05518          AT_DCL_ERR(module_attr_idx) = TRUE;
05519       }
05520       else if (MD_FLOAT64 != cmd_line_flags.s_float64) {
05521          PRINTMSG(AT_DEF_LINE(module_attr_idx), 1248, Error,
05522                   AT_DEF_COLUMN(module_attr_idx),
05523                   AT_OBJ_NAME_PTR(module_attr_idx),
05524                   "-s float64");
05525          AT_DCL_ERR(module_attr_idx) = TRUE;
05526       }
05527       else if (MD_DEFAULT_INTEGER_TYPE != INTEGER_DEFAULT_TYPE) {
05528 #ifdef KEY /* Bug 7359 */
05529          PRINTMSG(AT_DEF_LINE(module_attr_idx), 623, Warning,
05530                   AT_DEF_COLUMN(module_attr_idx),
05531                   AT_OBJ_NAME_PTR(module_attr_idx));
05532 #else /* KEY Bug 7359 */
05533          PRINTMSG(AT_DEF_LINE(module_attr_idx), 623, Error,
05534                   AT_DEF_COLUMN(module_attr_idx),
05535                   AT_OBJ_NAME_PTR(module_attr_idx));
05536 #endif /* KEY Bug 7359 */
05537          AT_DCL_ERR(module_attr_idx) = TRUE;
05538       }
05539 
05540       if (MD_ENABLE_DOUBLE_PRECISION != on_off_flags.enable_double_precision) {
05541          PRINTMSG(AT_DEF_LINE(module_attr_idx), 618, Error,
05542                   AT_DEF_COLUMN(module_attr_idx),
05543                   AT_OBJ_NAME_PTR(module_attr_idx));
05544          AT_DCL_ERR(module_attr_idx) = TRUE;
05545       }
05546 
05547 #if defined(_ACCEPT_CMD_a_dalign)
05548 
05549       if (MD_DALIGN != cmd_line_flags.dalign) {
05550          PRINTMSG(AT_DEF_LINE(module_attr_idx), 1011, Error,
05551                   AT_DEF_COLUMN(module_attr_idx),
05552                   AT_OBJ_NAME_PTR(module_attr_idx));
05553          AT_DCL_ERR(module_attr_idx) = TRUE;
05554       }
05555 # endif
05556 
05557    }
05558 
05559    if (FP_CLASS(fp_file_idx) != Elf_File_Fp) {
05560 
05561       /* Elf files were read in during the elf search */
05562 
05563       if (found) {
05564          if (!read_in_module_tbl(fp_file_idx, 
05565                                  module_attr_idx, 
05566                                  mod_file_ptr, 
05567                                  NULL)) {
05568             found = FALSE;
05569          }
05570       }
05571       fclose(mod_file_ptr);
05572    }
05573 
05574    if (ATP_PGM_UNIT(module_attr_idx) != Module) {
05575 
05576       if (found && AT_ATTR_LINK(module_attr_idx) != NULL_IDX) {
05577          ATP_FIRST_SH_IDX(module_attr_idx) = 
05578                           ATP_FIRST_SH_IDX(AT_ATTR_LINK(module_attr_idx));
05579       }
05580       else {
05581          found = FALSE;
05582       }
05583       TBL_FREE(mod_link_tbl);
05584    }
05585 
05586 DONE:
05587 
05588    alternate_entry  = FALSE;
05589    keep_module_procs  = save_keep_module_procs;
05590    inline_search  = FALSE;
05591 
05592    TRACE (Func_Exit, "find_prog_unit_tbl", NULL);
05593 
05594    return(found);
05595 
05596 }  /* find_prog_unit_tbl */
05597 
05598 /******************************************************************************\
05599 |*                        *|
05600 |* Description:                     *|
05601 |*  Open the module file for reading.  Issue an error if there are        *|
05602 |*  problems.                   *|
05603 |*                        *|
05604 |* Input parameters:                    *|
05605 |*  module_attr_idx -> Attr index describing module being USEd.       *|
05606 |*  fp_file_idx -> Index to file path table of file to open.        *|
05607 |*                        *|
05608 |* Output parameters:                   *|
05609 |*  NONE                      *|
05610 |*                        *|
05611 |* Returns:                     *|
05612 |*  the file pointer to the file just opened.           *|
05613 |*                        *|
05614 \******************************************************************************/
05615 static  FILE  *open_module_file(int module_attr_idx,
05616           int fp_file_idx)
05617 
05618 {
05619    char   *lib_error;
05620    FILE   *mod_file_ptr;
05621 
05622 
05623    TRACE (Func_Entry, "open_module_file", NULL);
05624 
05625    mod_file_ptr = fopen(FP_NAME_PTR(fp_file_idx), "rb");
05626 
05627    if (mod_file_ptr == NULL_IDX) {
05628 
05629       if (FP_FILE_IDX(fp_file_idx) != NULL_IDX &&
05630           FP_CLASS(FP_FILE_IDX(fp_file_idx)) != Directory_Fp) {
05631   
05632          /* Don't issue an error for individual files in directories. */
05633 
05634          lib_error = strerror(errno);
05635 
05636          PRINTMSG(AT_DEF_LINE(module_attr_idx), 1132, Warning,
05637                   AT_DEF_COLUMN(module_attr_idx),
05638                   FP_NAME_PTR(fp_file_idx),
05639                   lib_error,
05640                   AT_OBJ_NAME_PTR(module_attr_idx));
05641       }
05642       FP_SRCH_THE_FILE(fp_file_idx) = FALSE;
05643       mod_file_end_offset   = 0;
05644    }
05645    else {
05646 
05647       /* Do not use FSEEK macro here, because this is where we are       */
05648       /* setting mod_file_end_offset, which is used by the FSEEK macro.  */
05649 
05650       fseek(mod_file_ptr, 0, SEEK_END); /* Seek to end of file */
05651 
05652       mod_file_end_offset = ftell(mod_file_ptr);
05653 
05654       fseek(mod_file_ptr, 0, SEEK_SET); /* Seek to start of file */
05655    }
05656 
05657    TRACE (Func_Exit, "open_module_file", NULL);
05658 
05659    return(mod_file_ptr);
05660 
05661 }  /* open_module_file */
05662 
05663 /******************************************************************************\
05664 |*                        *|
05665 |* Description:                     *|
05666 |*  srch_ar_file_for_module_tbl searches archival libraries for module    *|
05667 |*  information tables.  This routine can search archival libraries that  *|
05668 |*  have the Cray format or the sparc format.  (These differ for member   *|
05669 |*  names over 15 characters.)  This will search one archive file for a   *|
05670 |*  specific module name.  If it finds the module, mod_file_ptr will be   *|
05671 |*  left pointing to the start of the module and TRUE will be returned.   *|
05672 |*  If it finds a problem with the file or it doesn't find the module     *|
05673 |*  FALSE will be returned.                                               *|
05674 |*                        *|
05675 |* Input parameters:                    *|
05676 |*  module_attr_idx -> Attr index of module to search for.          *|
05677 |*  fp_file_idx -> File path table index to entry describing archive  *|
05678 |*         library to seach.                                  *|
05679 |*  fp_module_idx -> If this a resumed search, this is a file path      *|
05680 |*               table index for the last module found in this      *|
05681 |*               library.  If no modules have been found or if this *|
05682 |*               is not a resumed search, then this index is NULL.  *|
05683 |*  module_file_ptr -> FILE pointer to archive library to read from.      *|
05684 |*                        *|
05685 |* Output parameters:                   *|
05686 |*  NONE                      *|
05687 |*                        *|
05688 |* Returns:                     *|
05689 |*  TRUE  -> The module has been found.  mod_file_ptr will be set to      *|
05690 |*           start of module information table.                           *|
05691 |*  FALSE -> The module was not found.                                    *|
05692 |*                        *|
05693 \******************************************************************************/
05694 static  boolean srch_ar_file_for_module_tbl(int    module_attr_idx,
05695               int   *fp_module_idx,
05696               int    fp_file_idx,
05697               FILE  *mod_file_ptr)
05698 
05699 {
05700    typedef  struct    ar_hdr  ar_hdr_type;
05701 
05702       ar_hdr_type ar_header;
05703    static char    ar_name[256];
05704       boolean   found;
05705       int   idx;
05706       boolean   in_middle_of_file;
05707       long_type member_start_offset;
05708 #ifdef KEY /* Bug 10177 */
05709       int   name_length = 0;
05710 #else /* KEY Bug 10177 */
05711       int   name_length;
05712 #endif /* KEY Bug 10177 */
05713       long_type name_tbl_offset;
05714       int   num_recs_read;
05715       long_type offset;
05716       int   size;
05717 
05718 
05719    TRACE (Func_Entry, "srch_ar_file_for_module_tbl", NULL);
05720 
05721    /* At entry, we are either starting the search in a new archive library */
05722    /* or resuming the search from a given offset.  If we are resuming the  */
05723    /* search we are pointing to whatever follows a module information      */
05724    /* table entry.  This may be a new archive member or a new Cray PDT     */
05725    /* member.  If FP_OFFSET for the file is non-zero we are resuming the   */
05726    /* search.  If the search is being resumed, then mod_file_ptr is set to */
05727    /* the start of the file.  It needs to skip ARMAG, the archive magic    */
05728    /* header string.  If this is a new file being searched, mod_file_ptr   */
05729    /* is set just past ARMAG.                                              */
05730 
05731    offset   = FP_OFFSET(fp_file_idx);
05732 
05733    if (offset > 0) {
05734 
05735       if (!FSEEK(mod_file_ptr, SARMAG, SEEK_SET)) {
05736          return(FALSE);     /* Seek failed.  Exit to look in another file. */
05737       }
05738       in_middle_of_file = TRUE;
05739    }
05740    else {
05741       in_middle_of_file = FALSE;
05742    }
05743 
05744    found    = FALSE;
05745 
05746    /* name_tbl_offset contains the offset in the archive of the // table.  */
05747    /* The // archive holds names of archive members which are greater than */
05748    /* 15 characters.  This table always preceeds all normal member files.  */
05749    /* The only table which may preceed this table, is the symbol table,    */
05750    /* a special table created if there are relocatables in the archive.    */
05751    /* This special table can be ignored by this search.  The // table is   */
05752    /* found in archives for sparcs systems.                                */
05753 
05754    name_tbl_offset  = 0;
05755 
05756    while (!found) {   /* Loop through archival members. */
05757       num_recs_read = fread(&ar_header,
05758                                 AR_HDR_SIZE, /* Macro from ar.h */
05759                                 1,
05760                                 mod_file_ptr);
05761 
05762       if (feof(mod_file_ptr)) {
05763          FP_SRCH_THE_FILE(fp_file_idx)  = FALSE;
05764          break;
05765       }
05766 
05767       member_start_offset = ftell(mod_file_ptr);
05768 
05769       if (num_recs_read != 1) {
05770          PRINTMSG(AT_DEF_LINE(module_attr_idx), 726, Error,
05771                   AT_DEF_COLUMN(module_attr_idx),
05772                   AT_OBJ_NAME_PTR(module_attr_idx));
05773          FP_SRCH_THE_FILE(fp_file_idx)  = FALSE;
05774          break;
05775       }
05776 
05777       /* Calculate actual size of member.  */
05778 
05779       size  = (size_t) atoi(&ar_header.ar_size[0]);
05780 
05781       /* Skip known non module files within the archive.  On */
05782       /* Solaris, the string table is //.  Keep the offset   */
05783       /* into the // table, in case we hit names that are    */
05784       /* longer than 15 chars and need to access them.  On   */
05785       /* Crays, skip .relotable, .cldtable and .directory.   */
05786 
05787       if (strncmp (ar_header.ar_name, "// ", 3) == 0) {
05788          name_tbl_offset = member_start_offset;
05789 
05790          if (!FSEEK(mod_file_ptr, size, SEEK_CUR)) {
05791             break;
05792          }
05793       }
05794       else if (in_middle_of_file && 
05795               (size + AR_HDR_SIZE + member_start_offset) < offset) {
05796 
05797          /* If this is a resumed search we need to find which member we */
05798          /* are searching in.  We do this by reading up each member and */
05799          /* checking to see if the offset falls within that particular  */
05800          /* member.  We need to do this, because we cannot tell how     */
05801          /* far we are from the end of the member when we resume.  We   */
05802          /* need the members header to tell us the size of the member.  */
05803          /* Once we are in the correct member, we calculate the size    */
05804          /* left in the member by taking the offset to be resumed to    */
05805          /* and subtracting off the offset of the start of the member.  */
05806          /* Then we take the size of the member and subtract off how    */
05807          /* far we are inside the member.  In this else clause, we      */
05808          /* haven't reached the correct member yet, so skip this one.   */
05809 
05810          if (!FSEEK(mod_file_ptr, size, SEEK_CUR)) {
05811             break;
05812          }
05813       }
05814       else if ((strncmp (ar_header.ar_name, ".directory", 10) == 0) ||
05815                 (strncmp (ar_header.ar_name, ".cldtable", 9) == 0) ||
05816                 (strncmp (ar_header.ar_name, ".relotable", 10) == 0)) {
05817 
05818          if (!FSEEK(mod_file_ptr, size, SEEK_CUR)) {
05819             break;
05820          }
05821       }
05822       else {  /* Assume a searchable member. */
05823 
05824          if (in_middle_of_file) {
05825 
05826             /* We have found the member where we are going to resume */
05827             /* the search.  Set size to how much of this member we   */
05828             /* have to search through yet and then set mod_file_ptr  */
05829             /* to the point where we resume the search.              */
05830 
05831             size    = size - (offset - member_start_offset);
05832             in_middle_of_file = FALSE;
05833 
05834             if (!FSEEK(mod_file_ptr, offset, SEEK_SET)) {
05835                break;
05836             }
05837          }
05838          else {  /* Find the name of the member. */
05839 
05840             if (strncmp(ar_header.ar_name, "#1/", 3) == 0) {
05841 
05842                /* On Crays, if the member name is greater than 15 characters */
05843                /* ar_name contains #1/length of name.  The name follows      */
05844                /* ar_header before the member starts.  This section reads in */
05845                /* the name.                                                  */
05846 
05847                ar_header.ar_name[sizeof (ar_header.ar_name) - 1]= '\0';
05848                name_length  = (size_t) atoi(&ar_header.ar_name[3]);
05849                num_recs_read  = fread(&ar_name, name_length, 1, mod_file_ptr);
05850 
05851                /* Subtract off any filename chars that may appear after */
05852                /* the header.  This is a Cray specific thing.           */
05853 
05854                size     = size - name_length;
05855                member_start_offset  = ftell(mod_file_ptr);
05856 
05857                if (num_recs_read != 1) {
05858                   PRINTMSG(AT_DEF_LINE(module_attr_idx), 726, Error,
05859                            AT_DEF_COLUMN(module_attr_idx),
05860                            AT_OBJ_NAME_PTR(module_attr_idx));
05861                   FP_SRCH_THE_FILE(fp_file_idx) = FALSE;
05862                   break;
05863                }
05864             }
05865 
05866             else if (ar_header.ar_name[0] == '/') {
05867 
05868                /* On sparc systems, if the name is longer than 15 characters */
05869                /* ar_name contains /number, where number is an index into    */
05870                /* the // string table of the name of the member.  This       */
05871                /* section reads up that name and determines its length.      */
05872 
05873                switch (ar_header.ar_name[1]) {
05874                case '0':
05875                case '1':
05876                case '2':
05877                case '3':
05878                case '4':
05879                case '5':
05880                case '6':
05881                case '7':
05882                case '8':
05883                case '9':
05884 
05885                   /* This is an index to the // entry of the name.  */
05886                   /* The name is longer than 15 characters.         */
05887                   /* The // archive member (name_tbl_offset) should */
05888                   /* always be first or second before any named     */
05889                   /* normal members.  If we don't have a // archive */
05890                   /* member then there's a file problem, so issue   */
05891                   /* an error.                                      */
05892 
05893                   if (name_tbl_offset == 0) {
05894                      PRINTMSG(AT_DEF_LINE(module_attr_idx), 726, Error,
05895                               AT_DEF_COLUMN(module_attr_idx),
05896                               AT_OBJ_NAME_PTR(module_attr_idx));
05897                      FP_SRCH_THE_FILE(fp_file_idx)  = FALSE;
05898                      goto EXIT;
05899                   }
05900 
05901                   idx = (size_t) atoi(&ar_header.ar_name[1]);
05902 
05903                   if (!FSEEK(mod_file_ptr, (name_tbl_offset + idx), SEEK_SET)) {
05904                      goto EXIT;
05905                   }
05906 
05907                   if (fgets(ar_name, sizeof(ar_name), mod_file_ptr) == NULL) {
05908                      goto EXIT;
05909                   }
05910 
05911                   if (!FSEEK(mod_file_ptr, member_start_offset, SEEK_SET)) {
05912                      goto EXIT;
05913                   }
05914 
05915                   for (idx = 0; idx < sizeof(ar_name); idx++) {
05916 
05917                      /* ar has a BUG. Not all file names are '/' terminated */
05918                      /* some are blank terminated. */
05919 
05920                      if (ar_name[idx] == '/' ||
05921                          ar_name[idx] == ' ') {
05922                         name_length = idx;
05923                         break;
05924                      }
05925                      else if (ar_name[idx] == '\n') {
05926                         break;
05927                      }
05928                   }
05929                   break;
05930                }
05931             }
05932             else {
05933 
05934                /* This is a plain old < 15 characters name of a member. */
05935                /* Determine the length of the name.                     */
05936 
05937                (void) memcpy ((void *)ar_name, 
05938                               (void *)&ar_header.ar_name,
05939                               sizeof(ar_header.ar_name));
05940             
05941                /* Determine the actual length of this file name */
05942 
05943                for (idx = 0; idx < sizeof(ar_header.ar_name); idx++) {
05944 
05945                   /* ar has a BUG. Not all file names are '/' terminated */
05946                   /* some are blank terminated. */
05947 
05948                   if (ar_name[idx] == '/' ||
05949                       ar_name[idx] == ' ') {
05950                      name_length = idx;
05951                      break;
05952                   }
05953                }
05954             }
05955 
05956 # if defined(_MODULE_TO_DOT_o)
05957             if (on_off_flags.module_to_mod && !FP_SYSTEM_FILE(fp_file_idx)) {
05958 
05959                /* This module is created on systems that do not put their   */
05960                /* module information in the .o file, but in a .mod file.    */
05961                /* Play it safe while looking into archive files and only    */
05962                /* select out .mod files to search through.  Skip the rest.  */
05963    
05964                if (name_length < 5 ||
05965                   ar_name[name_length-1] != 'd' || 
05966                   ar_name[name_length-2] != 'o' || 
05967                   ar_name[name_length-3] != 'm' || 
05968                   ar_name[name_length-4] != '.') {
05969 
05970                   if (!FSEEK(mod_file_ptr, size, SEEK_CUR)) {
05971                      break;
05972                   }
05973                   size = 0;   /* Exit to next member. */
05974                }
05975             }
05976 
05977 # elif !defined(_MODULE_TO_DOT_M)
05978             if (on_off_flags.module_to_mod) {
05979 
05980                /* This module is created on systems that do not put their   */
05981                /* module information in the .o file, but in a .mod file.    */
05982                /* Play it safe while looking into archive files and only    */
05983                /* select out .mod files to search through.  Skip the rest.  */
05984    
05985                if (name_length < 5 ||
05986                   ar_name[name_length-1] != 'd' || 
05987                   ar_name[name_length-2] != 'o' || 
05988                   ar_name[name_length-3] != 'm' || 
05989                   ar_name[name_length-4] != '.') {
05990 
05991                   if (!FSEEK(mod_file_ptr, size, SEEK_CUR)) {
05992                      break;
05993                   }
05994                   size = 0;   /* Exit to next member. */
05995                }
05996             }
05997 # endif
05998 
05999 # if defined(_MODULE_TO_DOT_M)
06000 
06001             /* This module is created on systems that do not put their   */
06002             /* module information in the .o file, but in a .M file.      */
06003             /* Play it safe while looking into archive files and only    */
06004             /* select out .M files to search through.  Skip the rest.    */
06005 
06006             if (name_length < 3 ||
06007                ar_name[name_length-1] != 'M' ||
06008                ar_name[name_length-2] != '.') {
06009 
06010                if (!FSEEK(mod_file_ptr, size, SEEK_CUR)) {
06011                   break;
06012                }
06013                size = 0;   /* Exit to next member. */
06014             }
06015 # endif
06016          }
06017 
06018          found  = srch_for_module_tbl(module_attr_idx,
06019                                       fp_module_idx,
06020                                       fp_file_idx,
06021                                       size,
06022                                       mod_file_ptr);
06023       }
06024 
06025       /* Next archive header starts on an even byte boundary. */
06026 
06027       if (!found && (ftell(mod_file_ptr) & 01)) {
06028 
06029          if (!FSEEK(mod_file_ptr, 1L, SEEK_CUR)) {
06030             break;
06031          }
06032       }
06033    }
06034  
06035 EXIT:
06036 
06037    TRACE (Func_Exit, "srch_ar_file_for_module_tbl", NULL);
06038 
06039    return(found);
06040 
06041 }  /* srch_ar_file_for_module_tbl */
06042 
06043 /******************************************************************************\
06044 |*                        *|
06045 |* Description:                     *|
06046 |*                        *|
06047 |* Input parameters:                    *|
06048 |*      module_attr_idx -> Attr index of module being searched for.           *|
06049 |*      fp_module_idx   -> Fp index to entry describing module.  This routine *|
06050 |*                         changes the value as new modules are found.   This *|
06051 |*                         is NULL if we haven't found any modules in this    *|
06052 |*                         file yet.                                          *|
06053 |*      fp_file_idx     -> Fp index to entry describing file containing module*|
06054 |*      size    -> If this is an archive file, size if the size left  *|
06055 |*                         of this member in the archive file.                *|
06056 |*      mod_file_ptr    -> Ptr to open file holding module.                   *|
06057 |*                        *|
06058 |* Output parameters:                   *|
06059 |*  NONE                      *|
06060 |*                        *|
06061 |* Returns:                     *|
06062 |*  TRUE if we found the module.                                          *|
06063 |*                        *|
06064 \******************************************************************************/
06065 static  boolean srch_for_module_tbl(int    module_attr_idx,
06066             int   *fp_module_idx,
06067             int    fp_file_idx,
06068             int    size,
06069             FILE  *mod_file_ptr)
06070 
06071 {
06072    boolean  found   = FALSE;
06073    int    idx;
06074    long        *mod_name_idx;
06075    int    name_len;
06076    int    num_recs_read;
06077    long_type  offset;
06078 
06079 
06080    TRACE (Func_Entry, "srch_for_module_tbl", NULL);
06081 
06082    /* On systems where the module table is buried in the .o files   */
06083    /* we have to search through the PDT loops for the module table. */
06084    /* If the module table is not buried in the .o files, but is its */
06085    /* own member, then this while loop will only be executed once.  */
06086 
06087 # if defined(_DEBUG)
06088 
06089    if (dump_flags.pdt_dump) {
06090       print_fp(fp_file_idx);
06091    }
06092 # endif
06093 
06094    while (!found) {
06095 
06096       if (FP_CLASS(fp_file_idx) == Archive_File_Fp && size <= 0) {
06097 
06098          /* Have reached end of this member.  Or we've gone off in the weeds */
06099 
06100          break;
06101       }
06102 
06103       offset    = ftell(mod_file_ptr);
06104       num_recs_read = fread(&mit_header, 
06105                                 MD_PDT_HEADER_BYTE_SIZE,
06106                                 1,
06107                                 mod_file_ptr);
06108 
06109       if (feof(mod_file_ptr)) {
06110    
06111          /* Found the end of this file, but didn't find the module */
06112          /* Try the next file in the list.                         */
06113    
06114          FP_SRCH_THE_FILE(fp_file_idx) = FALSE;
06115          break;
06116       }
06117    
06118       if (num_recs_read != 1) {
06119          PRINTMSG(AT_DEF_LINE(module_attr_idx), 726, Error,
06120                   AT_DEF_COLUMN(module_attr_idx),
06121                   AT_OBJ_NAME_PTR(module_attr_idx));
06122          FP_SRCH_THE_FILE(fp_file_idx)  = FALSE;
06123          break;
06124       }
06125 
06126       if (MD_PDT_HDR_TYPE != COMPILER_INFO_TABLE_TYPE) {
06127    
06128 # if defined(_DEBUG)
06129 
06130          if (dump_flags.pdt_dump) {
06131             dump_pdt(mod_file_ptr);
06132          }
06133 # endif
06134          /* Not a module information table.  Find the next loader */
06135          /* table in this file.  Reset to start of this table and */
06136          /* then seek to the end of this table.  If the header    */
06137          /* length is zero, we have stumbled on a bad file,       */
06138          /* perhaps another vendors mixed with ours???            */
06139    
06140          if (MD_PDT_HDR_LEN == 0 ||
06141              !FSEEK(mod_file_ptr, offset, SEEK_SET) ||
06142              !FSEEK(mod_file_ptr, (long) MD_PDT_HDR_LEN * TARGET_BYTES_PER_WORD,
06143                                   SEEK_CUR)) {
06144             FP_SRCH_THE_FILE(fp_file_idx) = FALSE;
06145             break;
06146          }
06147 
06148          /* Offset points to start of this table.  ftell returns */
06149          /* position of end of this table.  Decrease size by the */
06150          /* size of this table that we are skipping.             */
06151 
06152          if (FP_CLASS(fp_file_idx) == Archive_File_Fp) {
06153             size -= (ftell(mod_file_ptr) - offset);
06154           }
06155          continue;
06156       }
06157 
06158          /* Not a module information table.  Find the next loader */
06159 
06160       num_recs_read = fread(MD_AFTER_PDT,
06161                             MD_TBL_BYTE_SIZE - MD_PDT_HEADER_BYTE_SIZE,
06162                             1,
06163                             mod_file_ptr);
06164       
06165       if (feof(mod_file_ptr)) {
06166 
06167          /* Found the end of this file, but didn't find the module */
06168          /* Try the next file in the list.                         */
06169 
06170          FP_SRCH_THE_FILE(fp_file_idx) = FALSE;
06171          break;
06172       }
06173 
06174       if (num_recs_read != 1) {
06175          PRINTMSG(AT_DEF_LINE(module_attr_idx), 726, Error,
06176                   AT_DEF_COLUMN(module_attr_idx),
06177                   AT_OBJ_NAME_PTR(module_attr_idx));
06178          FP_SRCH_THE_FILE(fp_file_idx) = FALSE;
06179          break;
06180       }
06181 
06182 # if defined(_DEBUG)
06183 
06184       if (dump_flags.pdt_dump) {
06185          dump_pdt(mod_file_ptr);
06186       }
06187 # endif
06188 
06189       /* Found a module.  Save the information in the file_path_tbl. */
06190       /* If it matches we need the info, if it doesn't it will be    */
06191       /* easier to search for next time.                             */
06192    
06193       TBL_REALLOC_CK(file_path_tbl, 1);
06194       CLEAR_TBL_NTRY(file_path_tbl, file_path_tbl_idx);
06195       name_len  = MD_NAME_LEN;
06196 
06197       if (*fp_module_idx == NULL_IDX) {
06198          *fp_module_idx     = fp_file_idx;
06199          FP_MODULE_IDX(*fp_module_idx)  = file_path_tbl_idx;
06200          *fp_module_idx     = file_path_tbl_idx;
06201          FP_NAME_LEN(*fp_module_idx)  = name_len;
06202          FP_NAME_IDX(*fp_module_idx)  = str_pool_idx + 1;
06203          FP_FILE_IDX(*fp_module_idx)  = fp_file_idx;
06204          FP_OFFSET(*fp_module_idx)  = offset;
06205          FP_CLASS(*fp_module_idx) = (inline_search) ? Inline_Fp:Module_Fp;
06206          mod_name_idx     = MD_NAME_LONG;
06207 
06208          TBL_REALLOC_CK(str_pool, WORD_LEN(name_len));
06209 
06210          for (idx = FP_NAME_IDX(*fp_module_idx); idx <= str_pool_idx; idx++) {
06211             str_pool[idx].name_long = *mod_name_idx;
06212                mod_name_idx++;
06213          }
06214       }
06215       else if (FP_OFFSET(*fp_module_idx) == -1) {
06216 
06217          /* Searching for this name.  Should be next in this file. */
06218 
06219          if (compare_names(AT_OBJ_NAME_LONG(module_attr_idx),
06220                            AT_NAME_LEN(module_attr_idx),
06221                            MD_NAME_LONG,
06222                            name_len) != 0) {
06223 
06224              /* Cute little problem here - kay */
06225 
06226          }
06227          else { /* Found module - update offset */
06228             FP_OFFSET(*fp_module_idx) = offset;
06229          }
06230       }
06231       else {
06232 
06233         /* Found a module.  Do not have a list of modules. So make one. */
06234 
06235          FP_MODULE_IDX(*fp_module_idx)  = file_path_tbl_idx;
06236          *fp_module_idx     = file_path_tbl_idx;
06237          FP_NAME_LEN(*fp_module_idx)  = name_len;
06238          FP_NAME_IDX(*fp_module_idx)  = str_pool_idx + 1;
06239          FP_FILE_IDX(*fp_module_idx)  = fp_file_idx;
06240          FP_OFFSET(*fp_module_idx)  = offset;
06241          FP_CLASS(*fp_module_idx) = (inline_search) ? Inline_Fp:Module_Fp;
06242          mod_name_idx     = MD_NAME_LONG;
06243 
06244          TBL_REALLOC_CK(str_pool, WORD_LEN(name_len));
06245 
06246          for (idx = FP_NAME_IDX(*fp_module_idx); idx <= str_pool_idx; idx++) {
06247             str_pool[idx].name_long = *mod_name_idx;
06248             mod_name_idx++;
06249          }
06250       }
06251 
06252       if (compare_names(AT_OBJ_NAME_LONG(module_attr_idx),
06253                         AT_NAME_LEN(module_attr_idx),
06254                         MD_NAME_LONG,
06255                         name_len) != 0) {
06256 
06257          /* Reset to start of this table and    */
06258          /* then seek to the end of this table. */
06259 
06260          if (!FSEEK(mod_file_ptr, offset, SEEK_SET) ||
06261               MD_PDT_HDR_LEN == 0 ||
06262              !FSEEK(mod_file_ptr, (long) MD_PDT_HDR_LEN * TARGET_BYTES_PER_WORD,
06263                                   SEEK_CUR)) {
06264             FP_SRCH_THE_FILE(fp_file_idx) = FALSE;
06265             break;
06266          }
06267 
06268          /* Offset points to start of this table.  ftell returns */
06269          /* position of end of this table.  Decrease size by the */
06270          /* size of this table that we are skipping.             */
06271 
06272          if (FP_CLASS(fp_file_idx) == Archive_File_Fp) {
06273              size -= (ftell(mod_file_ptr) - offset);
06274          }
06275       }
06276       else {
06277 
06278          /* We found the module we are looking for.  Set FP_OFFSET */
06279          /* to the end of this module information table.  All      */
06280          /* modules that we have found before this module have     */
06281          /* been entered in the file path table so they can be     */
06282          /* found again really easy.  Thus we set FP_OFFSET to the */
06283          /* end of this table, because we have already searched    */
06284          /* and recorded all modules up to this point.  If we need */
06285          /* to search for a module and it is not already listed in */
06286          /* the file path table, we will resume our search at this */
06287          /* point.  MD_PDT_HDR_LEN is the length of this module    */
06288          /* information table.  It is kept in number of words and  */
06289          /* needs to be reset to bytes.                            */
06290 
06291          FP_OFFSET(fp_file_idx) = offset + 
06292                                  ((long)MD_PDT_HDR_LEN * TARGET_BYTES_PER_WORD);
06293          found = TRUE;
06294       }
06295    }
06296 
06297    TRACE (Func_Exit, "srch_for_module_tbl", NULL);
06298 
06299    return(found);
06300 
06301 } /* srch_for_module_tbl */
06302 
06303 /******************************************************************************\
06304 |*                        *|
06305 |* Description:                     *|
06306 |*                        *|
06307 |* Input parameters:                    *|
06308 |*      module_attr_idx -> Attr index of module being searched for.           *|
06309 |*      fp_module_idx   -> Fp index to entry describing module.               *|
06310 |*      mod_file_ptr    -> Ptr to open file holding module.                   *|
06311 |*                        *|
06312 |* Output parameters:                   *|
06313 |*  NONE                      *|
06314 |*                        *|
06315 |* Returns:                     *|
06316 |*  TRUE - if we found and read module header successfully.               *|
06317 |*                        *|
06318 \******************************************************************************/
06319 static  boolean read_module_tbl_header(int  module_attr_idx,
06320                int  fp_module_idx,
06321                FILE    *mod_file_ptr)
06322 {
06323    boolean  found     = FALSE;
06324    int    num_recs_read;
06325    long_type  offset;
06326 
06327 
06328    TRACE (Func_Entry, "read_module_tbl_header", NULL);
06329 
06330    if (FP_OFFSET(fp_module_idx) == -1) {
06331 
06332       /* This file has just been written out - Don't */
06333       /* know where the table is, so find it.        */
06334 
06335       offset = 0;
06336 
06337       while (!feof(mod_file_ptr)) {
06338          num_recs_read = fread(&mit_header,
06339                                MD_PDT_HEADER_BYTE_SIZE,
06340                                1,
06341                                mod_file_ptr);
06342 
06343          if (num_recs_read != 1 || feof(mod_file_ptr)) {
06344             fp_module_idx = NULL_IDX;
06345             break;
06346          }
06347 
06348          if (MD_PDT_HDR_TYPE != COMPILER_INFO_TABLE_TYPE) {
06349             offset  = offset + ((long) MD_PDT_HDR_LEN * 
06350                                            TARGET_BYTES_PER_WORD);
06351 
06352             if (!FSEEK(mod_file_ptr,
06353                        (((long) MD_PDT_HDR_LEN * TARGET_BYTES_PER_WORD) - 
06354                          (long) MD_PDT_HEADER_BYTE_SIZE), SEEK_CUR)) {
06355                fp_module_idx = NULL_IDX;
06356                break;
06357             }
06358             continue;
06359          }
06360 
06361          num_recs_read = fread(MD_AFTER_PDT,
06362                                MD_TBL_BYTE_SIZE - MD_PDT_HEADER_BYTE_SIZE,
06363                                1,
06364                                mod_file_ptr);
06365 
06366          if (num_recs_read != 1 || feof(mod_file_ptr)) {
06367             fp_module_idx = NULL_IDX;
06368             break;
06369          }
06370 
06371          if (compare_names(AT_OBJ_NAME_LONG(module_attr_idx),
06372                            AT_NAME_LEN(module_attr_idx),
06373                            MD_NAME_LONG,
06374                            MD_NAME_LEN) == 0) {
06375             break;
06376          }
06377 
06378          offset = offset + ((long) MD_PDT_HDR_LEN * TARGET_BYTES_PER_WORD);
06379 
06380          if (!FSEEK(mod_file_ptr, 
06381                     ((long)MD_PDT_HDR_LEN * TARGET_BYTES_PER_WORD) - 
06382                                             (long) MD_TBL_BYTE_SIZE,
06383                     SEEK_CUR)) {
06384             fp_module_idx = NULL_IDX;
06385             break;
06386          }
06387       }
06388 
06389       if (fp_module_idx != NULL_IDX) {
06390          FP_OFFSET(fp_module_idx) = offset;
06391          found        = TRUE;
06392       }
06393    }
06394    else if (FSEEK(mod_file_ptr, FP_OFFSET(fp_module_idx), SEEK_CUR)) {
06395       num_recs_read = fread(&mit_header,
06396                             MD_TBL_BYTE_SIZE,
06397                             1,
06398                             mod_file_ptr);
06399 
06400       if (num_recs_read != 1) {
06401          PRINTMSG(AT_DEF_LINE(module_attr_idx), 726, Error,
06402                   AT_DEF_COLUMN(module_attr_idx),
06403                   AT_OBJ_NAME_PTR(module_attr_idx));
06404       }
06405       else {
06406          found    = TRUE;
06407       }
06408    }
06409 
06410    TRACE (Func_Exit, "read_module_tbl_header", NULL);
06411 
06412    return(found);
06413 
06414 }  /* read_module_tbl_header */
06415 
06416 /******************************************************************************\
06417 |*                        *|
06418 |* Description:                     *|
06419 |*  Read in the module information table if it is in a file.              *|
06420 |*  Copy in the module information table if it is in an elf buffer.       *|
06421 |*                        *|
06422 |* Input parameters:                    *|
06423 |*  module_attr_idx => Attr index of the module to be read in.            *|
06424 |*  mod_file_ptr    => Pointer to file, it mod table is in file.          *|
06425 |*  mod_info_tbl    => Pointer to mod table in elf buffer.                *|
06426 |*                        *|
06427 |* Output parameters:                   *|
06428 |*  NONE                      *|
06429 |*                        *|
06430 |* Returns:                     *|
06431 |*  TRUE if a module info table was successfully brought in.              *|
06432 |*                        *|
06433 \******************************************************************************/
06434 static  boolean  read_in_module_tbl(int    fp_file_idx,
06435             int    module_attr_idx,
06436             FILE  *mod_file_ptr,
06437             char  *mod_info_tbl)
06438 
06439 {
06440    int      al_idx;
06441    int      end_sb_idx;
06442    int      idx;
06443    int      ln_idx;
06444    int      name_idx;
06445    int      num_recs_read;
06446    boolean    ok      = TRUE;
06447    int      old_attr_tbl_idx  = attr_tbl_idx;
06448    int      old_bounds_tbl_idx  = bounds_tbl_idx;
06449    int      old_const_tbl_idx = const_tbl_idx;
06450    int      old_const_pool_idx  = const_pool_idx;
06451    int      old_ir_tbl_idx    = ir_tbl_idx;
06452    int      old_ir_list_tbl_idx = ir_list_tbl_idx;
06453    int      old_ln_idx;
06454    int      old_name_pool_idx;
06455    int      old_sec_name_tbl_idx  = sec_name_tbl_idx;
06456    int      old_sh_tbl_idx    = sh_tbl_idx;
06457    int      old_stor_blk_tbl_idx  = stor_blk_tbl_idx;
06458    int      old_type_tbl_idx  = type_tbl_idx;
06459    boolean    only_stmt;
06460    int      save_attr_list_start;
06461    int      save_attr_list_end;
06462    int      sb_idx;
06463    int      srch_sb_idx;
06464 
06465 
06466    TRACE (Func_Entry, "read_in_module_tbl", NULL);
06467 
06468    if (MD_HAS_ERRORS && inline_search) {
06469 
06470       /* Do not read if not module and there is errors. */
06471 
06472       return(FALSE);
06473    }
06474 
06475    /* If this is an alternate entry, we need to seek forward */
06476    /* to find the table entries and the main entry.  There   */
06477    /* will be an mit_header for each alternate entry,        */
06478    /* followed by the main entry.                            */
06479 
06480    alternate_entry  = MD_ALTERNATE_ENTRY;
06481 
06482    while (MD_ALTERNATE_ENTRY) {
06483 
06484       if (mod_info_tbl != NULL) {  /* Copying from elf buffer */
06485          memcpy((void *) &mit_header.wd[0],
06486                 (char *) mod_info_tbl,
06487                 (sizeof(mit_header_type)));
06488 
06489         mod_info_tbl += (sizeof(mit_header_type));
06490       }
06491       else {
06492          num_recs_read = fread(&mit_header,
06493                                sizeof(mit_header_type),
06494                                1,
06495                                mod_file_ptr);
06496 # if defined(_DEBUG)
06497 
06498          if (dump_flags.pdt_dump) {
06499             dump_pdt(mod_file_ptr);
06500          }
06501 # endif
06502 
06503          if (num_recs_read != 1) {
06504             PRINTMSG(AT_DEF_LINE(module_attr_idx), 726, Error,
06505                      AT_DEF_COLUMN(module_attr_idx),
06506                      AT_OBJ_NAME_PTR(module_attr_idx));
06507             ok  = FALSE;
06508             goto EXIT;
06509          }
06510       }
06511    }
06512 
06513    /* Store the module path into the name pool, before we read in the new     */
06514    /* module stuff into the name pool.  This way it won't get compressed out. */
06515 
06516    if (!inline_search) {
06517 
06518       if (!ATP_IN_CURRENT_COMPILE(module_attr_idx)) {
06519          ATP_MOD_PATH_LEN(module_attr_idx)   = FP_NAME_LEN(fp_file_idx);
06520          ATP_MOD_PATH_IDX(module_attr_idx)   = name_pool_idx + 1;
06521          name_idx        = FP_NAME_IDX(fp_file_idx);
06522 
06523          TBL_REALLOC_CK(name_pool, WORD_LEN(FP_NAME_LEN(fp_file_idx)));
06524 
06525          for (idx = ATP_MOD_PATH_IDX(module_attr_idx);idx<=name_pool_idx;idx++){
06526             name_pool[idx].name_long = str_pool[name_idx].name_long;
06527             name_idx++;
06528          }
06529       }
06530       only_stmt   = ATP_USE_TYPE(module_attr_idx) == Use_Only;
06531  
06532    }
06533    else {
06534       only_stmt   = FALSE;
06535    }
06536  
06537    old_name_pool_idx  = name_pool_idx;
06538 
06539 
06540    if (mod_info_tbl != NULL) { /* Elf file - Will always be 3 or greater */
06541        memcpy((void *) &mit_descriptor[1].wd, 
06542               (char *) mod_info_tbl,
06543               (sizeof(mit_descriptor_type) * Num_Of_Tbls));
06544 
06545       mod_info_tbl += (sizeof(mit_descriptor_type) * Num_Of_Tbls);
06546    }
06547    else {
06548       num_recs_read = fread(&mit_descriptor[1],
06549                             sizeof(mit_descriptor_type),
06550                             Num_Of_Tbls,
06551                             mod_file_ptr);
06552 
06553       if (num_recs_read != Num_Of_Tbls) {
06554          PRINTMSG(AT_DEF_LINE(module_attr_idx), 726, Error,
06555                   AT_DEF_COLUMN(module_attr_idx),
06556                   AT_OBJ_NAME_PTR(module_attr_idx));
06557          ok = FALSE;
06558          goto EXIT;
06559       }
06560    }
06561 
06562 
06563    if (MD_NUM_ENTRIES(Loc_Name_Tbl) == 1 && !inline_search) { 
06564 
06565       /* There is always 1 entry - the name of the module */
06566 
06567       ok = FALSE;
06568 
06569       if (only_stmt) {
06570          PRINTMSG(AT_DEF_LINE(module_attr_idx), 793, Error,
06571                   AT_DEF_COLUMN(module_attr_idx),
06572                   AT_OBJ_NAME_PTR(module_attr_idx));
06573          AT_DCL_ERR(module_attr_idx) = TRUE;
06574       }
06575       else if (ATP_USE_LIST(module_attr_idx) != NULL_IDX) {  /* rename-list */
06576          PRINTMSG(AT_DEF_LINE(module_attr_idx), 934, Error,
06577                   AT_DEF_COLUMN(module_attr_idx),
06578                   AT_OBJ_NAME_PTR(module_attr_idx));
06579          AT_DCL_ERR(module_attr_idx) = TRUE;
06580       }
06581       else {
06582 
06583          /* There is no only-list or rename-list, so just issue */
06584          /* a warning that the module is empty.                 */
06585 
06586          PRINTMSG(AT_DEF_LINE(module_attr_idx), 867, Warning,
06587                   AT_DEF_COLUMN(module_attr_idx),
06588                   AT_OBJ_NAME_PTR(module_attr_idx));
06589       }
06590       goto EXIT;
06591    }
06592 
06593 # ifdef _DEBUG
06594    if (!inline_search && loc_name_tbl_idx != SCP_LN_LW_IDX(curr_scp_idx)) {
06595       PRINTMSG(AT_DEF_LINE(module_attr_idx), 832, Internal,
06596                AT_DEF_COLUMN(module_attr_idx),
06597                AT_OBJ_NAME_PTR(SCP_ATTR_IDX(curr_scp_idx)));
06598    }
06599 # endif
06600 
06601    /* Add 2 buffer entries between the old and new local name tables.  One */
06602    /* of these is used to hold the all zero word, so that srch_sym_tbl can */
06603    /* be used with the new stuff from the module.                          */
06604 
06605    ++loc_name_tbl_idx;
06606    ++loc_name_tbl_idx;
06607 
06608    old_ln_idx   = loc_name_tbl_idx;
06609 
06610    if (!inline_search) {
06611 
06612       /* Leave space in the constant table so that we can use ntr_const_tbl   */
06613       /* to make sure everything is entered after the current constant table. */
06614 
06615       save_const_tbl_idx  = const_tbl_idx;
06616       const_tbl_idx          += (MD_NUM_ENTRIES(Const_Tbl) + 2);
06617       old_const_tbl_idx   = const_tbl_idx;
06618 
06619       save_const_pool_idx = const_pool_idx;
06620       const_pool_idx           += (MD_NUM_ENTRIES(Const_Pool) + 2);
06621       old_const_pool_idx  = const_pool_idx;
06622    }
06623    else {
06624       save_const_tbl_idx  = NULL_IDX;
06625       save_const_pool_idx = NULL_IDX;
06626    }
06627 
06628    /* KAY - What if we are at the end of the constant pool?  */
06629 
06630 # if defined(_HOST32) 
06631 
06632    /* If this is host32, the table always went out on the 1st index */
06633    /* so make sure it always comes in on a non-daligned index.      */
06634    /* Everything should come out okay that way.  If const_pool_idx  */
06635    /* is double aligned, then the address following it will be      */
06636    /* non-double aligned and exactly what we want.                  */
06637 
06638    while ((((long)&const_pool[const_pool_idx]) % 8) != 0) {
06639       const_pool_idx++;
06640    }
06641    old_const_pool_idx = const_pool_idx;
06642 
06643 # endif
06644 
06645    if (!read_sytb_from_module_file(module_attr_idx,
06646                                    mod_file_ptr,
06647                                    mod_info_tbl)) {
06648 
06649       loc_name_tbl_idx = old_ln_idx - 2;
06650       ok = FALSE;
06651       goto EXIT;
06652    }
06653 
06654    /* Although a constant entry may be larger than one const_tbl entry,      */
06655    /* entries being read from the module info file are all treated as each   */
06656    /* being one const tbl entry in length.  First room must be made for all  */
06657    /* the new entries.  They must all be read in, because if we treated each */
06658    /* as individual entries, we couldn't determine their size, because type  */
06659    /* CHARACTER uses another const tbl entry to tell how long the char is.   */
06660 
06661    /* Allocate mod link table and clear all entries. */
06662 
06663    /* The mod_link_tbl will be used for compression and straightening out    */
06664    /* table indexes.  In simple use semantics, entries will be set, but they */
06665    /* will never be used.  We have to set table entries, because we do not   */
06666    /* know if we will use them until we process all tables in the module.    */
06667 
06668    allocate_mod_link_tbl(0);  /* Let routine determine size. */
06669 
06670    /* Loop and set the local name table entries.  ln_idx is set earlier.     */
06671 
06672 
06673    for (ln_idx = old_ln_idx+1; ln_idx <= loc_name_tbl_idx; ln_idx++) {
06674       LN_NAME_IDX(ln_idx)  = old_name_pool_idx + LN_NAME_IDX(ln_idx);
06675       LN_ATTR_IDX(ln_idx)  = old_attr_tbl_idx + LN_ATTR_IDX(ln_idx);
06676       ML_AT_LN_NAME(LN_ATTR_IDX(ln_idx))  = TRUE;
06677    }
06678 
06679    /* This loops thru the new storage block entries, looking for duplicates  */
06680    /* and also folding in the stack block to the parents and generally       */
06681    /* resolving the storage block entries.  At this point,                   */
06682    /* old_stor_blk_tbl_idx indexes to the end of the storage block table     */
06683    /* before the entries were read up from the module.  stor_blk_tbl_idx     */
06684    /* indexes to the end of the storage block table.  stor_blk_tbl_idx -     */
06685    /* old_stor_blk_tbl_idx, gives the number of new entries in the table.    */
06686    /* To get the original index of a storage block coming in from the module */
06687    /* take (idx - old_stor_blk_tbl_idx).  This is needed to set the correct  */
06688    /* entry in the mod_link_tbl, so that all the new module entries pointing */
06689    /* to the storage block table can be updated in assign_new_idxs_after_    */
06690    /* input.  Set the stor_blk_tbl_idx to the end of the old table, so that  */
06691    /* searches will not search the new entries.                              */
06692 
06693    end_sb_idx   = stor_blk_tbl_idx;
06694    stor_blk_tbl_idx = old_stor_blk_tbl_idx;
06695 
06696    for (idx = stor_blk_tbl_idx+1; idx <= end_sb_idx; idx++) {
06697       SB_NAME_IDX(idx)    = old_name_pool_idx + SB_NAME_IDX(idx);
06698 #ifdef KEY /* Bug 14150 */
06699       int ext_name_idx = SB_EXT_NAME_IDX(idx);
06700       SB_EXT_NAME_IDX(idx)  = ext_name_idx ?
06701         (old_name_pool_idx + ext_name_idx) :
06702   0;
06703 #endif /* KEY Bug 14150 */
06704       SB_HAS_RENAMES(idx) = FALSE;
06705       SB_DEF_LINE(idx)    = AT_DEF_LINE(module_attr_idx);
06706       SB_DEF_COLUMN(idx)  = AT_DEF_COLUMN(module_attr_idx);
06707       SB_SCP_IDX(idx)   = curr_scp_idx;
06708       SB_ORIG_SCP_IDX(idx)  = curr_scp_idx;
06709       SB_LAST_ATTR_LIST(idx)  = NULL_IDX;
06710 
06711       if (SB_FIRST_ATTR_IDX(idx) != NULL_IDX) {
06712          SB_FIRST_ATTR_IDX(idx) = old_attr_tbl_idx + SB_FIRST_ATTR_IDX(idx);
06713       }
06714 
06715       switch (SB_LEN_FLD(idx)) {
06716       case CN_Tbl_Idx:
06717          SB_LEN_IDX(idx)  = old_const_tbl_idx + SB_LEN_IDX(idx);
06718          break;
06719 
06720       case AT_Tbl_Idx:
06721          SB_LEN_IDX(idx)  = old_attr_tbl_idx + SB_LEN_IDX(idx);
06722          break;
06723 
06724       case IR_Tbl_Idx:
06725          SB_LEN_IDX(idx)  = old_ir_tbl_idx + SB_LEN_IDX(idx);
06726          break;
06727 
06728       case IL_Tbl_Idx:
06729          SB_LEN_IDX(idx)  = old_ir_list_tbl_idx + SB_LEN_IDX(idx);
06730          break;
06731 
06732       /* KAY - This case can be removed when we no longer support 3.0 */
06733 
06734       default:
06735          SB_LEN_FLD(idx)  = CN_Tbl_Idx;
06736          SB_LEN_IDX(idx)  = old_const_tbl_idx + SB_LEN_IDX(idx);
06737          break;
06738       }
06739 
06740       /* If we're inline searching we never want to mix storage blocks. */
06741 
06742       if (!inline_search) {
06743          SB_MODULE_IDX(idx) = (SB_MODULE_IDX(idx) == NULL_IDX) ?
06744                                           module_attr_idx :
06745                                           old_attr_tbl_idx + SB_MODULE_IDX(idx);
06746          SB_USE_ASSOCIATED(idx) = TRUE;
06747          srch_sb_idx    = srch_stor_blk_tbl(SB_NAME_PTR(idx), 
06748                                                     SB_NAME_LEN(idx),
06749                                                     curr_scp_idx);
06750       }
06751       else {
06752          srch_sb_idx    = NULL_IDX;
06753 
06754          if (SB_MODULE_IDX(idx) != NULL_IDX) {
06755             SB_MODULE_IDX(idx)  = old_attr_tbl_idx + SB_MODULE_IDX(idx);
06756          }
06757       }
06758 
06759       if (srch_sb_idx == NULL_IDX) { 
06760          sb_idx     = ++stor_blk_tbl_idx;
06761          stor_blk_tbl[sb_idx] = stor_blk_tbl[idx];
06762 
06763       }
06764 
06765       /* If we find a common storage block, it can only have gotten here     */
06766       /* thru use association.   If we have   character*(i) function j()     */
06767       /* where i is host associated, i's storage block does not get copied   */
06768       /* down until attr resolution time.                                    */
06769 
06770       else if (SB_IS_COMMON(idx) &&
06771                (compare_names(AT_OBJ_NAME_LONG(SB_MODULE_IDX(srch_sb_idx)),
06772                               AT_NAME_LEN(SB_MODULE_IDX(srch_sb_idx)),
06773                               AT_OBJ_NAME_LONG(SB_MODULE_IDX(idx)),
06774                               AT_NAME_LEN(SB_MODULE_IDX(idx))) != 0)) {
06775 
06776          /* Mark the new storage block as being defined in multiple scopes.  */
06777          /* Also, mark it as hidden, so only the first storage block will be */
06778          /* found when searches are made for this storage block.  During     */
06779          /* storage_blk_resolution, when this block is found, SB_MERGED_BLK  */
06780          /* will be updated to the end (or start) of the SB_MERGED_BLK list. */
06781          /* Then the original block will be marked SB_DEF_MULT_SCPS.         */
06782          /* final_attr_resolution,  ATD_STOR_BLK_IDX will be updated to      */
06783          /* SB_MERGED_BLK and then SB_DEF_MULT_SCPS will be checked to see   */
06784          /* if ATD_EQUIV needs to be set.  If this is an only_stmt, nothing  */
06785          /* gets changed in the original block and the new block gets        */
06786          /* compressed out.                                                  */
06787 
06788          sb_idx       = ++stor_blk_tbl_idx;
06789          stor_blk_tbl[sb_idx]   = stor_blk_tbl[idx];
06790          SB_DEF_MULT_SCPS(sb_idx) = TRUE;
06791          SB_HIDDEN(sb_idx)    = TRUE;
06792          SB_MERGED_BLK_IDX(sb_idx)  = srch_sb_idx;
06793       }
06794       else { /* This is the same common block from the same module or it     */
06795              /* is a static based or darg block.  Share the block.           */
06796 
06797          sb_idx = srch_sb_idx;
06798       }
06799       
06800       ML_SB_IDX(idx - old_stor_blk_tbl_idx) = sb_idx;
06801    }
06802 
06803    if (keep_module_procs) {
06804 
06805       /* Create a list of all module procedures that can be inlined.       */
06806       /* Save attr_list_idx so we can delete the new list when we're done. */
06807 
06808       save_attr_list_start    = SCP_ATTR_LIST(curr_scp_idx);
06809       save_attr_list_end    = SCP_ATTR_LIST_END(curr_scp_idx);
06810       SCP_ATTR_LIST(curr_scp_idx) = NULL_IDX;
06811       SCP_ATTR_LIST_END(curr_scp_idx) = NULL_IDX;
06812 
06813       assign_new_idxs_after_input(module_attr_idx);
06814 
06815       al_idx        = SCP_ATTR_LIST(curr_scp_idx);
06816       SCP_ATTR_LIST(curr_scp_idx) = save_attr_list_start;
06817       SCP_ATTR_LIST_END(curr_scp_idx) = save_attr_list_end;
06818 
06819       /* Have module procedures to use for inlining.  Mark the  */
06820       /* attrs so they do not get checked for duplicate attrs.  */
06821 
06822       process_procs_for_inlining(al_idx);
06823       free_attr_list(al_idx);
06824    }
06825    else {
06826       assign_new_idxs_after_input(module_attr_idx);
06827    }
06828 
06829    /* We want to use MD_NUM_ENTRIES(Stor_Blk_Tbl) here because we allocated */
06830    /* space for that many entries when we started.  The actual number of    */
06831    /* stor blk entries is most likely less because we collapsed the store   */
06832    /* block table previously.                                               */
06833 
06834    for (idx = 0; idx <= MD_NUM_ENTRIES(Stor_Blk_Tbl); idx++) {
06835       ML_SB_IDX(idx)  = NULL_IDX;
06836    }
06837 
06838 # ifdef _DEBUG
06839    for (sb_idx = old_stor_blk_tbl_idx + 1;
06840            sb_idx <= stor_blk_tbl_idx; sb_idx++) {
06841 
06842       if (SB_LEN_FLD(sb_idx) == CN_Tbl_Idx &&
06843           TYP_TYPE(CN_TYPE_IDX(SB_LEN_IDX(sb_idx))) != Integer) {
06844          print_sb(sb_idx);
06845          print_cn(SB_LEN_IDX(sb_idx));
06846          PRINTMSG(1, 626, Internal, 0, "integer constant SB_LEN_IDX",
06847                   "read_in_module_tbl");
06848       }
06849    }
06850 # endif
06851 
06852    ML_AT_IDX(0)   = old_attr_tbl_idx;
06853    ML_BD_IDX(0)   = old_bounds_tbl_idx;
06854    ML_CN_IDX(0)   = old_const_tbl_idx;
06855    ML_CP_IDX(0)   = old_const_pool_idx;
06856    ML_IL_IDX(0)   = old_ir_list_tbl_idx;
06857    ML_IR_IDX(0)   = old_ir_tbl_idx;
06858    ML_LN_IDX(0)   = SCP_LN_FW_IDX(curr_scp_idx);
06859    ML_NP_IDX(0)   = old_name_pool_idx;
06860    ML_SB_IDX(0)   = old_stor_blk_tbl_idx;
06861    ML_SN_IDX(0)   = old_sec_name_tbl_idx;
06862    ML_SH_IDX(0)   = old_sh_tbl_idx;
06863    ML_TYP_IDX(0)  = old_type_tbl_idx;
06864 
06865 EXIT: 
06866 
06867    TRACE (Func_Exit, "read_in_module_tbl", NULL);
06868 
06869    return(ok);
06870 
06871 }   /* read_in_module_tbl */
06872 
06873 /******************************************************************************\
06874 |*                        *|
06875 |* Description:                     *|
06876 |*                        *|
06877 |* Input parameters:                    *|
06878 |*                        *|
06879 |* Output parameters:                   *|
06880 |*  NONE                      *|
06881 |*                        *|
06882 |* Returns:                     *|
06883 |*                        *|
06884 \******************************************************************************/
06885 static  boolean read_sytb_from_module_file(int      module_attr_idx,
06886              FILE          *mod_file_ptr,
06887              char          *mod_info_tbl)
06888 
06889 {
06890    long     *from_idx;
06891    int       i;
06892    int       idx;
06893    int       j;
06894    int       num_entries;
06895    int       num_recs_read;
06896    boolean     ok   = TRUE;
06897    old_const_tbl_type *old_cn_tbl   = NULL;
06898    old_ir_tbl_type  *old_ir_tbl   = NULL;
06899 #ifdef KEY /* Bug 10177 */
06900    int       save_const_tbl_idx = 0;
06901    int       save_ir_tbl_idx = 0;
06902 #else /* KEY Bug 10177 */
06903    int       save_const_tbl_idx;
06904    int       save_ir_tbl_idx;
06905 #endif /* KEY Bug 10177 */
06906    int       size;
06907 #ifdef KEY /* Bug 10177 */
06908    void     *tbl = 0;
06909 #else /* KEY Bug 10177 */
06910    void     *tbl;
06911 #endif /* KEY Bug 10177 */
06912    tbl_type_type   tbl_type;
06913    long     *to_idx;
06914 
06915 
06916    TRACE (Func_Entry, "read_sytb_from_module_file", NULL);
06917 
06918    /* WARNING:  CHECK_TBL_ALLOC_SIZE may move the table. */
06919 
06920    for (idx = 1; idx <= Num_Of_Tbls; idx++) {
06921       tbl_type    = MD_TBL_TYPE(idx);
06922       num_entries = MD_NUM_ENTRIES(idx);
06923 
06924       if (num_entries > 0) {
06925 
06926          switch (tbl_type) {
06927 
06928          case Attr_Tbl:
06929 
06930             /* If we're reading up a smaller version of the attr table, we */
06931             /* still want to make space for everything.  We'll adjust the  */
06932             /* older version after it has been read in.                    */
06933 
06934             CHECK_TBL_ALLOC_SIZE(attr_tbl, attr_tbl_idx + num_entries);
06935             CHECK_TBL_ALLOC_SIZE(attr_aux_tbl, attr_aux_tbl_idx + num_entries);
06936 
06937             size    = sizeof(attr_tbl_type);
06938             tbl     = &attr_tbl[attr_tbl_idx + 1];
06939             attr_tbl_idx       += num_entries;
06940             attr_aux_tbl_idx   += num_entries;
06941             break;
06942 
06943          case Bounds_Tbl:
06944             CHECK_TBL_ALLOC_SIZE(bounds_tbl, bounds_tbl_idx + num_entries);
06945             size    = sizeof(bounds_tbl_type);
06946             tbl     = &bounds_tbl[bounds_tbl_idx + 1];
06947             bounds_tbl_idx     += num_entries;
06948             break;
06949 
06950          case Const_Tbl:
06951             CHECK_TBL_ALLOC_SIZE(const_tbl, const_tbl_idx + num_entries);
06952 
06953             if (! MD_NEW_CONST_TBL) {  /* KAY - What version ?? */
06954                size = sizeof(old_const_tbl_type);
06955                old_cn_tbl = (old_const_tbl_type *)malloc(size * num_entries);
06956                tbl  = old_cn_tbl;
06957                save_const_tbl_idx = const_tbl_idx + 1;
06958             }
06959             else {
06960                size = sizeof(const_tbl_type);
06961                tbl  = &const_tbl[const_tbl_idx + 1];
06962             }
06963             const_tbl_idx      += num_entries;
06964             break;
06965 
06966          case Const_Pool:
06967             CHECK_TBL_ALLOC_SIZE(const_pool, const_pool_idx + num_entries);
06968             size    = sizeof(const_pool_type);
06969             tbl     = &const_pool[const_pool_idx + 1];
06970             const_pool_idx     += num_entries;
06971             break;
06972 
06973          case Ir_List_Tbl:
06974             CHECK_TBL_ALLOC_SIZE(ir_list_tbl, ir_list_tbl_idx + num_entries);
06975             size    = sizeof(ir_list_tbl_type);
06976             tbl     = &ir_list_tbl[ir_list_tbl_idx + 1];
06977             ir_list_tbl_idx    += num_entries;
06978             break;
06979 
06980          case Ir_Tbl:
06981             CHECK_TBL_ALLOC_SIZE(ir_tbl, ir_tbl_idx + num_entries);
06982 
06983             if (MD_VERSION_NUM > MD_LAST_4_0_VERSION) {
06984                size   = sizeof(ir_tbl_type);
06985                tbl    = &ir_tbl[ir_tbl_idx + 1];
06986             }
06987             else {
06988                size   = sizeof(old_ir_tbl_type);
06989                old_ir_tbl = (old_ir_tbl_type *)malloc(size * num_entries);
06990                tbl    = old_ir_tbl;
06991                save_ir_tbl_idx  = ir_tbl_idx + 1;
06992             }
06993             ir_tbl_idx         += num_entries;
06994             break;
06995 
06996          case Name_Pool:
06997             CHECK_TBL_ALLOC_SIZE(name_pool, name_pool_idx + num_entries);
06998             size    = sizeof(name_pool_type);
06999             tbl     = &name_pool[name_pool_idx + 1];
07000             name_pool_idx      += num_entries;
07001             break;
07002 
07003          case Sec_Name_Tbl:
07004             CHECK_TBL_ALLOC_SIZE(sec_name_tbl, sec_name_tbl_idx + num_entries);
07005             size    = sizeof(sec_name_tbl_type);
07006             tbl     = &sec_name_tbl[sec_name_tbl_idx + 1];
07007             sec_name_tbl_idx   += num_entries;
07008             break;
07009 
07010          case Sh_Tbl:
07011             size    = sizeof(sh_tbl_type);
07012 
07013             if (keep_module_procs || inline_search) {
07014                CHECK_TBL_ALLOC_SIZE(sh_tbl, sh_tbl_idx + num_entries);
07015                tbl    = &sh_tbl[sh_tbl_idx + 1];
07016                sh_tbl_idx      += num_entries;
07017             }
07018             else {  /* Skip this table - Not getting module procedures. */
07019 
07020                if (mod_info_tbl != NULL) {  /* Copying from elf buffer */
07021                   mod_info_tbl += (size * num_entries);
07022                   continue;
07023                }
07024                else if (!FSEEK(mod_file_ptr, (size * num_entries), SEEK_CUR)) {
07025                   ok = FALSE;  /* Let error message issue.  Bad file. */
07026                }
07027                else {
07028                   continue;
07029                }
07030                break;
07031             }
07032             break;
07033 
07034          case Stor_Blk_Tbl:
07035             CHECK_TBL_ALLOC_SIZE(stor_blk_tbl, stor_blk_tbl_idx + num_entries);
07036             size    = sizeof(stor_blk_tbl_type);
07037             tbl     = &stor_blk_tbl[stor_blk_tbl_idx + 1];
07038             stor_blk_tbl_idx   += num_entries;
07039             break;
07040 
07041          case Type_Tbl:
07042             CHECK_TBL_ALLOC_SIZE(type_tbl, type_tbl_idx + num_entries);
07043             size    = sizeof(type_tbl_type);
07044             tbl     = &type_tbl[type_tbl_idx + 1];
07045             type_tbl_idx       += num_entries;
07046             break;
07047 
07048          case Loc_Name_Tbl:
07049             CHECK_TBL_ALLOC_SIZE(loc_name_tbl, loc_name_tbl_idx + num_entries);
07050             size    = sizeof(loc_name_tbl_type);
07051             tbl     = &loc_name_tbl[loc_name_tbl_idx + 1];
07052             loc_name_tbl_idx   += num_entries;
07053             break;
07054 
07055          default:
07056             ok = FALSE;
07057             PRINTMSG(AT_DEF_LINE(module_attr_idx), 726, Error,
07058                      AT_DEF_COLUMN(module_attr_idx),
07059                      AT_OBJ_NAME_PTR(module_attr_idx));
07060             goto EXIT;
07061          }
07062    
07063          if (mod_info_tbl != NULL) {  /* Copying from elf buffer */
07064             (void) memcpy(tbl,
07065                          (char *) mod_info_tbl,
07066                          size * num_entries);
07067             mod_info_tbl += (size * num_entries);
07068          }
07069          else {
07070             num_recs_read = fread(tbl,
07071                                   size,
07072                                   num_entries,
07073                                   mod_file_ptr);
07074 
07075             if (num_recs_read != num_entries) {
07076                ok = FALSE;
07077                PRINTMSG(AT_DEF_LINE(module_attr_idx), 726, Error,
07078                         AT_DEF_COLUMN(module_attr_idx),
07079                         AT_OBJ_NAME_PTR(module_attr_idx));
07080                break;  /* File is bad - exit */
07081             }
07082          }
07083 
07084          if (tbl_type == Ir_Tbl && MD_VERSION_NUM <= MD_LAST_4_0_VERSION) {
07085 
07086             for (i = 0; i < num_entries; i++) {
07087                to_idx = (long *) &(ir_tbl[save_ir_tbl_idx+i]);
07088                from_idx = (long *) &(old_ir_tbl[i]);
07089 
07090 # if defined(_HOST32)
07091                to_idx[0] = from_idx[0];
07092                to_idx[1] = from_idx[1];
07093                to_idx[2] = 0;
07094                to_idx[3] = 0;
07095                to_idx[4] = from_idx[2];
07096                to_idx[5] = from_idx[3];
07097                to_idx[6] = from_idx[4];
07098                to_idx[7] = from_idx[5];
07099 # else
07100                to_idx[0] = from_idx[0];
07101                to_idx[1] = 0;
07102                to_idx[2] = from_idx[1];
07103                to_idx[3] = from_idx[2];
07104 # endif
07105                IR_RANK(save_ir_tbl_idx+i) = OLD_IR_RANK(i);
07106                IR_DV_DIM(save_ir_tbl_idx+i) = OLD_IR_DV_DIM(i);
07107                IR_OPR(save_ir_tbl_idx+i)  = OLD_IR_OPR(i);
07108             }
07109             free(old_ir_tbl);
07110          }
07111 
07112          if (tbl_type == Const_Tbl) {
07113             if (! MD_NEW_CONST_TBL &&
07114                 old_cn_tbl != NULL) {
07115                for (i = 0; i < num_entries; i++) {
07116                   to_idx = (long *) &(const_tbl[save_const_tbl_idx+i]);
07117                   from_idx = (long *) &(old_cn_tbl[i]);
07118                   Pragma("_CRI shortloop")
07119                   for (j = 0; j < OLD_NUM_CN_WDS; j++) {
07120                      to_idx[j] = from_idx[j];
07121                   }
07122                }
07123                free(old_cn_tbl);
07124             }
07125          }
07126       }
07127    }
07128 
07129 EXIT:
07130 
07131    TRACE (Func_Exit, "read_sytb_from_module_file", NULL);
07132 
07133    return(ok);
07134 
07135 }  /* read_sytb_from_module_file */
07136 
07137 # if defined(_TARGET_OS_SOLARIS) && defined(_MODULE_TO_DOT_o)
07138 
07139 /******************************************************************************\
07140 |*                        *|
07141 |* Description:                     *|
07142 |*  srch_elf_file_for_module_tbl searches SPARC elf files for module      *|
07143 |*  information tables.                                                   *|
07144 |*                        *|
07145 |* Input parameters:                    *|
07146 |*  module_attr_idx -> Attr index of module to search for.          *|
07147 |*  fp_file_idx -> File path table index to entry describing elf file *|
07148 |*         to seach.                                          *|
07149 |*                        *|
07150 |* Output parameters:                   *|
07151 |*  NONE                      *|
07152 |*                        *|
07153 |* Returns:                     *|
07154 |*  TRUE  -> The module has been found.  Mod information table has been   *|
07155 |*           completely read in.                                          *|
07156 |*  FALSE -> The module was not found.                                    *|
07157 |*                        *|
07158 \******************************************************************************/
07159 static  boolean srch_elf_file_for_module_tbl(int   module_attr_idx,
07160                int   fp_file_idx)
07161 
07162 {
07163    int     fd;    /* File descriptor of ELF file      */
07164    boolean   found    = FALSE;
07165 
07166    Elf    *file_elfd; /* ELF descriptor for whole file    */
07167    Elf    *obj_elfd;  /* ELF descriptor for curr. object  */
07168    Elf_Cmd   elf_cmd; /* ELF command to read from file    */
07169    Elf32_Ehdr *ehdr;    /* Header from current object       */
07170 
07171 
07172    TRACE (Func_Entry, "srch_elf_file_for_module_tbl", NULL);
07173 
07174    if ((fd = open(FP_NAME_PTR(fp_file_idx), O_RDONLY, 0)) == -1) {
07175 
07176       /* BHJ - need my 126 message here to say bad file. */
07177 
07178       return(found);
07179    }
07180 
07181    /* Check ELF version.   See elf(3E).  */
07182    
07183    /* Notice that the elf_version() call is the very first call to the ELF */
07184    /* library in the whole program.  It has no idea that a file has been   */
07185    /* opened, much less that the resulting fd is going to get passed to    */
07186    /* the ELF library.  It's just a check between the version of ELF the   */
07187    /* code was compiled with (from the <libelf.h> #include file), and the  */
07188    /* version of ELF the ELF library it's linked with was compiled with.   */
07189 
07190    if (elf_version(EV_CURRENT) == EV_NONE) {
07191 
07192       /* BHJ - Something is wrong with the file.  - See above comment.     */
07193       /*       May want a more descriptive message, like something is      */
07194       /*       wrong with the file.                                        */
07195 
07196       return(found);
07197    }
07198 
07199    /* Process the file, which may be either a simple file or an archive of */
07200    /* files.  The outer while{} loop will iterate once for a simple file,  */
07201    /* and as many times as there are files in the archive for an archive   */
07202    /* file.  In either case, anything that is not an ELF object file will  */
07203    /* be skipped, due to the elf32_getehdr() call returning zero.          */
07204 
07205    /* See elf(3E), elf_begin(3E), elf32_getehdr(3E), elf_next(3E),         */
07206    /* elf_end(3E).                                                         */
07207 
07208    /* This needs to be ELF_C_READ so that we can process archive files.    */
07209    /* If it is switched to ELF_C_RDWR, this code will not allow archive    */
07210    /* files here.                                                          */
07211 
07212    elf_cmd  = ELF_C_READ;
07213    file_elfd  = elf_begin(fd, elf_cmd, ((Elf *) NULL));
07214 
07215    while ((obj_elfd = elf_begin(fd, elf_cmd, file_elfd)) != ((Elf *) NULL)) {
07216 
07217       /* If you're not working with an ELF file, it's the elf32_getehdr()  */
07218       /* call that tells you so.  It yields back a ((Elf32_Ehdr *) NULL)   */
07219       /* in that case.  Actually, I think I may have coded it as a check   */
07220       /* against a 0 (zero) return value, but it's really a NULL pointer.  */
07221 
07222 
07223       if ((ehdr = elf32_getehdr(obj_elfd)) != 0) {
07224 
07225          /* This is an ELF object file.  Process it. */
07226 
07227          FP_CLASS(fp_file_idx)  = Elf_File_Fp;
07228 
07229          if (do_elf_object(obj_elfd, 
07230                            ehdr, 
07231                            module_attr_idx,
07232                            fp_file_idx)) {
07233             found = TRUE;
07234             break;
07235          }
07236       }
07237 
07238       elf_cmd = elf_next(obj_elfd);
07239       elf_end(obj_elfd);
07240    }
07241 
07242    elf_end(file_elfd);
07243    close(fd);
07244 
07245    TRACE (Func_Exit, "srch_elf_file_for_module_tbl", NULL);
07246 
07247    return(found);
07248 
07249 } /* srch_elf_file_for_module_tbl */
07250 # endif
07251 
07252 /******************************************************************************\
07253 |*                        *|
07254 |* Description:                     *|
07255 |*  Process one object module from an ELF file.                           *|
07256 |*                        *|
07257 |* Input parameters:                    *|
07258 |*  obj_elfd  -> Elf descriptor for current object.         *|
07259 |*  ehdr    -> Elf header for current object.               *|
07260 |*  module_attr_idx -> Attr index of module to search for.          *|
07261 |*                        *|
07262 |* Output parameters:                   *|
07263 |*  NONE                      *|
07264 |*                        *|
07265 |* Returns:                     *|
07266 |*  TRUE  -> The module has been found.  Mod information table has been   *|
07267 |*           completely read in.                                          *|
07268 |*  FALSE -> The module was not found.                                    *|
07269 |*                        *|
07270 \******************************************************************************/
07271 # if defined(_TARGET_OS_SOLARIS) && defined(_MODULE_TO_DOT_o)
07272 static  boolean do_elf_object(Elf   *obj_elfd,
07273             Elf32_Ehdr  *ehdr,
07274             int    module_attr_idx,
07275             int    fp_file_idx)
07276 {
07277 
07278    Elf_Data   *data;  /* Current section's data           */
07279    boolean     found  = FALSE;
07280    Elf_Scn    *scn; /* Current section                  */
07281    Elf32_Shdr   *shdr;  /* Current section's header         */
07282 
07283 
07284    TRACE (Func_Entry, "do_elf_object", NULL);
07285 
07286    /* Process each section of the current object.  * See elf_nextscn(3E). */
07287 
07288    scn = (Elf_Scn *) NULL;
07289 
07290    while ((scn = elf_nextscn(obj_elfd, scn)) != ((Elf_Scn *) NULL)) {
07291 
07292       /* If this section isn't for us, skip it.  * See elf32_getshdr(3E). */
07293 
07294       if ((shdr = elf32_getshdr(scn)) == ((Elf32_Shdr *) NULL)) {
07295           continue;
07296       }
07297 
07298 # if 0
07299       {
07300          char       *s_name;
07301 
07302          /* Tell the section's name.  It's stored in the section header */
07303          /* string table.   See elf_strptr(3E).                         */
07304 
07305          s_name = elf_strptr(obj_elfd, ehdr->e_shstrndx,
07306                              ((size_t) shdr->sh_name));
07307          printf("Elf section: '%s', type %u, flags %#x, size %u\n",
07308                 ((s_name == ((char *) NULL)) ? "(none)" : s_name),
07309                 shdr->sh_type, shdr->sh_flags, shdr->sh_size);
07310       }
07311 # endif
07312 
07313       /* Skip sections that aren't .note ones. See /usr/include/sys/elf.h. */
07314 
07315       if (shdr->sh_type != SHT_NOTE) {
07316           continue;
07317       }
07318 
07319 # if 0
07320       printf("This is a NOTES section.  Contents:\n");
07321 # endif
07322 
07323       /* Go through each data object in the section.  Typically,   */
07324       /* this loop will execute exactly once.  The only time it    */
07325       /* would iterate more than one time would be if the section  */
07326       /* were currently being built up by multiple calls to the    */
07327       /* elf_newdata(3E) routine during the creation of a new      */
07328       /* Elf file.                                                 */
07329 
07330       /* We skip data blocks that aren't made of plain vanilla     */
07331       /* bytes, because we don't know how to handle them.  They    */
07332       /* wouldn't be ours, anyway, so it's okay to do this.        */
07333       /* See elf_getdata(3E).                                      */
07334 
07335       data = ((Elf_Data *) NULL);
07336 
07337       while ((data = elf_getdata(scn, data)) != ((Elf_Data *) NULL)) {
07338 
07339          if (data->d_type == ELF_T_BYTE) {
07340 
07341             if (do_elf_notes_section(data, module_attr_idx, fp_file_idx)) {
07342                found = TRUE;
07343                break;
07344             }
07345          }
07346       }
07347    }  /* once-per-section loop */
07348 
07349    TRACE (Func_Exit, "do_elf_object", NULL);
07350 
07351    return(found);
07352 
07353 } /* do_elf_object */
07354 
07355 /******************************************************************************\
07356 |*                        *|
07357 |* Description:                     *|
07358 |*      Process one .notes section from an ELF file.            *|
07359 |*                        *|
07360 |*  Process each successive note in this .note section.  A          *|
07361 |*  single note looks like this:                                      *|
07362 |*                        *|
07363 |*    1 32-bit word:   length of name (below)                         *|
07364 |*    1 32-bit word:   length of descriptor (below)                   *|
07365 |*    1 32-bit word:   type of note                 *|
07366 |*    0 or more bytes: name, padded with bytes of zero to             *|
07367 |*                     the next 32-bit word boundary                  *|
07368 |*    0 or more bytes: descriptor (the data in this note),            *|
07369 |*                     padded with bytes of zero to the               *|
07370 |*                     next 32-bit boundary                           *|
07371 |*                        *|
07372 |*  The name and descriptor lengths (the first two words)             *|
07373 |*  do not include the trailing padding bytes for the name            *|
07374 |*  and the descriptor.  If the name (or descriptor) is an            *|
07375 |*  even multiple of 32-bit words long (including zero),              *|
07376 |*  no padding is added.  Name, descriptor, and type are              *|
07377 |*  all chosen by the originator.  The name is typically              *|
07378 |*  that of the originator.  The type can be used by an               *|
07379 |*  originator to differentiate amongst multiple kinds of             *|
07380 |*  data that said originator might place in the descriptor.          *|
07381 |*                        *|
07382 |*  Multiple notes, from multiple originators, may occur in           *|
07383 |*  a .note section.  When traversing the notes in a section,         *|
07384 |*  programs should pay attention to those they understand,           *|
07385 |*  and skip those they don't.                                        *|
07386 |*                        *|
07387 |*  This particular program removes entries that match "Cray          *|
07388 |*  Research, Incorporated", and have type NOTE_TYPE.  Such           *|
07389 |*  entries contain module information that originated in             *|
07390 |*  .o files created by the SPARC f90 compiler, and was               *|
07391 |*  included in an executable by ld(1).  Since such module            *|
07392 |*  information is of no use in an executable, this utility           *|
07393 |*  was created to remove it.                                         *|
07394 |*                        *|
07395 |*  See /usr/include/sys/elf.h, _SunOS 5.3 Linker and                 *|
07396 |*      Libraries Manual_ (hardcopy or AnswerBook),                   *|
07397 |*      chapter 5, page 137 ("Note Section").                         *|
07398 |*                        *|
07399 |*                        *|
07400 |* Input parameters:                    *|
07401 |*  data    -> Pointer to in copy memory of whole notes section.  *|
07402 |*  module_attr_idx -> Attr index of module to search for.          *|
07403 |*                        *|
07404 |* Output parameters:                   *|
07405 |*  NONE                      *|
07406 |*                        *|
07407 |* Returns:                     *|
07408 |*  TRUE  -> The module has been found.  Mod information table has been   *|
07409 |*           completely read in.                                          *|
07410 |*  FALSE -> The module was not found.                                    *|
07411 |*                        *|
07412 \******************************************************************************/
07413 static  boolean do_elf_notes_section(Elf_Data   *data,
07414              int     module_attr_idx,
07415              int     fp_file_idx)
07416 {
07417 
07418    Elf32_Word    data_off_src;  /* # of source data bytes done      */
07419    boolean     found;   /* TRUE if found module             */
07420    char     *mod_info_tbl;  /* Ptr to .note descriptor          */
07421    Elf32_Nhdr   *n_hdr;   /* .note block header               */
07422    char     *n_name_ptr;  /* Pointer to name in .note block   */
07423    unsigned int      namesz;  /* Bytes of name to print           */
07424    Elf32_Word    note_size; /* Size of this .note               */
07425 
07426 
07427    /* RUP_BYTES() rounds a byte count up to the next Elf32_Word boundary.  */
07428 
07429 # define BRND_SIZE  (sizeof(Elf32_Word))
07430 # define RUP_BYTES(n) (((n) + BRND_SIZE - 1) & ~(BRND_SIZE - 1))
07431 
07432 
07433    TRACE (Func_Entry, "do_elf_notes_section", NULL);
07434 
07435 # if 0
07436 
07437    /* Tell about the size of the data block.  See /usr/include/libelf.h.  */
07438 
07439    printf("  %d bytes at section offset %u:\n", data->d_size, data->d_off);
07440 
07441 # endif
07442 
07443    data_off_src = 0;
07444    found  = FALSE;
07445 
07446    while (data_off_src < data->d_size) {
07447 
07448       /* Based on the note header that starts at the current    */
07449       /* location in this data block, find the size of the      */
07450       /* entry, and get a pointer to the name.                  */
07451 
07452       n_hdr      = (Elf32_Nhdr *) (((char *) data->d_buf) + data_off_src);
07453       note_size  = sizeof(Elf32_Nhdr)
07454                    + RUP_BYTES(n_hdr->n_namesz)
07455                    + RUP_BYTES(n_hdr->n_descsz);
07456       n_name_ptr = (char *) ((void *) (n_hdr + 1));
07457       namesz   = n_hdr->n_namesz
07458                      - ((*(n_name_ptr + n_hdr->n_namesz - 1) == '\0') ? 1 : 0);
07459       mod_info_tbl = n_name_ptr + RUP_BYTES(n_hdr->n_namesz);
07460 
07461 #     if 0
07462 
07463       {
07464          unsigned int    namesz;     /* Bytes of name to print           */
07465          unsigned int    len;        /* Bytes of .note descriptor done   */
07466 
07467          if (data_off_src != 0) {
07468              printf("\n");
07469          printf("    Name len: %u\n", n_hdr->n_namesz);
07470          printf("    Data len: %u\n", n_hdr->n_descsz);
07471          printf("    Type:     %u\n", n_hdr->n_type);
07472 
07473          /*
07474           * Adjust for a possible trailing NUL byte on the
07475           * originator name.  We don't want to send it to
07476           * printf(3C).
07477           */
07478          printf("    Name:     '%*.*s'\n", namesz, namesz, n_name_ptr);
07479 
07480          /* Report the descriptor, 8 bytes per line. */
07481 
07482 
07483          for (len = 0; len < n_hdr->n_descsz; len++, n_desc_ptr++) {
07484 
07485              if (len == 0) {
07486                  printf("    Desc:    ");
07487              }
07488              else if ((len & 0x7) == 0) {
07489                  printf("\n             ");
07490              }
07491              printf(" %02x", (((int) *n_desc_ptr) & 0xFF));
07492          }
07493          if (len != 0)
07494              printf("\n");
07495          }
07496       }
07497 # endif
07498 
07499       /* Is this CRI SPARC f90 module information? */
07500 
07501       if (n_hdr->n_type == NOTE_TYPE
07502          && memcmp(n_name_ptr, NOTE_ORIG_NAME, NOTE_ORGNAM_LEN) == 0) {
07503 
07504          /* note_size bytes is the size of the module information.         */
07505          /* The elf data routine brings in the whole table to memory.      */
07506          /* Check the name to see if this is the module we're looking for. */
07507 
07508          (void) memcpy((long *) &mit_header.wd[0], 
07509                        ((char *) mod_info_tbl),
07510                        sizeof(mit_header_type));
07511 
07512          if (compare_names(AT_OBJ_NAME_LONG(module_attr_idx),
07513                            AT_NAME_LEN(module_attr_idx),
07514                            MD_NAME_LONG,
07515                            MD_NAME_LEN) == 0) {
07516 
07517            /* Found it.  Copy memory so we can use it. */
07518            /* Bump the pointer past mit_header.        */
07519 
07520            mod_info_tbl += sizeof(mit_header_type);
07521 
07522            read_in_module_tbl(fp_file_idx,
07523                               module_attr_idx,
07524                               NULL,      /* No file pointer */
07525                               mod_info_tbl);
07526            found = TRUE;
07527            break;
07528         }
07529      }
07530 
07531      /* Find the next note's offset.                           */
07532      /* note_size is the size of the module information table. */
07533 
07534      data_off_src += note_size;
07535 
07536    }  /* once-per-note loop */
07537 
07538    TRACE (Func_Exit, "do_elf_notes_section", NULL);
07539 
07540    return(found);
07541 
07542 } /* do_elf_notes_section */
07543 # endif
07544 
07545 /******************************************************************************\
07546 |*                        *|
07547 |* Description:                     *|
07548 |*  Reassigns the indexes in the tables after a module has been read in.  *|
07549 |*                        *|
07550 |* Input parameters:                    *|
07551 |*  NONE                      *|
07552 |*                        *|
07553 |* Output parameters:                   *|
07554 |*  NONE                      *|
07555 |*                        *|
07556 |* Returns:                     *|
07557 |*  NOTHING                     *|
07558 |*                        *|
07559 \******************************************************************************/
07560 static void  assign_new_idxs_after_input(int  module_attr_idx)
07561 
07562 {
07563    int    al_idx;
07564    int    at_idx    = attr_tbl_idx - MD_NUM_ENTRIES(Attr_Tbl);
07565    int    attr_idx;
07566    int    bd_idx    = bounds_tbl_idx - MD_NUM_ENTRIES(Bounds_Tbl);
07567    int    bounds_idx;
07568    int    cn_idx    = const_tbl_idx - MD_NUM_ENTRIES(Const_Tbl);
07569    int    column;
07570    int    const_idx;
07571    int    cp_idx    = const_pool_idx - MD_NUM_ENTRIES(Const_Pool);
07572    int    dim;
07573    int    il_idx    = ir_list_tbl_idx - MD_NUM_ENTRIES(Ir_List_Tbl);
07574    int    ir_idx    = ir_tbl_idx - MD_NUM_ENTRIES(Ir_Tbl);
07575    int    line;
07576    int    list_idx;
07577    int    mod_idx;
07578    int    name_idx;
07579    int    new_module_idx;
07580    int    np_idx    = name_pool_idx - MD_NUM_ENTRIES(Name_Pool);
07581    int    old_cn_idx;
07582    int    old_il_idx;
07583    int    save_il_free_list;
07584    int    sh_idx;
07585    int    sn_idx    = sec_name_tbl_idx-MD_NUM_ENTRIES(Sec_Name_Tbl);
07586    int    sn_name_idx;
07587    int    stmt_idx;
07588    int    typ_idx   = type_tbl_idx - MD_NUM_ENTRIES(Type_Tbl);
07589    int    type_idx;
07590 
07591 
07592    TRACE (Func_Entry, "assign_new_idxs_after_input", NULL);
07593 
07594    line   = AT_DEF_LINE(module_attr_idx);
07595    column = AT_DEF_COLUMN(module_attr_idx);
07596 
07597    if (keep_module_procs || inline_search) {
07598       sh_idx  =  sh_tbl_idx - MD_NUM_ENTRIES(Sh_Tbl);
07599    }
07600    else {
07601       sh_idx  = NULL_IDX;
07602    }
07603 
07604 # ifdef _DEBUG
07605    if (at_idx < 0) {
07606       PRINTMSG(1, 626, Internal, 0, "positive at_idx",
07607                "assign_new_idxs_after_input");
07608    }
07609 
07610    if (bd_idx < 0) {
07611       PRINTMSG(1, 626, Internal, 0, "positive bd_idx",
07612                "assign_new_idxs_after_input");
07613    }
07614 
07615    if (cn_idx < 0) {
07616       PRINTMSG(1, 626, Internal, 0, "positive cn_idx",
07617                "assign_new_idxs_after_input");
07618    }
07619 
07620    if (cp_idx < 0) {
07621       PRINTMSG(1, 626, Internal, 0, "positive cp_idx",
07622                "assign_new_idxs_after_input");
07623    }
07624 
07625    if (il_idx < 0) {
07626       PRINTMSG(1, 626, Internal, 0, "positive il_idx",
07627                "assign_new_idxs_after_input");
07628    }
07629 
07630    if (ir_idx < 0) {
07631       PRINTMSG(1, 626, Internal, 0, "positive ir_idx",
07632                "assign_new_idxs_after_input");
07633    }
07634 
07635    if (np_idx < 0) {
07636       PRINTMSG(1, 626, Internal, 0, "positive np_idx",
07637                "assign_new_idxs_after_input");
07638    }
07639 
07640    if (sn_idx < 0) {
07641       PRINTMSG(1, 626, Internal, 0, "positive sn_idx",
07642                "assign_new_idxs_after_input");
07643    }
07644 
07645    if (typ_idx < 0) {
07646       PRINTMSG(1, 626, Internal, 0, "positive typ_idx",
07647                "assign_new_idxs_after_input");
07648    }
07649 # endif
07650 
07651 
07652    /* Keep old_cn_idx because we will be increasing the size of the constant */
07653    /* table entry and we don't want to overwrite those indexes.              */
07654    /* Also keep old_il_idx for the same reason.                              */
07655 
07656    old_cn_idx = const_tbl_idx;
07657    old_il_idx = ir_list_tbl_idx;
07658 
07659