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