Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
w2c_driver.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 /* ====================================================================
00037  * ====================================================================
00038  *
00039  *
00040  * Revision history:
00041  *  07-Oct-95 - Original Version
00042  *
00043  * Description:
00044  *
00045  *  Defines an interface for a DSO version of whirl2c, with facilities
00046  *  for translating a PU at a time or arbitrary subexpressions.
00047  *
00048  *  Note that before any of these routines can be called, general
00049  *  WHIRL accessor routine initiation must have occurred. 
00050  *  Furthermore, there is no longer any concept of a .B input file
00051  *  (although we assume there may be a .B input file-name), only a
00052  *  WN* input tree and SYMTABs.
00053  *
00054  * ====================================================================
00055  * ====================================================================
00056  */
00057 
00058 #ifdef _KEEP_RCS_ID
00059 #endif /* _KEEP_RCS_ID */
00060 
00061 #include <sys/elf_whirl.h>  /* for WHIRL_REVISION */
00062 #include <time.h>
00063 #include "whirl2c_common.h" /* For defs.h, config.h, erglob.h, etc. */
00064 #include "config_clist.h"   /* For CLIST command line parameters */
00065 #include "config_list.h"    /* For List_Cite */
00066 #include "w2cf_parentize.h" /* For W2CF_Parent_Map and W2FC_Parentize */
00067 #include "file_util.h"      /* For Last_Pathname_Component */
00068 #include "flags.h"          /* for OPTION_GROUP */
00069 #include "timing.h"         /* Start/Stop Timer */
00070 #include "wn_lower.h"       /* For lowering Fortran specific operations */
00071 
00072 #include "PUinfo.h"
00073 #include "ty2c.h"
00074 #include "st2c.h"
00075 #include "tcon2c.h"
00076 #include "wn2c.h"
00077 #include "w2c_driver.h"
00078 #include "unparse_target_c.h"
00079 
00080 #include <string>
00081 #include <stdio.h>
00082 
00083 /* Avoid errors due to uses of "int" in stdio.h macros.
00084  */
00085 #undef int
00086 
00087 //the maximum line length for the global_data.c file
00088 #define MAX_LINE_LEN 2000
00089 
00090 
00091 /* ====================================================================
00092  *
00093  * Local data and macros.
00094  *
00095  * ====================================================================
00096  */
00097 
00098 /* Default extensions for input/outfile files: */
00099 static const char *W2C_File_Extension[W2C_NUM_FILES] = 
00100 {
00101    ".c",       /* original input file */
00102    ".w2c.h",   /* .h output file */
00103    ".w2c.c",   /* .c output file */
00104    ".w2c.loc",  /* .loc output file */
00105    ".global_data.c", /* initialization input file */
00106 };
00107 
00108 /* CITE extensions for input/outfile files: */
00109 static const char *W2C_Cite_Extension[W2C_NUM_FILES] = 
00110 {
00111    ".c",                /* original input file */
00112    "-after-lno.h",      /* .c output file */
00113    "-after-lno.c",      /* .h output file */
00114    ".loc",              /* .loc output file */
00115    ".global_data.c", /* initialization input file */
00116 };
00117 
00118 /* ProMPF extensions for input/outfile files: */
00119 static const char *W2C_Prompf_Extension[W2C_NUM_FILES] = 
00120 {
00121    ".c",         /* original input file */
00122    ".mh",        /* transformed header file */
00123    ".m",         /* transformed source file */
00124    ".anl_srcpos" /* srcpos mapping (temporary) output file */
00125 };
00126 
00127 /* Get the right extension: */
00128 #define W2C_Extension(i) \
00129         (W2C_Prompf_Emission? W2C_Prompf_Extension[i] : \
00130          (List_Cite ? W2C_Cite_Extension[i] : W2C_File_Extension[i]))
00131 
00132 
00133 /* statements that can be skipped in w2c translation
00134  */
00135 #define W2C_MAX_SKIP_ITEMS 128
00136 static W2CF_SKIP_ITEM Skip[W2C_MAX_SKIP_ITEMS+1];
00137 static INT Next_Skip_Item = 0;
00138 
00139 
00140 /* W2C status information */
00141 static BOOL        W2C_Outfile_Initialized = FALSE;
00142 static BOOL        W2C_Initialized = FALSE;
00143 static CONTEXT     Global_Context = INIT_CONTEXT;
00144 static const char *W2C_Progname = "";
00145 static const char *W2C_File_Name[W2C_NUM_FILES] = 
00146                                           {NULL, NULL, NULL, NULL};
00147 static BOOL        File_Is_Created[W2C_NUM_FILES] = 
00148                                           {FALSE, FALSE, FALSE, FALSE, FALSE};
00149 static MEM_POOL     W2C_Parent_Pool;
00150 
00151 /* External data set through command-line options */
00152 FILE *W2C_File[W2C_NUM_FILES] = {NULL, NULL, NULL, NULL};
00153 BOOL  W2C_Enabled = TRUE;           /* Invoke W2C */
00154 BOOL  W2C_Verbose = TRUE;           /* Show translation information */
00155 BOOL  W2C_No_Pragmas = FALSE;       /* Do not emit pragmas */
00156 BOOL  W2C_Emit_Adims = FALSE;       /* Emit comments for array dims */
00157 BOOL  W2C_Emit_Prefetch = FALSE;    /* Emit comments for prefetches */
00158 BOOL  W2C_Emit_All_Regions = FALSE; /* Emit cmplr-generated regions */
00159 BOOL  W2C_Emit_Linedirs = FALSE;    /* Emit preproc line-directives */
00160 BOOL  W2C_Emit_Nested_PUs = FALSE;  /* Emit code for nested PUs */
00161 BOOL  W2C_Emit_Frequency = FALSE;   /* Emit feedback frequency info */
00162 BOOL  W2C_Emit_Cgtag = FALSE;       /* Emit codegen tags for loop */
00163 BOOL  W2C_Lower_Fortran = FALSE;    /* Lower Fortran intrinsics and io */
00164 BOOL  W2C_Emit_Omp = FALSE;         /* Force OMP pragmas wherever possible */
00165 INT32 W2C_Line_Length = 0;   /* Max output line length; zero==default */
00166 
00167 /* External data set through the API or otherwise */
00168 BOOL          W2C_Only_Mark_Loads = FALSE; /* Only mark, do not xlate loads */
00169 BOOL          W2C_Purple_Emission = FALSE; /* Emitting purple extracted srcs */
00170 BOOL          W2C_Prompf_Emission = FALSE; /* Emitting prompf xformed sources */
00171 const WN_MAP *W2C_Construct_Map = NULL;    /* Construct id mapping for prompf */
00172 WN_MAP        W2C_Frequency_Map = WN_MAP_UNDEFINED; /* Frequency mapping */
00173 BOOL          W2C_Cplus_Initializer = FALSE; /* Whether to call C++ init */
00174 Unparse_Target *W2X_Unparse_Target = NULL;
00175 
00176 
00177 /* ====================================================================
00178  *
00179  * Process_Filename_Options()
00180  *
00181  *    Once the command line is parsed, check for option interaction.
00182  *
00183  * Open_Read_File()
00184  *    Opens the file with the given name and path for reading.
00185  *
00186  * Open_Append_File()
00187  *
00188  *    Opens the file with the given name for appending more to its
00189  *    end if it already exists, or to create it if it does not
00190  *    already exist.
00191  *
00192  * Open_Create_File()
00193  *
00194  *    Same as Open_Append_File(), but a new file is always created,
00195  *    possibly overwriting an existing file.
00196  *
00197  * Close_File()
00198  *
00199  *    Closes the given file if different from NULL and not stdout or
00200  *    stderr.
00201  *
00202  * Open_W2c_Output_File()
00203  *
00204  *    Assuming that Process_Filename_Options() has been called, open
00205  *    the given kind of output file.  No effect if the file is already
00206  *    open, and the output will be appended to the output file if the
00207  *    file has already been created by this process.
00208  *
00209  * Close_W2c_Output_File()
00210  *
00211  *    If the file-pointer is non-NULL, we assume the file is open and
00212  *    close it.  Otherwise, this operation has no effect.
00213  *
00214  * ====================================================================
00215  */
00216 
00217 static void 
00218 Process_Filename_Options(const char *src_filename, const char *irb_filename)
00219 {
00220    /* No processing is currently necessary for -W2C:loc_file,
00221     * which both indicates that a source to source location
00222     * mapping should be generated and the name of the file into
00223     * which it should be written.
00224     *
00225     * The name of the original source can be used to derive the 
00226     * names of the output .c and .h files when these are not 
00227     * explicitly provided.  If no original source file-name 
00228     * (-W2C:src_file) has been specified, then we assume the name
00229     * given by src_file_name, irb_file_name, or "anonymous.c".  
00230     * The -W2C:doth_file -W2C:dotc_file names are derived from the
00231     * resultant -W2C:src_file, unless they are explicitly provided.
00232     *
00233     * Postcondition:
00234     *
00235     *   (W2C_File_Name[W2C_ORIG_FILE] != NULL) &&
00236     *   (W2C_File_Name[W2C_DOTH_FILE] != NULL)       &&
00237     *   (W2C_File_Name[W2C_DOTC_FILE] != NULL)
00238     */
00239    #define MAX_FNAME_LENGTH 256-7 /* allow for suffix ".w2c.c\0" */
00240    static char filename[MAX_FNAME_LENGTH+7];
00241    const char *fname;
00242    
00243    /* If we do not have an original source file name, then invent one */
00244    if (W2C_File_Name[W2C_ORIG_FILE] == NULL)
00245    {
00246       if (src_filename != NULL && src_filename[0] != '\0')
00247          W2C_File_Name[W2C_ORIG_FILE] = src_filename;
00248       else if (irb_filename != NULL && irb_filename[0] != '\0')
00249          W2C_File_Name[W2C_ORIG_FILE] = irb_filename;
00250       else
00251          W2C_File_Name[W2C_ORIG_FILE] = "anonymous.c";
00252    }
00253 
00254    /* Copy the original file-name to a static buffer */
00255    if (strlen(W2C_File_Name[W2C_ORIG_FILE]) > MAX_FNAME_LENGTH)
00256    {
00257       W2C_File_Name[W2C_ORIG_FILE] = 
00258          strncpy(filename, W2C_File_Name[W2C_ORIG_FILE], MAX_FNAME_LENGTH);
00259       filename[MAX_FNAME_LENGTH] = '\0';
00260       fprintf(stderr, 
00261               "WARNING: src_file name truncated to (max=%d chars): \"%s\"\n",
00262               MAX_FNAME_LENGTH, W2C_File_Name[W2C_ORIG_FILE]);
00263    }
00264    else
00265       W2C_File_Name[W2C_ORIG_FILE] =
00266          strcpy(filename, W2C_File_Name[W2C_ORIG_FILE]);
00267 
00268    /* We want the output files to be created in the current directory,
00269     * so strip off any directory path, and substitute the suffix 
00270     * appropriately.
00271     */
00272    fname = Last_Pathname_Component(filename);
00273    if ( W2C_File_Name[W2C_DOTH_FILE] == NULL ) {
00274       W2C_File_Name[W2C_DOTH_FILE] = 
00275          New_Extension ( fname, W2C_Extension(W2C_DOTH_FILE) );
00276    }
00277    if ( W2C_File_Name[W2C_DOTC_FILE] == NULL ) {
00278       W2C_File_Name[W2C_DOTC_FILE] = 
00279          New_Extension ( fname, W2C_Extension(W2C_DOTC_FILE) );
00280    }
00281    if (W2C_File_Name[W2C_LOC_FILE] == NULL)
00282    {
00283       if (List_Cite || W2C_Prompf_Emission)
00284       {
00285          W2C_File_Name[W2C_LOC_FILE] =
00286             New_Extension(fname, W2C_Extension(W2C_LOC_FILE));
00287       }
00288    }
00289 #if 0 //FMZ--see the comment about global_data file in this file
00290    if (W2C_File_Name[W2C_DATA_FILE] == NULL) {
00291      W2C_File_Name[W2C_DATA_FILE] = 
00292        New_Extension ( fname, W2C_Extension(W2C_DATA_FILE) );
00293    }
00294 #endif
00295 
00296 } /* Process_Filename_Options */
00297 
00298 
00299 static FILE *
00300 Open_Read_File(const char *filename)
00301 {
00302    FILE *f = NULL;
00303 
00304    /* Open the input file */
00305    if (filename == NULL || 
00306        (f = fopen(filename, "r")) == NULL)
00307    {
00308       ErrMsg(EC_IR_Open, filename, errno);
00309    }
00310    return f;
00311 } /* Open_Read_File */
00312 
00313 
00314 static FILE *
00315 Open_Append_File(const char *filename)
00316 {
00317    FILE *f = NULL;
00318 
00319    /* Open the input file */
00320    if (filename == NULL || 
00321        (f = fopen(filename, "a")) == NULL)
00322    {
00323       ErrMsg(EC_IR_Open, filename, errno);
00324    }
00325    return f;
00326 } /* Open_Append_File */
00327 
00328 
00329 static FILE *
00330 Open_Create_File(const char *filename)
00331 {
00332    FILE *f = NULL;
00333 
00334    /* Open the input file */
00335    if (filename == NULL || 
00336        (f = fopen(filename, "w")) == NULL)
00337    {
00338       ErrMsg(EC_IR_Open, filename, errno);
00339    }
00340    return f;
00341 } /* Open_Create_File */
00342 
00343 
00344 static void
00345 Close_File(const char *filename, FILE *afile)
00346 {
00347   if (afile != NULL             && 
00348       !Same_File(afile, stdout) && 
00349       !Same_File(afile, stderr) && 
00350       fclose(afile) != 0)
00351   {
00352      Set_Error_Line(ERROR_LINE_UNKNOWN); /* No line number for error */
00353      ErrMsg(EC_Src_Close, filename, errno);
00354   }
00355 } /* Close_File */
00356 
00357 
00358 static void 
00359 Open_W2c_Output_File(W2C_FILE_KIND kind)
00360 {
00361    if (W2C_File[kind] == NULL)
00362    {
00363       if (File_Is_Created[kind])
00364       {
00365          W2C_File[kind] = Open_Append_File(W2C_File_Name[kind]);
00366       }
00367       else
00368       {
00369          W2C_File[kind] = Open_Create_File(W2C_File_Name[kind]);
00370          File_Is_Created[kind] = TRUE;
00371       }
00372    } /* if (!files_are_open) */
00373 } /* Open_W2c_Output_File */
00374 
00375 
00376 static void
00377 Close_W2c_Output_File(W2C_FILE_KIND kind)
00378 {
00379    Close_File(W2C_File_Name[kind], W2C_File[kind]);
00380   W2C_File[kind] = NULL;
00381 } /* Close_W2c_Output_File */
00382 
00383 
00384 /* ====================================================================
00385  * Begin_New_Location_File: should be called when we start processing
00386  *     a new file for which we want locations information.
00387  *
00388  * End_Locations_File: should be called when we end processing of
00389  *     a new file for which we want locations information.
00390  *
00391  * Continue_Locations_File: should be called for each PU translation 
00392  *     for which we want locations information.  After the PU
00393  *     translation we should call Close_W2c_Output_File(W2C_LOC_FILE).
00394  *
00395  * ==================================================================== 
00396  */
00397 
00398 static void
00399 Begin_New_Locations_File(void)
00400 {
00401    /* This should only be called every time a new output file
00402     * is to be generated by whirl2f.  Note that we open and
00403     * close the file here, to make sure we only generate entries
00404     * in the location file when W2C_Outfile_Translate_Pu() is called!
00405     */
00406    if (W2C_File_Name[W2C_LOC_FILE] != NULL)
00407    {
00408       /* Need to do this before writing to a file for which a 
00409        * SRCPOS mapping should be maintained.
00410        */
00411       if (W2C_Prompf_Emission)
00412       {
00413          Open_W2c_Output_File(W2C_LOC_FILE);
00414          Write_String(W2C_File[W2C_LOC_FILE], NULL/* No srcpos map */,
00415                       "SRCPOS_MAP_BEGIN\n");
00416       }
00417       else
00418       {
00419          Open_W2c_Output_File(W2C_LOC_FILE);
00420          Write_String(W2C_File[W2C_LOC_FILE], NULL/* No srcpos map */,
00421                       "(SRCPOS-MAP\n");
00422       }
00423     }
00424 } /* Begin_New_Locations_File */
00425 
00426 
00427 static void
00428 End_Locations_File(void)
00429 {
00430    /* This should only be called every time we are done with *all*
00431     * location information for a file.
00432     */
00433    if (W2C_File_Name[W2C_LOC_FILE] != NULL)
00434    {
00435       /* Need to do this before writing to a file for which a 
00436        * SRCPOS mapping should be maintained.
00437        */
00438       if (W2C_Prompf_Emission)
00439       {
00440          Open_W2c_Output_File(W2C_LOC_FILE);
00441          Write_String(W2C_File[W2C_LOC_FILE],
00442                       NULL/* No srcpos map */,
00443                       "SRCPOS_MAP_END\n");
00444       }
00445       else
00446       {
00447          Open_W2c_Output_File(W2C_LOC_FILE);
00448          Write_String(W2C_File[W2C_LOC_FILE], NULL/* No srcpos map */, ")\n");
00449       }
00450       Terminate_Token_Buffer(W2C_File[W2C_LOC_FILE]);
00451       Close_W2c_Output_File(W2C_LOC_FILE);
00452    }
00453 } /* End_Locations_File */
00454 
00455 
00456 static void
00457 Continue_Locations_File(void)
00458 {
00459    /* Need to do this for every PU, i.e. every time 
00460     * W2C_Outfile_Translate_Pu() is called.
00461     */
00462    if (W2C_File_Name[W2C_LOC_FILE] != NULL)
00463    {
00464       Open_W2c_Output_File(W2C_LOC_FILE);
00465    }
00466 } /* Continue_Locations_File */
00467 
00468 
00469 static void
00470 Move_Locations_To_Anl_File(const char *loc_fname)
00471 {
00472 #define MAX_ANL_FNAME_LENGTH 256-5 /* allow for suffix ".anl\0" */
00473    char        cbuf[MAX_ANL_FNAME_LENGTH+1];
00474    INT         i, next_ch;
00475    FILE       *anl_file;
00476    FILE       *loc_file;
00477    const char *anl_fname;
00478    static char fname[MAX_ANL_FNAME_LENGTH+5];
00479 
00480    strncpy(fname, loc_fname, MAX_ANL_FNAME_LENGTH);
00481    anl_fname = Last_Pathname_Component(fname);
00482    anl_fname = New_Extension(anl_fname, ".anl");
00483    anl_file = Open_Append_File(anl_fname);
00484    loc_file = Open_Read_File(loc_fname);
00485 
00486    next_ch = getc(loc_file);
00487    while (next_ch != EOF)
00488    {
00489       for (i = 0; (next_ch != EOF && i < MAX_ANL_FNAME_LENGTH); i++)
00490       {
00491          cbuf[i] = next_ch;
00492          next_ch = getc(loc_file);
00493       }
00494       if (i > 0)
00495       {
00496          cbuf[i] = '\0';
00497          fputs(cbuf, anl_file);
00498       }
00499    }
00500    Close_File(anl_fname, anl_file);
00501    Close_File(loc_fname, loc_file);
00502    unlink(loc_fname);
00503 } /* Move_Locations_To_Anl_File */
00504 
00505 
00506 /* ====================================================================
00507  *                   Undo side-effects to the incoming WHIRL
00508  *                   ---------------------------------------
00509  *
00510  * W2C_Undo_Whirl_Side_Effects: This subroutine must be called after
00511  * every translation phase which may possibly create side-effects
00512  * in the incoming WHIRL tree.  The translation should thus become
00513  * side-effect free as far as concerns the incoming WHIRL tree.
00514  *
00515  * ==================================================================== 
00516  */
00517 
00518 static void
00519 W2C_Undo_Whirl_Side_Effects(void)
00520 {
00521    Stab_Free_Tmpvars();
00522    Stab_Free_Namebufs();
00523 }
00524 
00525 
00526 /* ====================================================================
00527  *                   Setting up the global symbol table
00528  *                   ----------------------------------
00529  *
00530  * W2C_Enter_Global_Symtab: Enter the global symbols into the w2c
00531  * symbol table.  The global symbol-table should be the top-of the
00532  * stack at this point.
00533  *
00534  * ==================================================================== 
00535  */
00536 
00537 static void
00538 W2C_Enter_Global_Symbols(void)
00539 {
00540    const ST *st;
00541    ST_IDX    st_idx;
00542    FLD_HANDLE   fld;
00543    TY_IDX    ty;
00544 
00545    /* Enter_Sym_Info for every struct or class type in the global
00546     * symbol table, with associated fields.  Do this prior to any
00547     * variable declarations, just to ensure that field names and
00548     * common block names retain their names to the extent this is
00549     * possible.
00550     */
00551    for (ty = 1; ty < TY_Table_Size(); ty++)
00552    {
00553       if (TY_Is_Structured(ty))
00554       {
00555          (void)W2CF_Symtab_Nameof_Ty(ty);
00556          for (fld = TY_flist(Ty_Table[ty]); !fld.Is_Null (); fld = FLD_next(fld))
00557             (void)W2CF_Symtab_Nameof_Fld(fld);
00558       } /* if a struct */
00559    } /* for all types */
00560 
00561    /* Enter_Sym_Info for every variable, function, and const in the global
00562     * symbol table.
00563     */
00564    FOREACH_SYMBOL(GLOBAL_SYMTAB, st, st_idx)
00565    {
00566       if ((ST_sym_class(st) == CLASS_VAR || ST_sym_class(st) == CLASS_FUNC) &&
00567           !Stab_Is_Based_At_Common_Or_Equivalence(st))
00568       {
00569          if (ST_sym_class(st) == CLASS_VAR && ST_sclass(st) == SCLASS_CPLINIT)
00570             W2C_Cplus_Initializer = TRUE;
00571 
00572          (void)W2CF_Symtab_Nameof_St(st);
00573       }
00574       else if (ST_sym_class(st) == CLASS_CONST)
00575       {
00576          (void)W2CF_Symtab_Nameof_St(st);
00577       }
00578    }
00579 } /* W2C_Enter_Global_Symbols */
00580 
00581 
00582 /* =================================================================
00583  * Routines for checking correct calling order of excported routines
00584  * =================================================================
00585  */
00586 
00587 static BOOL
00588 Check_Outfile_Initialized(const char *caller_name)
00589 {
00590    if (!W2C_Outfile_Initialized)
00591       fprintf(stderr, 
00592               "NOTE: Ignored call to %s(); call W2C_Outfile_Init() first!\n",
00593               caller_name);
00594    return W2C_Outfile_Initialized;
00595 } /* Check_Outfile_Initialized */
00596 
00597 static BOOL
00598 Check_Initialized(const char *caller_name)
00599 {
00600    if (!W2C_Initialized)
00601       fprintf(stderr, 
00602               "NOTE: Ignored call to %s(); call W2C_Init() first!\n",
00603               caller_name);
00604    return W2C_Initialized;
00605 } /* Check_Initialized */
00606 
00607 static BOOL
00608 Check_PU_Pushed(const char *caller_name)
00609 {
00610    if (PUinfo_current_func == NULL)
00611       fprintf(stderr, 
00612               "NOTE: Ignored call to %s(); call W2C_Push_PU() first!\n",
00613               caller_name);
00614    return (PUinfo_current_func != NULL);
00615 } /* Check_PU_Pushed */
00616 
00617 
00618 /* =================================================================
00619  *                 EXPORTED LOW-LEVEL W2C INTERFACE
00620  *                 --------------------------------
00621  *
00622  * See comments in w2c_driver.h
00623  *
00624  * =================================================================
00625  */
00626 
00627 BOOL
00628 W2C_Should_Emit_Nested_PUs(void)
00629 {
00630    return W2C_Emit_Nested_PUs;
00631 } /* W2C_Should_Emit_Nested_PUs */
00632 
00633 
00634 
00635 void
00636 W2C_Process_Command_Line (INT phase_argc, char * const phase_argv[],
00637                           INT argc, char * const argv[])
00638 {
00639     /* Get the program name
00640      */
00641     if (argv[0] != NULL)
00642        W2C_Progname = argv[0];
00643 
00644     /* The processing of the CLIST group was moved out to the back-end.
00645      * Instead of directly using the Current_CLIST, we initiate
00646      * whirl2c specific variables to hold the values.
00647      */
00648    W2C_File_Name[W2C_ORIG_FILE] = CLIST_orig_filename;
00649    W2C_File_Name[W2C_DOTH_FILE] = CLIST_doth_filename;
00650    W2C_File_Name[W2C_DOTC_FILE] = CLIST_dotc_filename;
00651    W2C_File_Name[W2C_LOC_FILE] = CLIST_loc_filename;
00652    W2C_Enabled = CLIST_enabled;
00653    W2C_Verbose = CLIST_verbose;
00654    W2C_No_Pragmas = CLIST_no_pragmas;
00655    W2C_Emit_Adims = CLIST_emit_adims;
00656    W2C_Emit_Prefetch = CLIST_emit_prefetch;
00657    W2C_Emit_All_Regions = CLIST_emit_all_regions;
00658    W2C_Emit_Linedirs = CLIST_emit_linedirs;
00659    W2C_Emit_Nested_PUs = CLIST_emit_nested_pus;
00660    W2C_Emit_Frequency = CLIST_emit_frequency;
00661    W2C_Emit_Cgtag = CLIST_emit_cgtag;
00662    W2C_Lower_Fortran = CLIST_lower_ftn;
00663    W2C_Emit_Omp = CLIST_emit_omp;
00664    W2C_Line_Length = CLIST_line_length;
00665 
00666     Process_Filename_Options(Src_File_Name, Irb_File_Name);
00667 } /* W2C_Process_Command_Line */
00668 
00669 
00670 void
00671 W2C_Init(void)
00672 {
00673    /* Initialize the various whirl2c subcomponents, unless they
00674     * are already initialized.
00675     */
00676    const char * const caller_err_phase = Get_Error_Phase ();
00677 
00678    if (W2C_Initialized)
00679       return; /* Already initialized */
00680       
00681    Set_Error_Phase ( "W2C Initialization" );
00682 
00683    /* Create a pool to hold the parent map for every PU, one at a time.
00684     */
00685    MEM_POOL_Initialize(&W2C_Parent_Pool, "W2C_Parent_Pool", FALSE);
00686    MEM_POOL_Push(&W2C_Parent_Pool);
00687 
00688    /* Always do this first!
00689     */
00690    Initialize_Token_Buffer(FREE_FORMAT, W2C_Prompf_Emission);
00691    if (W2C_Line_Length > 0)
00692       Set_Maximum_Linelength(W2C_Line_Length);
00693 
00694    /* Enter the global symbols into the symbol table, since that
00695     * ensures these get the first priority at keeping their names 
00696     * unchanged (note that a w2c invented name-suffix is added to 
00697     * disambiguate names).
00698     */
00699    W2X_Unparse_Target = new Unparse_Target_C;
00700    Stab_initialize_flags();
00701    W2CF_Symtab_Push();
00702    W2C_Enter_Global_Symbols();
00703 
00704    /* Initiate the various W2C modules.
00705     */
00706    CONTEXT_reset(Global_Context);
00707    TY2C_initialize(Global_Context);
00708    ST2C_initialize(Global_Context);
00709    TCON2C_initialize();
00710    WN2C_initialize();
00711    PUinfo_initialize();
00712 
00713    W2C_Initialized = TRUE;
00714    Set_Error_Phase ( caller_err_phase );
00715 } /* W2C_Init */
00716 
00717 
00718 void 
00719 W2C_Push_PU(const WN *pu, WN *body_part_of_interest)
00720 {
00721    if (!Check_Initialized("W2C_Push_PU"))
00722       return;
00723 
00724    Is_True(WN_opcode(pu) == OPC_FUNC_ENTRY, 
00725            ("Invalid opcode for W2C_Push_PU()"));
00726 
00727    /* Set up the parent mapping
00728     */
00729    MEM_POOL_Push(&W2C_Parent_Pool);
00730    W2CF_Parent_Map = WN_MAP_Create(&W2C_Parent_Pool);
00731    W2CF_Parentize(pu);
00732    Stab_initialize();
00733 
00734    /* See if the body_part_of_interest has any part to be skipped
00735     * by the w2c translator.
00736     */
00737    if (WN_opc_operator(body_part_of_interest) == OPR_BLOCK)
00738    {
00739       Remove_Skips(body_part_of_interest, 
00740                    Skip,
00741                    &Next_Skip_Item,
00742                    W2C_MAX_SKIP_ITEMS,
00743                    TRUE /*is C*/);
00744    }
00745 
00746    PUinfo_init_pu(pu, body_part_of_interest);
00747 } /* W2C_Push_PU */
00748 
00749 
00750 void 
00751 W2C_Pop_PU(void)
00752 {
00753    SYMTAB_IDX symtab;
00754 
00755    if (!Check_Initialized("W2C_Pop_PU") ||
00756        !Check_PU_Pushed("W2C_Pop_PU"))
00757       return;
00758 
00759    PUinfo_exit_pu();
00760 
00761    /* Restore any removed statement sequence
00762     */
00763    if (Next_Skip_Item > 0)
00764    {
00765       Restore_Skips(Skip, Next_Skip_Item, TRUE /*Is C*/);
00766       Next_Skip_Item = 0;
00767    }
00768 
00769    /* Reset the symtab used by wn2c between PUs, such that local
00770     * declarations will reappear even when the same PU is repeatedly
00771     * translated.
00772     */
00773    symtab = CURRENT_SYMTAB;
00774    CURRENT_SYMTAB = GLOBAL_SYMTAB;
00775    WN2C_new_symtab();
00776    CURRENT_SYMTAB = symtab;
00777    Stab_finalize();
00778 
00779    WN_MAP_Delete(W2CF_Parent_Map);
00780    W2CF_Parent_Map = WN_MAP_UNDEFINED;
00781    MEM_POOL_Pop(&W2C_Parent_Pool);
00782 
00783    W2C_Frequency_Map = WN_MAP_UNDEFINED;
00784 } /* W2C_Pop_PU */
00785 
00786 
00787 void
00788 W2C_Mark_Loads(void)
00789 {
00790    W2C_Only_Mark_Loads = TRUE;
00791 } /* W2C_Mark_Loads */
00792 
00793 
00794 void
00795 W2C_Nomark_Loads(void)
00796 {
00797    W2C_Only_Mark_Loads = FALSE;
00798 } /* W2C_Nomark_Loads */
00799 
00800 
00801 void 
00802 W2C_Set_Prompf_Emission(const WN_MAP *construct_map)
00803 {
00804    W2C_Prompf_Emission = TRUE;
00805    W2C_Construct_Map = construct_map; /* Construct id mapping for prompf */
00806 } /* W2C_Set_Prompf_Emission */
00807 
00808 
00809 void 
00810 W2C_Set_Frequency_Map(WN_MAP frequency_map)
00811 {
00812    W2C_Frequency_Map = frequency_map; /* Feedback frequency mapping for wopt */
00813 } /* W2C_Set_Frequency_Map */
00814 
00815 
00816 const char *
00817 W2C_Get_Transformed_Src_Path(void)
00818 {
00819    return W2C_File_Name[W2C_DOTC_FILE];
00820 } /* W2C_Get_Transformed_Src_Path */
00821 
00822 
00823 void
00824 W2C_Set_Purple_Emission(void)
00825 {
00826    W2C_Purple_Emission = TRUE;
00827 } /* W2C_Set_Purple_Emission */
00828 
00829 
00830 void
00831 W2C_Reset_Purple_Emission(void)
00832 {
00833    W2C_Purple_Emission = FALSE;
00834 } /* W2C_Reset_Purple_Emission */
00835 
00836 
00837 void
00838 W2C_def_TY(FILE *outfile, TY_IDX ty)
00839 {
00840    TOKEN_BUFFER tokens;
00841    CONTEXT context = INIT_CONTEXT;
00842 
00843    if (!Check_Initialized("W2C_def_TY"))
00844       return;
00845 
00846    tokens = New_Token_Buffer();
00847    TY2C_translate(tokens, ty, context);
00848    Write_And_Reclaim_Tokens(outfile, W2C_File[W2C_LOC_FILE], &tokens);
00849    W2C_Undo_Whirl_Side_Effects();
00850 } /* W2C_def_TY */
00851 
00852 
00853 void
00854 W2C_Translate_Global_Types(FILE *outfile)
00855 {
00856    FILE *saved_hfile = W2C_File[W2C_DOTH_FILE];
00857 
00858    if (!Check_Initialized("W2C_Translate_Global_Types"))
00859       return;
00860 
00861    W2C_File[W2C_DOTH_FILE] = outfile;
00862    WN2C_translate_structured_types();
00863    W2C_File[W2C_DOTH_FILE] = saved_hfile;
00864    W2C_Undo_Whirl_Side_Effects();
00865 } /* W2C_Translate_Global_Types */
00866 
00867 void W2C_write_init(FILE *outfile) {
00868 
00869   if (!Check_Initialized("W2C_write_init")) {
00870     return;
00871   }
00872   
00873 
00874 }
00875 
00876 void
00877 W2C_Translate_Global_Defs(FILE *outfile)
00878 {
00879    FILE *saved_hfile = W2C_File[W2C_DOTH_FILE];
00880 
00881    if (!Check_Initialized("W2C_Translate_Global_Defs"))
00882       return;
00883 
00884    W2C_File[W2C_DOTH_FILE] = outfile;
00885    WN2C_translate_file_scope_defs(Global_Context);
00886 
00887    W2C_File[W2C_DOTH_FILE] = saved_hfile;
00888    W2C_Undo_Whirl_Side_Effects();
00889 } /* W2C_Translate_Global_Defs */
00890 
00891 
00892 const char * 
00893 W2C_Object_Name(const ST *func_st)
00894 {
00895    return W2CF_Symtab_Nameof_St(func_st);
00896 } /* W2C_Function_Name */
00897 
00898 
00899 void 
00900 W2C_Translate_Stid_Lhs(char       *strbuf,
00901                        UINT        bufsize,
00902                        const ST   *stid_st, 
00903                        STAB_OFFSET stid_ofst, 
00904                        TY_IDX      stid_ty, 
00905                        TYPE_ID     stid_mtype)
00906 {
00907    TOKEN_BUFFER tokens;
00908    TY_IDX       stored_ty;
00909    CONTEXT      context = INIT_CONTEXT;
00910 
00911    tokens = New_Token_Buffer();
00912    WN2C_stid_lhs(tokens,
00913                  &stored_ty,   /* Corrected stored type */
00914                  stid_st,      /* base symbol */
00915                  stid_ofst,    /* offset from base */
00916                  stid_ty,      /* stored type */
00917                  stid_mtype,   /* stored mtype */
00918                  context);
00919    Str_Write_And_Reclaim_Tokens(strbuf, bufsize, &tokens);
00920    W2C_Undo_Whirl_Side_Effects();
00921 } /* W2C_Translate_Stid_Lhs */
00922 
00923 
00924 void 
00925 W2C_Translate_Istore_Lhs(char       *strbuf, 
00926                          UINT        bufsize,
00927                          const WN   *lhs,
00928                          STAB_OFFSET istore_ofst, 
00929                          TY_IDX      istore_ty_idx,
00930                          TYPE_ID     istore_mtype)
00931 {
00932    TOKEN_BUFFER tokens;
00933    TY_IDX       stored_ty;
00934    CONTEXT      context = INIT_CONTEXT;
00935 
00936    tokens = New_Token_Buffer();
00937    WN2C_memref_lhs(tokens, 
00938                    &stored_ty,
00939                    lhs,            /* lhs address */
00940                    istore_ofst,    /* offset from this address */
00941                    istore_ty_idx,  /* type table index for stored object */
00942                    Ty_Table[istore_ty_idx].Pointed(), /* type for stored obj */
00943                    istore_mtype,   /* base-type for stored object */
00944                    context);
00945    Str_Write_And_Reclaim_Tokens(strbuf, bufsize, &tokens);
00946    W2C_Undo_Whirl_Side_Effects();
00947 } /* W2C_Translate_Istore_Lhs */
00948 
00949 
00950 void 
00951 W2C_Translate_Wn(FILE *outfile, const WN *wn)
00952 {
00953    TOKEN_BUFFER       tokens;
00954    CONTEXT            context = INIT_CONTEXT;
00955    const char * const caller_err_phase = Get_Error_Phase ();
00956 
00957    if (!Check_Initialized("W2C_Translate_Wn") ||
00958        !Check_PU_Pushed("W2C_Translate_Wn"))
00959       return;
00960 
00961    Start_Timer (T_W2C_CU);
00962    Set_Error_Phase ("WHIRL To C");
00963 
00964    tokens = New_Token_Buffer();
00965    (void)WN2C_translate(tokens, wn, context);
00966    Write_And_Reclaim_Tokens(outfile, W2C_File[W2C_LOC_FILE], &tokens);
00967    W2C_Undo_Whirl_Side_Effects();
00968 
00969    Stop_Timer (T_W2C_CU);
00970    Set_Error_Phase (caller_err_phase);
00971 } /* W2C_Translate_Wn */
00972 
00973 
00974 void 
00975 W2C_Translate_Wn_Str(char *strbuf, UINT bufsize, const WN *wn)
00976 {
00977    TOKEN_BUFFER       tokens;
00978    CONTEXT            context = INIT_CONTEXT;
00979    const char * const caller_err_phase = Get_Error_Phase ();
00980 
00981    if (!Check_Initialized("W2C_Translate_Wn_Str") ||
00982        !Check_PU_Pushed("W2C_Translate_Wn_Str"))
00983       return;
00984 
00985    Start_Timer (T_W2C_CU);
00986    Set_Error_Phase ("WHIRL To C");
00987 
00988    tokens = New_Token_Buffer();
00989    (void)WN2C_translate(tokens, wn, context);
00990    Str_Write_And_Reclaim_Tokens(strbuf, bufsize, &tokens);
00991    W2C_Undo_Whirl_Side_Effects();
00992 
00993    Stop_Timer (T_W2C_CU);
00994    Set_Error_Phase (caller_err_phase);
00995 } /* W2C_Translate_Wn_Str */
00996 
00997 
00998 void 
00999 W2C_Translate_Purple_Main(FILE *outfile, const WN *pu, const char *region_name)
01000 {
01001    TOKEN_BUFFER tokens;
01002    CONTEXT      context = INIT_CONTEXT;
01003    const char * const caller_err_phase = Get_Error_Phase ();
01004 
01005    if (!Check_Initialized("W2C_Translate_Purple_Main"))
01006       return;
01007 
01008    Is_True(WN_opcode(pu) == OPC_FUNC_ENTRY, 
01009            ("Invalid opcode for W2C_Translate_Purple_Main()"));
01010 
01011    Start_Timer (T_W2C_CU);
01012    Set_Error_Phase ("WHIRL To C");
01013 
01014    /* Translate the function header as a purple main program
01015     */
01016    tokens = New_Token_Buffer();
01017    W2C_Push_PU(pu, WN_func_body(pu));
01018    (void)WN2C_translate_purple_main(tokens, pu, region_name, context);
01019    W2C_Pop_PU();
01020    W2C_Undo_Whirl_Side_Effects();
01021    Write_And_Reclaim_Tokens(outfile, W2C_File[W2C_LOC_FILE], &tokens);
01022 
01023    Stop_Timer (T_W2C_CU);
01024    Set_Error_Phase (caller_err_phase);
01025 } /* W2C_Translate_Purple_Main */
01026 
01027 
01028 void
01029 W2C_Fini(void)
01030 {
01031    /* Ignore this call if W2C_Outfile_Initialized, since a call to
01032     * W2C_Outfile_Fini() must take care of the finalization for
01033     * this case.
01034     */
01035    INT i;
01036 
01037    if (!Check_Initialized("W2C_Fini"))
01038       return;
01039    else if (!W2C_Outfile_Initialized)
01040    {
01041       Stab_Reset_Referenced_Flag(GLOBAL_SYMTAB);
01042       TY2C_finalize();
01043       ST2C_finalize();
01044       TCON2C_finalize();
01045       WN2C_finalize();
01046       PUinfo_finalize();
01047       W2CF_Symtab_Terminate();
01048       Stab_finalize_flags();
01049       if (W2C_File_Name[W2C_LOC_FILE] != NULL)
01050          End_Locations_File(); /* Writes filenames-table to file */
01051       else
01052          Terminate_Token_Buffer(NULL);
01053 
01054       /* Reset all global variables */
01055       W2C_Initialized = FALSE;
01056       CONTEXT_reset(Global_Context);
01057       W2C_Progname = "";
01058       for (i=0;i<W2C_NUM_FILES;i++) W2C_File_Name[i] = NULL;
01059       for (i=0;i<W2C_NUM_FILES;i++) File_Is_Created[i] = FALSE;
01060       for (i=0;i<W2C_NUM_FILES;i++) W2C_File[i] = NULL;
01061       W2C_Enabled = TRUE;           /* Invoke W2C */
01062       W2C_Verbose = TRUE;           /* Show translation information */
01063       W2C_No_Pragmas = FALSE;       /* Do not emit pragmas */
01064       W2C_Emit_Adims = FALSE;       /* Emit comments for array dims */
01065       W2C_Emit_Prefetch = FALSE;    /* Emit comments for prefetches */
01066       W2C_Emit_All_Regions = FALSE; /* Emit cmplr-generated regions */
01067       W2C_Emit_Linedirs = FALSE;    /* Emit preproc line-directives */
01068       W2C_Emit_Nested_PUs = FALSE;  /* Emit code for nested PUs */
01069       W2C_Emit_Frequency = FALSE;   /* Emit feedback frequency info */
01070       W2C_Lower_Fortran = FALSE;    /* Lower Fortran intrinsics and io */
01071       W2C_Line_Length = 0;   /* Max output line length; zero==default */
01072 
01073       W2C_Only_Mark_Loads = FALSE;
01074       W2C_Cplus_Initializer = FALSE;
01075 
01076       MEM_POOL_Pop(&W2C_Parent_Pool);
01077       MEM_POOL_Delete(&W2C_Parent_Pool);
01078    } /* if (initialized) */
01079 } /* W2C_Fini */
01080 
01081 
01082 /* =================================================================
01083  *                  EXPORTED OUTPUT-FILE INTERFACE
01084  *                  ------------------------------
01085  *
01086  * This is the easiest interface for using whirl2c, and it
01087  * maintains output file status and produces a uniform output
01088  * format based on the -CLIST options.  There are strict rules
01089  * as to how this interface interacts with the lower-level 
01090  * interface described above (see .h file for details).
01091  *
01092  * W2C_Outfile_Init()
01093  *    Initializes the output-files for whirl2c, based on the
01094  *    command-line options.  Will call W2C_Init() if this has
01095  *    not already been done.
01096  *
01097  * W2C_Outfile_Translate_Pu()
01098  *    Translates a PU, presupposing W2C_Outfile_Init() has been 
01099  *    called.  The PU will be lowered (for Fortran) and the 
01100  *    output C code will be appended to the output files.
01101  *
01102  * W2C_Output_Fini()
01103  *    Finalizes a W2C translation by closing the output-files, and
01104  *    calling W2C_Fini().  Optionally, this may cause common blocks
01105  *    (for Fortran-to-C translation) to be appended to the generated
01106  *    header-file.
01107  *
01108  * =================================================================
01109  */
01110 
01111 void
01112 W2C_Outfile_Init(BOOL emit_global_decls)
01113 {
01114    /* Initialize the various whirl2c subcomponents.  It is not
01115     * always desirable to open a .h file for global declarations,
01116     * and this can be suppressed (no global declarations will be
01117     * emitted) by passing emit_global_decls=FALSE.  For even more
01118     * control over the W2C translation process, use the lower-level
01119     * translation routines, instead of this more abstract
01120     * interface.
01121     */
01122    time_t systime;
01123 
01124    if (W2C_Outfile_Initialized)
01125       return; /* Already initialized */
01126 
01127    W2C_Outfile_Initialized = TRUE;
01128    if (W2C_Verbose)
01129    {
01130       if (W2C_Prompf_Emission || W2C_File_Name[W2C_LOC_FILE] == NULL)
01131          fprintf(stderr, 
01132                  "%s translates %s into %s and %s, based on source %s\n", 
01133                  W2C_Progname,
01134                  Irb_File_Name, 
01135                  W2C_File_Name[W2C_DOTH_FILE], 
01136                  W2C_File_Name[W2C_DOTC_FILE], 
01137                  W2C_File_Name[W2C_ORIG_FILE]);
01138       else
01139          fprintf(stderr, 
01140                  "%s translates %s into %s, %s and %s, based on source %s\n", 
01141                  W2C_Progname,
01142                  Irb_File_Name,
01143                  W2C_File_Name[W2C_DOTH_FILE],
01144                  W2C_File_Name[W2C_DOTC_FILE],
01145                  W2C_File_Name[W2C_LOC_FILE],
01146                  W2C_File_Name[W2C_ORIG_FILE]);
01147    } /* if verbose */
01148 
01149    /* Initialize the whirl2c modules!
01150     */
01151    if (!W2C_Initialized)
01152       W2C_Init();
01153 
01154    /* Open the output files (and write location mapping header).
01155     */
01156    Begin_New_Locations_File();
01157    Open_W2c_Output_File(W2C_DOTC_FILE);
01158 
01159    /* Write out a header-comment into the whirl2c generated 
01160     * source file.
01161     */
01162    systime = time(NULL);
01163    Write_String(W2C_File[W2C_DOTC_FILE], W2C_File[W2C_LOC_FILE],
01164                 "/*******************************************************\n"
01165                 " * C file translated from WHIRL ");
01166    Write_String(W2C_File[W2C_DOTC_FILE], W2C_File[W2C_LOC_FILE],
01167                 ((systime != (time_t)-1)? 
01168                  ctime(&systime) : "at unknown time\n"));
01169    Write_String(W2C_File[W2C_DOTC_FILE], W2C_File[W2C_LOC_FILE],
01170                 " *******************************************************/"
01171                 "\n\n");
01172 
01173    /* Emit the header file if appropriate */
01174    if (emit_global_decls)
01175    {
01176       Open_W2c_Output_File(W2C_DOTH_FILE);
01177 
01178       if(Compile_Upc) 
01179         /* Include <whirl2c.h> in the .h file */
01180         Write_String(W2C_File[W2C_DOTH_FILE], NULL/* No srcpos map */,
01181                      "/* Include builtin types and operators */\n"
01182                      //WEI: Took external_defs out, use upc_proxy instead
01183                      "#include \"upcr_proxy.h\"\n#include<upcr.h>\n#include <whirl2c.h>\n\n");
01184       else
01185         /* Include <whirl2c.h> in the .h file */
01186         Write_String(W2C_File[W2C_DOTH_FILE], NULL/* No srcpos map */,
01187                      "/* Include builtin types and operators */\n"
01188                      "#include \"whirl2c.h\"\n\n");
01189       
01190       /* Include the .h file in the .c file */
01191       Write_String(W2C_File[W2C_DOTC_FILE], W2C_File[W2C_LOC_FILE],
01192                    "/* Include file-level type and variable decls */\n"
01193                    "#include \"");
01194       Write_String(W2C_File[W2C_DOTC_FILE], W2C_File[W2C_LOC_FILE],
01195                    W2C_File_Name[W2C_DOTH_FILE]);
01196       Write_String(W2C_File[W2C_DOTC_FILE], W2C_File[W2C_LOC_FILE],
01197                    "\"\n\n");
01198    }
01199 
01200    // add the init file to output
01201    Write_String(W2C_File[W2C_DOTC_FILE], W2C_File[W2C_LOC_FILE],
01202                 "/* Included code from the initialization script */\n");
01203 /* We may not need the file named as "foo.global_data.c"
01204  * in all of  our test code this forces us give an empty file 
01205  * named "foo.global_data.c" (suppose test code named "foo.c"  to go
01206  * through the unparser.
01207  * FMZ----July 2,2004
01208  */
01209 #if 0
01210    char buf[MAX_LINE_LEN];
01211    FILE* in = fopen(W2C_File_Name[W2C_DATA_FILE], "r");
01212    if (in == NULL) {
01213       ErrMsg(EC_IR_Open, W2C_File_Name[W2C_DATA_FILE], errno);
01214    }
01215 
01216    while (fgets(buf, MAX_LINE_LEN, in) != NULL) {
01217      Write_String(W2C_File[W2C_DOTC_FILE], W2C_File[W2C_LOC_FILE], buf);
01218    }
01219 #endif 
01220 
01221    /*
01222      fstream fs;
01223      string line;
01224      fs.open(W2C_File_Name[W2C_DATA_FILE], ios::in);
01225      
01226      while (fs.good()) {
01227      getline(fs, line);
01228      Write_String(W2C_File[W2C_DOTC_FILE], W2C_File[W2C_LOC_FILE], (line + "\n").c_str());
01229      }
01230    */
01231      
01232 
01233    if (emit_global_decls)
01234       WN2C_translate_structured_types();
01235 
01236    W2C_Outfile_Initialized = TRUE;
01237 
01238 } /* W2C_Outfile_Init */
01239 
01240 
01241 void
01242 W2C_Outfile_Translate_Pu(WN *pu, BOOL emit_global_decls)
01243 {
01244    TOKEN_BUFFER       tokens;
01245    LOWER_ACTIONS      lower_actions = LOWER_NULL;
01246    const BOOL         pu_is_pushed = (PUinfo_current_func != NULL);
01247    const char * const caller_err_phase = Get_Error_Phase ();
01248 
01249    if (!Check_Outfile_Initialized("W2C_Outfile_Translate_Pu"))
01250       return;
01251 
01252    Is_True(WN_opcode(pu) == OPC_FUNC_ENTRY, 
01253            ("Invalid opcode for W2C_Outfile_Translate_Pu()"));
01254 
01255    /* Make sure all necessary output files are open.
01256     */
01257    Continue_Locations_File();
01258    Open_W2c_Output_File(W2C_DOTC_FILE);
01259    if (emit_global_decls)
01260       Open_W2c_Output_File(W2C_DOTH_FILE);
01261 
01262    if (W2C_Emit_Nested_PUs && !W2C_Lower_Fortran)
01263       lower_actions = LOWER_MP;
01264    else if (!W2C_Emit_Nested_PUs && W2C_Lower_Fortran)
01265       lower_actions = LOWER_IO_STATEMENT | LOWER_INTRINSIC;
01266    else if(W2C_Emit_Nested_PUs && W2C_Lower_Fortran)
01267       lower_actions = LOWER_MP | LOWER_IO_STATEMENT | LOWER_INTRINSIC;
01268 
01269    if (lower_actions != LOWER_NULL)
01270       pu = WN_Lower(pu, lower_actions, NULL, "W2C Lowering");
01271 
01272    Start_Timer (T_W2C_CU);
01273    Set_Error_Phase ("WHIRL To C");
01274 
01275    if (!pu_is_pushed)
01276       W2C_Push_PU(pu, WN_func_body(pu));
01277 
01278    tokens = New_Token_Buffer();
01279    (void)WN2C_translate(tokens, pu, Global_Context);
01280    Write_And_Reclaim_Tokens(W2C_File[W2C_DOTC_FILE], 
01281                             W2C_File[W2C_LOC_FILE], 
01282                             &tokens);
01283 
01284    if (!pu_is_pushed)
01285       W2C_Pop_PU();
01286 
01287    W2C_Undo_Whirl_Side_Effects();
01288 
01289    Stop_Timer (T_W2C_CU);
01290    Set_Error_Phase (caller_err_phase);
01291 } /* W2C_Outfile_Translate_Pu */
01292 
01293 
01294 void
01295 W2C_Outfile_Fini(BOOL emit_global_decls)
01296 {
01297    /* This finalization must be complete enough to allow repeated
01298     * invocations of whirl2c during the same process life-time.
01299     */
01300    const char *loc_fname = W2C_File_Name[W2C_LOC_FILE];
01301 
01302    if (!Check_Outfile_Initialized("W2C_Outfile_Fini"))
01303       return;
01304    
01305    /* Reopen files if they are closed */
01306    Continue_Locations_File();
01307    Open_W2c_Output_File(W2C_DOTC_FILE);
01308    if (emit_global_decls)
01309       Open_W2c_Output_File(W2C_DOTH_FILE);
01310 
01311    if (emit_global_decls)
01312    {
01313       TOKEN_BUFFER tokens = New_Token_Buffer();
01314 
01315       WN2C_translate_file_scope_defs(Global_Context);
01316       ST2C_Define_Common_Blocks(tokens, Global_Context);
01317 
01318       //WEI: Don't think we need this anymore, since Append_Symtab_Var now does this.
01319       //Could be wrong, though...
01320       if (!Compile_Upc) {
01321         Write_And_Reclaim_Tokens(W2C_File[W2C_DOTH_FILE], 
01322         W2C_File[W2C_LOC_FILE], 
01323         &tokens);
01324       }
01325    }
01326 
01327    Close_W2c_Output_File(W2C_LOC_FILE);
01328    Close_W2c_Output_File(W2C_DOTH_FILE);
01329    Close_W2c_Output_File(W2C_DOTC_FILE);
01330 
01331    /* All files must be closed before doing a partial 
01332     * finalization, except W2C_LOC_FILE.
01333     */
01334    W2C_Outfile_Initialized = FALSE;
01335    W2C_Fini(); /* Sets W2C_Initialized to FALSE */
01336 
01337    if (W2C_Prompf_Emission && loc_fname != NULL)
01338    {
01339       /* Copy the locations file to the .anl file and remove it 
01340        */
01341       Move_Locations_To_Anl_File(loc_fname);
01342    }
01343 } /* W2C_Outfile_Fini */
01344 
01345 
01346 void
01347 W2C_Cleanup(void)
01348 {
01349    /* Cleanup in case of error condition (or a forgotten call to Anl_Fini())
01350     */
01351    Close_W2c_Output_File(W2C_LOC_FILE);
01352    Close_W2c_Output_File(W2C_DOTH_FILE);
01353    Close_W2c_Output_File(W2C_DOTC_FILE);
01354    if (W2C_File_Name[W2C_LOC_FILE] != NULL)
01355       unlink(W2C_File_Name[W2C_LOC_FILE]);
01356 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines