st2f.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-May-95 - Original Version
00042  *
00043  * Description:
00044  *
00045  *    See st2f.h for a description of the exported functions and 
00046  *    variables.  This module translates ST nodes into variable and
00047  *    function declarations (ST2F_decl_translate), and gets the 
00048  *    lvalue for a variable or function when directly referenced in
00049  *    an expression (ST2F_use_translate).  We provide a special 
00050  *    interface to deal with pseudo registers (pregs), but some 
00051  *    symbols must be handled by the context in which they appear,
00052  *    since this context uniquely determines the reference (e.g. 
00053  *    labels has label-numbers in the WN tree).
00054  *
00055  *    Possibly necessary TODO: sym_consts are only partially
00056  *    supported at the moment.
00057  *
00058  *    Fortran pointers are represented by two declarations, where
00059  *    one declares the pointer object (which is allocated memory)
00060  *    and one denotes the pointer dereference which also serves to
00061  *    specify the type of object to which is pointed:
00062  *
00063  *        INTEGER*4 a(12)
00064  *        POINTER(p, a)
00065  *
00066  *    Only "p" occurs in the WHIRL symbol table.  We have to derive
00067  *    "a" from "p" (with a name derived from "p").  The w2cf_symtab.h
00068  *    facilities coordinates this for us.
00069  *
00070  *    It is crucial that names with external linkage are generated 
00071  *    with the same name between compilation units.  For this reason
00072  *    we give file-scope variables precedence in name-ownership (i.e.
00073  *    they are entered first into the symbol-table).  If, despite this
00074  *    effort, there are clashes between names with static and external 
00075  *    linkage, the generated code may not be compilable or correctly
00076  *    executable.  TODO: Emit warning about this.
00077  * 
00078  * ====================================================================
00079  * ====================================================================
00080  */
00081 
00082 #ifdef _KEEP_RCS_ID
00083 /*REFERENCED*/
00084 #endif
00085 
00086 #include <ctype.h>
00087 #include <alloca.h>
00088 #include <set>    // STL
00089 #include <vector> // STL
00090 using std::set;
00091 using std::vector;
00092 
00093 #include "whirl2f_common.h"
00094 #include "PUinfo.h"
00095 #include "tcon2f.h"
00096 #include "wn2f.h"
00097 #include "ty2f.h"
00098 #include "st2f.h"
00099 #include "init2f.h"
00100 #include "cxx_memory.h"
00101 #include "be_symtab.h"
00102 #include "unparse_target.h"
00103 #include "ty_ftn.h"
00104 
00105 typedef std::set<int> PARMSET;
00106 
00107  /* Defined in ty2f.c; signifies special translation of adjustable and
00108   * assumed sized arrays.
00109   */
00110 extern BOOL Use_Purple_Array_Bnds_Placeholder;
00111 extern WN* PU_Body; 
00112 /*------- Fwd refs for miscellaneous utilities ------------------------*/
00113 /*---------------------------------------------------------------------*/
00114 
00115 static BOOL ST2F_Is_Dummy_Procedure(ST *st) ;
00116 static void ST2F_Declare_Return_Type(TOKEN_BUFFER tokens,TY_IDX return_ty, const char* name) ;
00117 
00118 /*------- Handlers for references to and declarations of symbols ------*/
00119 /*---------------------------------------------------------------------*/
00120 
00121 static void ST2F_ignore(TOKEN_BUFFER tokens, ST *st);
00122 
00123 static void ST2F_decl_error(TOKEN_BUFFER tokens, ST *st);
00124 static void ST2F_decl_var(TOKEN_BUFFER tokens, ST *st);
00125 static void ST2F_decl_func(TOKEN_BUFFER tokens, ST *st);
00126 static void ST2F_decl_const(TOKEN_BUFFER tokens, ST *st);
00127 static void ST2F_decl_type (TOKEN_BUFFER tokens, ST *st);
00128 static void ST2F_decl_parameter (TOKEN_BUFFER tokens, ST *st);
00129 
00130 static void ST2F_use_error(TOKEN_BUFFER tokens, ST *st);
00131 static void ST2F_use_var(TOKEN_BUFFER tokens, ST *st);
00132 static void ST2F_use_func(TOKEN_BUFFER tokens, ST *st);
00133 static void ST2F_use_const(TOKEN_BUFFER tokens, ST *st);
00134 static void ST2F_use_block(TOKEN_BUFFER tokens, ST *st);
00135 
00136 TOKEN_BUFFER  param_tokens =  New_Token_Buffer();
00137 
00138 /* The following maps every ST class to a function that can translate
00139  * it to C.
00140  */
00141 typedef void (*ST2F_HANDLER_FUNC)(TOKEN_BUFFER, ST *);
00142 
00143 static const ST2F_HANDLER_FUNC ST2F_Decl_Handler[CLASS_COUNT] =
00144 {
00145   &ST2F_ignore,      /* CLASS_UNK   == 0x00 */
00146   &ST2F_decl_var,    /* CLASS_VAR   == 0x01 */
00147   &ST2F_decl_func,   /* CLASS_FUNC  == 0x02 */
00148   &ST2F_decl_const,  /* CLASS_CONST == 0x03 */
00149   &ST2F_decl_error,  /* CLASS_PREG  == 0x04 */
00150   &ST2F_decl_error,  /* CLASS_BLOCK == 0x05 */
00151   &ST2F_decl_error,  /* CLASS_NAME  == 0x06 */
00152   &ST2F_decl_error,  /* CLASS_MODULE == 0x07*/
00153   &ST2F_decl_type,   /* CLASS_TYPE   ==0x08 */
00154   &ST2F_decl_parameter, /*CLASS_PARAMETER == 0x08 */
00155 }; /* ST2F_Decl_Handler */
00156 
00157 static const ST2F_HANDLER_FUNC ST2F_Use_Handler[CLASS_COUNT] =
00158 {
00159   &ST2F_ignore,        /* CLASS_UNK   == 0x00 */
00160   &ST2F_use_var,       /* CLASS_VAR   == 0x01 */
00161   &ST2F_use_func,      /* CLASS_FUNC  == 0x02 */
00162   &ST2F_use_const,     /* CLASS_CONST == 0x03 */
00163   &ST2F_use_error,     /* CLASS_PREG  == 0x04 */
00164   &ST2F_use_block,     /* CLASS_BLOCK == 0x05 */
00165   &ST2F_use_error      /* CLASS_NAME  == 0x06 */
00166 }; /* ST2F_Use_Handler */
00167 
00168 
00169 /*----------- hidden routines to handle ST declarations ---------------*/
00170 /*---------------------------------------------------------------------*/
00171 static void
00172 ST2F_Define_Preg(const char *name, TY_IDX ty)
00173 {
00174    /* Declare a preg of the given type, name and offset as a local
00175     * (register) variable in the current context.
00176     */
00177    TOKEN_BUFFER decl_tokens = New_Token_Buffer();
00178    UINT         current_indent = Current_Indentation();
00179 
00180    Set_Current_Indentation(PUinfo_local_decls_indent);
00181    Append_F77_Indented_Newline(PUinfo_local_decls, 1, NULL/*label*/);
00182    Append_Token_String(decl_tokens, name);
00183    TY2F_translate(decl_tokens, ty);
00184    Append_And_Reclaim_Token_List(PUinfo_local_decls, &decl_tokens);
00185    Set_Current_Indentation(current_indent);
00186 } /* ST2F_Define_Preg */
00187 
00188 
00189 static void 
00190 ST2F_ignore(TOKEN_BUFFER tokens, ST *st)
00191 {
00192    return; /* Just ignore it, i.e. do nothing! */
00193 } /* ST2F_ignore */
00194 
00195 static void 
00196 ST2F_decl_error(TOKEN_BUFFER tokens, ST *st)
00197 {
00198    ASSERT_DBG_FATAL(FALSE, 
00199                     (DIAG_W2F_UNEXPECTED_SYMCLASS,
00200                      ST_sym_class(st), "ST2F_decl_error"));
00201 } /* ST2F_decl_error */
00202 
00203 static void 
00204 ST2F_decl_var(TOKEN_BUFFER tokens, ST *st)
00205 {
00206    INITO_IDX    inito;
00207    const char  *pointee_name;
00208    const char  *st_name = W2CF_Symtab_Nameof_St(st);
00209    TOKEN_BUFFER decl_tokens = New_Token_Buffer();
00210    TY_IDX       ty_rt = ST_type(st);
00211    ST *base;
00212 
00213    ASSERT_DBG_FATAL(ST_sym_class(st)==CLASS_VAR, 
00214                     (DIAG_W2F_UNEXPECTED_SYMCLASS, 
00215                      ST_sym_class(st), "ST2F_decl_var"));
00216 
00217    if (Current_scope > GLOBAL_SYMTAB) 
00218    {
00219        ASSERT_DBG_FATAL(!PUINFO_RETURN_TO_PARAM || st != PUINFO_RETURN_PARAM, 
00220                        (DIAG_W2F_DECLARE_RETURN_PARAM, "ST2F_decl_var"));
00221    }
00222 
00223   base = ST_base(st);
00224 
00225 
00226 //  if (ST_sclass(st)==SCLASS_DGLOBAL && Stab_Is_Common_Block(base))
00227 //      goto INITPRO;
00228 
00229    /* Declare the variable */
00230 
00231  if (Stab_Is_Common_Block(st))
00232    {
00233       /* Declare a common block */
00234       TY2F_Translate_Common(decl_tokens, st_name, ST_type(st));
00235    }
00236    else if (Stab_Is_Equivalence_Block(st))
00237    {
00238       if (ST_is_return_var(st))
00239          TY2F_Translate_Equivalence(decl_tokens, 
00240                                     ST_type(st), 
00241                                     TRUE /* alternate return point */);
00242       else
00243          TY2F_Translate_Equivalence(decl_tokens, 
00244                                     ST_type(st), 
00245                                     FALSE /* regular equivalence */);
00246    }
00247    else if (TY_Is_Pointer(ty_rt) && 
00248             !TY_is_f90_pointer(ty_rt) &&
00249             ST_sclass(st) != SCLASS_FORMAL)
00250    {
00251       /* Declare pointee with the name specified in the symbol table */
00252 //      pointee_name = W2CF_Symtab_Nameof_St_Pointee(st);
00253       Append_Token_String(decl_tokens, st_name);
00254 
00255       if (TY_ptr_as_array(Ty_Table[ty_rt]))
00256          TY2F_translate(decl_tokens, 
00257                         Stab_Array_Of(TY_pointed(ty_rt), 0/*size*/));
00258       else
00259          TY2F_translate(decl_tokens, TY_pointed(ty_rt));
00260 
00261       Append_F77_Indented_Newline(decl_tokens, 1, NULL/*label*/);
00262 
00263       /* Declare the pointer object */
00264 //       Append_Token_String(decl_tokens, "POINTER");
00265 //       Append_Token_Special(decl_tokens, '(');
00266 //       Append_Token_String(decl_tokens, st_name);
00267 //       Append_Token_Special(decl_tokens, ',');
00268 //       Append_Token_String(decl_tokens, pointee_name);
00269 //       Append_Token_Special(decl_tokens, ')');
00270    }
00271    else if (ST_sclass(st) == SCLASS_FORMAL && !ST_is_value_parm(st))
00272    {
00273       /* ie, regular f77 dummy argument,expect pointer TY      */
00274       /* To counteract the Fortran call-by-reference semantics */
00275 
00276       ASSERT_DBG_FATAL(TY_Is_Pointer(ty_rt), 
00277                        (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
00278                         TY_kind(ty_rt), "ST2F_decl_var"));
00279       Append_Token_String(decl_tokens, st_name);
00280       if (TY_kind(TY_pointed(ST_type(st))) == KIND_FUNCTION)
00281       {
00282          Prepend_Token_String(decl_tokens, "EXTERNAL");
00283       }
00284       else
00285       {
00286          TY_IDX ty;
00287          TY_IDX ty1 = TY_pointed(ty_rt);
00288 
00289          if (TY_Is_Pointer(ty1) && TY_ptr_as_array(Ty_Table[ty1]))
00290          {
00291             /* Handle ptr as array parameters
00292              */
00293             ty = Stab_Array_Of(TY_pointed(ty1), 0/*size*/);
00294          }
00295          else
00296          {
00297             ty = TY_pointed(ty_rt);
00298          }
00299          if (Use_Purple_Array_Bnds_Placeholder && TY_Is_Array(ty))
00300             TY2F_Translate_Purple_Array(decl_tokens, st, ty);
00301          else {
00302             TY2F_translate(decl_tokens, ty);
00303          } 
00304       }
00305    }
00306    else if (ST2F_Is_Dummy_Procedure(st))
00307    {
00308        TYLIST tylist_idx = TY_tylist(TY_pointed(ST_type(st)));
00309        TY_IDX rt = TY_IDX_ZERO;
00310        if (tylist_idx != (TYLIST) 0)
00311          rt = TYLIST_type(Tylist_Table[tylist_idx]);
00312 
00313        ST2F_Declare_Return_Type(tokens,rt,ST_name(st));
00314    }
00315    else if (ST_sclass(st) == SCLASS_EXTERN &&
00316             (strcmp(ST_name(st), "__mp_cur_numthreads") == 0 ||
00317              strcmp(ST_name(st), "__mp_sug_numthreads") == 0))
00318    {
00319       /* Special case */
00320       st_name = Concat3_Strings(ST_name(st), "_func", "$");
00321       Append_Token_String(decl_tokens, st_name);
00322       TY2F_translate(decl_tokens, ST_type(st));
00323       Append_F77_Indented_Newline(decl_tokens, 1, NULL/*label*/);
00324       Append_Token_String(decl_tokens, "EXTERNAL ");
00325       Append_Token_String(decl_tokens, st_name);
00326    }
00327    else
00328    {
00329       /* Declare as specified in the symbol table */
00330       Append_Token_String(decl_tokens, st_name);
00331       if (Use_Purple_Array_Bnds_Placeholder && TY_Is_Array(ST_type(st)))
00332          TY2F_Translate_Purple_Array(decl_tokens, st, ST_type(st));
00333       else {
00334          TY2F_translate(decl_tokens, ST_type(st));
00335        }
00336    }
00337    TY2F_Prepend_Structures(decl_tokens);
00338    Append_And_Reclaim_Token_List(tokens, &decl_tokens);
00339 
00340    if (ST_is_allocatable(st)) {
00341        TOKEN_BUFFER decl_tokens=New_Token_Buffer();
00342        Append_Token_String(decl_tokens,"ALLOCATABLE");
00343        Append_Token_String(decl_tokens,ST_name(st));
00344        Append_Token_Special(tokens, '\n');
00345        Append_F77_Indented_Newline(tokens, 0, NULL);
00346        Append_And_Reclaim_Token_List(tokens,&decl_tokens); }
00347 
00348 
00349    if (ST_is_private(st)) {
00350        TOKEN_BUFFER decl_tokens=New_Token_Buffer();
00351        Append_Token_String(decl_tokens,"PRIVATE");
00352        Append_Token_String(decl_tokens,ST_name(st));
00353        Append_Token_Special(tokens, '\n');
00354        Append_F77_Indented_Newline(tokens, 0, NULL);
00355        Append_And_Reclaim_Token_List(tokens,&decl_tokens); }
00356 
00357    if (ST_is_my_pointer(st)) {
00358        TOKEN_BUFFER decl_tokens=New_Token_Buffer();
00359        Append_Token_String(decl_tokens,"POINTER");
00360        Append_Token_String(decl_tokens,ST_name(st));
00361        Append_Token_Special(tokens, '\n');
00362        Append_F77_Indented_Newline(tokens, 0, NULL);
00363        Append_And_Reclaim_Token_List(tokens,&decl_tokens); }
00364 
00365    if (ST_is_f90_target(st)) {
00366        TOKEN_BUFFER decl_tokens=New_Token_Buffer();
00367        Append_Token_String(decl_tokens,"TARGET");
00368        Append_Token_String(decl_tokens,ST_name(st));
00369        Append_Token_Special(tokens, '\n');
00370        Append_F77_Indented_Newline(tokens, 0, NULL);
00371        Append_And_Reclaim_Token_List(tokens,&decl_tokens); }
00372 
00373 
00374    /* Save it's value between calls, if so specified, unless it is
00375     * an equivalence, in which case it is implicitly SAVE.
00376     */
00377    if (!Stab_Is_Equivalence_Block(st) &&
00378        !ST_is_parameter(st) &&
00379        (ST_sclass(st) == SCLASS_FSTATIC || 
00380         ST_sclass(st) == SCLASS_PSTATIC))
00381    {
00382       Append_F77_Indented_Newline(tokens, 1, NULL/*label*/);
00383       Append_Token_String(tokens, "SAVE");
00384       Append_Token_String(tokens, st_name);
00385    }
00386 
00387 INITPRO:
00388    /* Generate a DATA statement for initializers */
00389    if (ST_is_parameter(st)){
00390        inito = Find_INITO_For_Symbol(st);
00391        if (inito != (INITO_IDX) 0) {
00392           TOKEN_BUFFER decl_tokens=New_Token_Buffer();
00393           PARAMETER2F_translate(decl_tokens,inito);
00394           Append_F77_Indented_Newline(tokens, 1, NULL);
00395           Append_And_Reclaim_Token_List(tokens,&decl_tokens); }
00396        }
00397      else {
00398       if (ST_is_initialized(st) && 
00399        !Stab_No_Linkage(st)  )
00400 //     (!TY_Is_Structured(ST_type(st)) ||  /*structure can be initialized--FMZ*/
00401 //      (Stab_Is_Common_Block(st)      || 
00402 //      Stab_Is_Equivalence_Block(st))) 
00403        {
00404           inito = Find_INITO_For_Symbol(st);
00405           if (inito != (INITO_IDX) 0)
00406              INITO2F_translate(Data_Stmt_Tokens, inito);
00407        }
00408      }
00409 } /* ST2F_decl_var */
00410 
00411 static void 
00412 ST2F_decl_type(TOKEN_BUFFER tokens, ST *st)
00413 {
00414    const char  *st_name = W2CF_Symtab_Nameof_St(st);
00415    TOKEN_BUFFER decl_tokens = New_Token_Buffer();
00416    TY_IDX       ty_rt = ST_type(st);
00417 
00418    ASSERT_DBG_FATAL(ST_sym_class(st)==CLASS_TYPE, 
00419                     (DIAG_W2F_UNEXPECTED_SYMCLASS, 
00420                      ST_sym_class(st), "ST2F_decl_type"));
00421 
00422    if (Current_scope > GLOBAL_SYMTAB) 
00423        ASSERT_DBG_FATAL(!PUINFO_RETURN_TO_PARAM || st != PUINFO_RETURN_PARAM, 
00424                        (DIAG_W2F_DECLARE_RETURN_PARAM, "ST2F_decl_var"));
00425 
00426       if (Use_Purple_Array_Bnds_Placeholder && TY_Is_Array(ST_type(st)))
00427          TY2F_Translate_Purple_Array(decl_tokens, st, ST_type(st));
00428       else {
00429          TY2F_translate(decl_tokens, ST_type(st),1);
00430        }
00431    TY2F_Prepend_Structures(decl_tokens);
00432    Append_And_Reclaim_Token_List(tokens, &decl_tokens);
00433 
00434 } /* ST2F_decl_type */
00435 
00436 static void
00437 ST2F_decl_parameter(TOKEN_BUFFER tokens, ST *st)
00438 {
00439   const char    *st_name = W2CF_Symtab_Nameof_St(st);
00440   TOKEN_BUFFER  decl_tokens = New_Token_Buffer();
00441   TY_IDX        ty_rt = ST_type(st);
00442   ST            *base = ST_base(st);
00443   
00444   
00445   Append_Token_String(decl_tokens,st_name);
00446   if (Use_Purple_Array_Bnds_Placeholder && TY_Is_Array(ST_type(st)))
00447      TY2F_Translate_Purple_Array(decl_tokens, st, ST_type(st));
00448   else
00449      TY2F_translate(decl_tokens, ST_type(st));
00450   TY2F_Prepend_Structures(decl_tokens);
00451   Append_And_Reclaim_Token_List(tokens, &decl_tokens);
00452 /*other attributes that are allowed with the PARAMETER attribute are:
00453  *      DIMENSION
00454  *      PRIVATE
00455  *      PUBLIC
00456  *      SAVE
00457  */
00458 
00459   if (ST_is_private(st)) {
00460        decl_tokens=New_Token_Buffer();
00461        Append_Token_String(decl_tokens,"PRIVATE");
00462        Append_Token_String(decl_tokens,ST_name(st));
00463        Append_Token_Special(tokens, '\n');
00464        Append_F77_Indented_Newline(tokens, 0, NULL);
00465        Append_And_Reclaim_Token_List(tokens,&decl_tokens); }
00466 
00467 /* print out para_name = (value) */
00468 
00469     decl_tokens=New_Token_Buffer();
00470     Append_Token_String(decl_tokens,"PARAMETER (");
00471     Append_Token_String(decl_tokens,st_name);
00472     Append_Token_Special(decl_tokens, '=' );
00473     TCON2F_translate(decl_tokens,STC_val(base),TY_is_logical(ST_type(st)));
00474     Append_Token_Special(decl_tokens, ')'); 
00475     
00476     Append_Token_Special(tokens, '\n');
00477     Append_F77_Indented_Newline(tokens, 0, NULL);
00478     Append_And_Reclaim_Token_List(tokens,&decl_tokens); 
00479 
00480 } /* ST_decl_parameter */
00481 
00482 static void 
00483 ST2F_decl_func(TOKEN_BUFFER tokens, ST *st)
00484 {
00485    /* This only makes sense for "external" functions in Fortran,
00486     * while we should not do anything for other functions.
00487     */
00488    ASSERT_DBG_FATAL(ST_sym_class(st)==CLASS_FUNC,
00489                     (DIAG_W2F_UNEXPECTED_SYMCLASS, 
00490                      ST_sym_class(st), "ST2F_decl_func"));
00491    
00492    /* if f90 internal procedure, don't declare it */
00493 
00494    if (ST_export(st) == EXPORT_LOCAL_INTERNAL)
00495      return ;
00496 
00497    const char  *func_name = W2CF_Symtab_Nameof_St(st);
00498    TY_IDX       return_ty;
00499 
00500 
00501    /* Specify whether or not the function is EXTERNAL */
00502 
00503    if ((ST_sclass(st) == SCLASS_EXTERN) &&
00504       (strcmp(ST_name(st),"_ALLOCATE")!=0) &&
00505       (strcmp(ST_name(st),"_END")!=0) &&
00506       (strcmp(ST_name(st),"_DEALLOCATE") !=0)&&
00507       (strcmp(ST_name(st),"_CLOSE") !=0 )    &&
00508       (strcmp(ST_name(st),"_OPEN")!=0   ))
00509    {
00510      if(strncmp("_",func_name,1)!=0) { /*don't declare function name begin with "_" as external*/
00511         Append_Token_String(tokens, "EXTERNAL");
00512         Append_Token_String(tokens, func_name);
00513       }
00514    }
00515 
00516    /* Specify the function return type, unless it is void */
00517 
00518    return_ty = W2X_Unparse_Target->Func_Return_Type(ST_pu_type(st));
00519   if (strncmp("_",func_name,1)!=0)
00520        ST2F_Declare_Return_Type(tokens,return_ty,func_name);
00521 
00522 } /* ST2F_decl_func */
00523 
00524 static void 
00525 ST2F_decl_const(TOKEN_BUFFER tokens, ST *st)
00526 {
00527    /* A CLASS_CONST symbol never has a name, and as such cannot be
00528     * declared!
00529     */
00530    ASSERT_DBG_FATAL(FALSE, 
00531                     (DIAG_W2F_UNEXPECTED_SYMCLASS, 
00532                      ST_sym_class(st), "ST2F_decl_const"));
00533 } /* ST2F_decl_const */
00534 
00535 
00536 /*---------------- hidden routines to handle ST uses ------------------*/
00537 /*---------------------------------------------------------------------*/
00538 
00539 static void 
00540 ST2F_use_error(TOKEN_BUFFER tokens, ST *st)
00541 {
00542    ASSERT_DBG_FATAL(FALSE, 
00543                     (DIAG_W2F_UNEXPECTED_SYMCLASS,
00544                      ST_sym_class(st), "ST2F_use_error"));
00545 } /* ST2F_use_error */
00546 
00547 static void 
00548 ST2F_use_var(TOKEN_BUFFER tokens, ST *st)
00549 {
00550    TY_IDX return_ty;
00551 
00552    ASSERT_DBG_FATAL(ST_sym_class(st)==CLASS_VAR, 
00553                     (DIAG_W2F_UNEXPECTED_SYMCLASS, 
00554                      ST_sym_class(st), "ST2F_use_var"));
00555 
00556    /* Note that we do not trust the ST_is_return_var() flag,
00557     * unless the return_ty is non-void.  This is due to purple,
00558     * which may change a function into a subroutine.
00559     */
00560    return_ty = PUINFO_RETURN_TY;
00561    if ((return_ty != (TY_IDX) 0 && 
00562         TY_kind(return_ty) == KIND_SCALAR && 
00563         ST_is_return_var(st)) ||    
00564        (PUINFO_RETURN_TO_PARAM && st == PUINFO_RETURN_PARAM))
00565    {
00566       /* If we have a reference to the implicit return-variable, then
00567        * refer to the function return value.
00568        */
00569       Append_Token_String(tokens, PUINFO_FUNC_NAME);
00570    }
00571    else if (ST_keep_name_w2f(st))
00572    {
00573       /* Use the name as it is (after making it a legal fortran name)
00574        * and do not mark this variable as having been referenced.
00575        * Assume this a special symbol not to be declared.
00576        */
00577       Append_Token_String(tokens, 
00578                           WHIRL2F_make_valid_name(ST_name(st),WN2F_F90_pu && !ST_is_temp_var(st)));
00579      if  (Stab_Is_Based_At_Common_Or_Equivalence(st))
00580            Set_BE_ST_w2fc_referenced((ST *)ST_base(st));
00581      else
00582            Set_BE_ST_w2fc_referenced(st); //June
00583    }
00584    else if (Stab_Is_Based_At_Common_Or_Equivalence(st))
00585    {
00586       /* Reference the corresponding field in the common block (we do this
00587        * only to ensure that the name referenced matches the one used for
00588        * the member of the common-block at the place of declaration).  Note
00589        * that will full splitting, the original common block can be found
00590        * at ST_full(ST_base(st)).
00591        */
00592       WN2F_CONTEXT context = INIT_WN2F_CONTEXT;
00593 
00594       WN2F_Offset_Symref(tokens, 
00595                          ST_base(st),                         /* base-symbol */
00596                          Stab_Pointer_To(ST_type(ST_base(st))), /* base-type */
00597                          ST_type(st),                         /* object-type */
00598                          ST_ofst(st),                         /* object-ofst */
00599                          context);
00600       Set_BE_ST_w2fc_referenced((ST *)ST_base(st));
00601    }
00602    else if (ST_sclass(st) == SCLASS_EXTERN &&
00603             (strcmp(ST_name(st), "__mp_cur_numthreads") == 0 ||
00604              strcmp(ST_name(st), "__mp_sug_numthreads") == 0))
00605    {
00606       /* Special case */
00607       Append_Token_String(tokens, Concat3_Strings(ST_name(st), "_func", "$"));
00608       Append_Token_Special(tokens, '(');
00609       Append_Token_Special(tokens, ')');
00610       Set_BE_ST_w2fc_referenced(st);
00611    }
00612    else
00613    {
00614       Append_Token_String(tokens, W2CF_Symtab_Nameof_St(st));
00615 
00616       if (strcmp(TY_name(ST_type(st)),".Namelist."))
00617 
00618       Set_BE_ST_w2fc_referenced(st);
00619    }
00620 } /* ST2F_use_var */
00621 
00622 
00623 static void 
00624 ST2F_use_func(TOKEN_BUFFER tokens, ST *st)
00625 {
00626    ASSERT_DBG_FATAL(ST_sym_class(st)==CLASS_FUNC, 
00627                     (DIAG_W2F_UNEXPECTED_SYMCLASS, 
00628                      ST_sym_class(st), "ST2F_use_func"));
00629 
00630    Append_Token_String(tokens, W2CF_Symtab_Nameof_St(st));
00631    Set_BE_ST_w2fc_referenced(st);
00632 }
00633 
00634 static void 
00635 ST2F_use_const(TOKEN_BUFFER tokens, ST *st)
00636 {
00637    TY_IDX ty_idx = ST_type(st);
00638    TY& ty = Ty_Table[ty_idx];
00639 
00640    ASSERT_DBG_FATAL(ST_sym_class(st)==CLASS_CONST, 
00641                     (DIAG_W2F_UNEXPECTED_SYMCLASS, 
00642                      ST_sym_class(st), "ST2F_use_const"));
00643    
00644    /* A CLASS_CONST symbol never has a name, so just emit the value.
00645     */
00646 
00647    if (TY_mtype(ty) == MTYPE_STR && TY_align(ty_idx) > 1)
00648    {
00649       /* This must be a hollerith constant */
00650       TCON2F_hollerith(tokens, STC_val(st));
00651    }
00652    else
00653    {
00654       TCON2F_translate(tokens, STC_val(st), TY_is_logical(ty));
00655    }
00656 } /* ST2F_use_const */
00657 
00658 
00659 static void 
00660 ST2F_use_block(TOKEN_BUFFER tokens, ST *st)
00661 {
00662   /* with f90 at -O2, CLASS_BLOCK can appear on LDAs etc. in IO */
00663   /* put out something, so whirlbrowser doesn't fall over       */
00664 
00665    ASSERT_DBG_FATAL(ST_sym_class(st)==CLASS_BLOCK, 
00666                     (DIAG_W2F_UNEXPECTED_SYMCLASS, 
00667                      ST_sym_class(st), "ST2F_use_block"));
00668 
00669 
00670    Append_Token_String(tokens, ST_name(st));   
00671 } 
00672 
00673 /*------------------------ exported routines --------------------------*/
00674 /*---------------------------------------------------------------------*/
00675 
00676 
00677 void 
00678 ST2F_initialize()
00679 {
00680 
00681   return; 
00682 } /* ST2F_initialize */
00683 
00684 void 
00685 ST2F_finalize()
00686 {
00687   return; 
00688 } 
00689 
00690 void 
00691 ST2F_use_translate(TOKEN_BUFFER tokens, ST *st)
00692 { 
00693    ST2F_Use_Handler[ST_sym_class(st)](tokens, st);
00694 } 
00695 
00696 void 
00697 ST2F_deref_translate(TOKEN_BUFFER tokens, ST *st)
00698 {
00699    ASSERT_DBG_FATAL(ST_sym_class(st)==CLASS_VAR && 
00700                     TY_Is_Pointer(ST_type(st)) &&
00701                     !Stab_Is_Based_At_Common_Or_Equivalence(st), 
00702                     (DIAG_W2F_UNEXPECTED_SYMCLASS, 
00703                      ST_sym_class(st), "ST2F_deref_translate"));
00704 
00705    /* Consider this a reference to the pointer value */
00706    Append_Token_String(tokens, W2CF_Symtab_Nameof_St_Pointee(st));
00707    Set_BE_ST_w2fc_referenced(st);
00708 
00709 } /* ST2F_deref_translate */
00710 
00711 
00712 // dispatch handler for declarations..
00713 void 
00714 ST2F_decl_translate(TOKEN_BUFFER tokens, const ST *st)
00715 { 
00716    ST2F_Decl_Handler[ST_sym_class(st)](tokens, (ST *) st);
00717 } 
00718 
00719 static void
00720 collectst(WN *wn,PARMSET &tempset)
00721  {
00722 
00723    if (!wn) return;
00724 
00725    if (WN_opc_operator(wn) == OPR_LDID ||
00726        WN_opc_operator(wn) == OPR_LDA)
00727       tempset.insert(WN_st_idx(wn));
00728    else
00729      for (INT32 kidnum = 0; kidnum < WN_kid_count(wn); kidnum++)
00730        collectst(WN_kid(wn, kidnum),tempset);
00731    return;
00732  }
00733 
00734 
00735 static void GetStSet(ST_IDX bnd,PARMSET &tempset)
00736 {
00737    WN * stmt;
00738    WN *first_stmt = WN_first(PU_Body);
00739    WN kid;
00740 
00741    stmt = first_stmt;
00742    while ((stmt !=NULL)&&((WN_operator(stmt)!=OPR_STID)
00743                            ||(WN_operator(stmt) ==OPR_STID)
00744                            &&strcmp(ST_name(WN_st(stmt)),ST_name(ST_ptr(bnd)))))
00745 
00746        stmt = WN_next(stmt);
00747 
00748   if (stmt && WN_kid(stmt,0))
00749      collectst(WN_kid(stmt,0),tempset);
00750 }
00751 
00752 void ReorderParms(ST **parms,INT32 num_params)
00753 {
00754   INT32 i;
00755   ST **reorder_parms;
00756   ST_IDX bdindex;
00757   TY_IDX ty_index;
00758   ST_IDX real_index;
00759   PARMSET::iterator runner;
00760 
00761   vector<PARMSET> dependset(num_params);
00762   map<ST_IDX,int>  st_idx_to_parms;
00763   PARMSET  workset, tempst;
00764 
00765   workset.clear();
00766   reorder_parms = (ST **)alloca((num_params + 1) * sizeof(ST *));
00767   for (i=0; i<num_params; i++)
00768       st_idx_to_parms[(ST_IDX)(parms[i]->st_idx)] = i;
00769 
00770   for (i=0; i<num_params; i++)
00771    if (TY_kind(ST_type(parms[i])) == KIND_POINTER ){
00772         ty_index = TY_pointed(ST_type(parms[i]));
00773 
00774         if ((TY_kind(ty_index) == KIND_ARRAY) &&
00775              !TY_is_character(ty_index) &&
00776               !TY_is_f90_deferred_shape(ty_index)){
00777 
00778           TY& ty = Ty_Table[ty_index];
00779           ARB_HANDLE  arb_base = TY_arb(ty);
00780           ARB_HANDLE  arb;
00781           INT32       dim = ARB_dimension(arb_base) ;
00782           while (dim > 0){
00783              arb = arb_base[dim-1];
00784              if (ARB_const_lbnd(arb)&& ARB_const_ubnd(arb))
00785                      ;
00786              else {
00787               workset.insert(i);
00788               if (!ARB_const_lbnd(arb) && !ARB_empty_lbnd(arb)){
00789                  bdindex = ARB_lbnd_var(arb);
00790                  if (ST_is_temp_var(St_Table[bdindex])){
00791                      GetStSet(bdindex,tempst);
00792                      runner = tempst.begin();
00793                      while (runner != tempst.end()){
00794                      if (st_idx_to_parms[*runner]!=i)
00795                          dependset[i].insert(st_idx_to_parms[*runner]);
00796                       ++runner;
00797                     }
00798                   }
00799                  }
00800 
00801               if (!ARB_const_ubnd(arb) && !ARB_empty_ubnd(arb)){
00802                  bdindex = ARB_ubnd_var(arb);
00803                  if (ST_is_temp_var(St_Table[bdindex])){
00804                      GetStSet(bdindex,tempst);
00805                      runner = tempst.begin();
00806                      while (runner != tempst.end()){
00807                      if (st_idx_to_parms[*runner]!=i)
00808                          dependset[i].insert(st_idx_to_parms[*runner]);
00809                       ++runner;
00810                     }
00811                   }
00812                  }
00813                }
00814             dim--;
00815           }/*while*/
00816       }
00817    }
00818   INT32 keep = 0;
00819 
00820   for (i = 0; i<num_params; i++){
00821    if (dependset[i].empty()){
00822      workset.erase(i);
00823      reorder_parms[keep] = parms[i];
00824      keep++;
00825      for (INT32 j=0; j<num_params; j++){
00826            dependset[j].erase(i);
00827      } 
00828     }
00829   }
00830 
00831   PARMSET::iterator cleaner;
00832   vector<int> elems;
00833  
00834   if (!workset.empty())
00835    {
00836     runner = workset.begin();
00837     while (runner != workset.end()) {
00838      if (dependset[*runner].empty()){
00839         reorder_parms[keep] = parms[*runner];
00840         keep++;
00841         cleaner = workset.begin();
00842         while(cleaner !=workset.end()){
00843            dependset[*cleaner].erase(*runner);
00844            ++cleaner;
00845         }
00846          elems.push_back(*runner);
00847      }
00848      ++runner;
00849    }
00850  }
00851 
00852  while (!elems.empty())
00853   {
00854     INT32 i = elems.back();
00855     workset.erase(i);
00856     elems.pop_back();
00857   }
00858 
00859 //tempory for interface has temp variable but there is no assginment
00860 // statement kept in the interface block  
00861   if (!workset.empty()){
00862    runner = workset.begin();
00863    while (runner != workset.end()){
00864       reorder_parms[keep] = parms[*runner];
00865       runner++;
00866       keep++;
00867    }
00868   }
00869 
00870   for(INT32 k=0; k<num_params; k++)
00871       parms[k] = reorder_parms[k];
00872   return;
00873 }
00874 
00875 void
00876 ST2F_func_header(TOKEN_BUFFER tokens,
00877                  ST          *st,          /* Function ST entry     */
00878                  ST         **params,      /* Array of  parameters  */
00879                  INT32        num_params,  /* # of parms in array   */
00880                  BOOL         is_altentry) /* Alternate entry point */
00881 {
00882    /* Emit the header for a function definition or an alternate entry
00883     * point.  Note that the resultant token buffer will not have 
00884     * appended a newline after the function header.
00885     */
00886    TOKEN_BUFFER header_tokens = New_Token_Buffer();
00887    INT          param, first_param, implicit_parms = 0;
00888    TY_IDX       funtype = ST_pu_type(st);
00889    TY_IDX       return_ty;
00890    WN *wn;   
00891    WN *stmt;
00892    ST *rslt = NULL;
00893    BOOL needcom=1;
00894    BOOL has_result = 0;
00895    BOOL add_rsl_type = 0;
00896    BOOL is_module_program_unit = FALSE;
00897 
00898    const char * func_n_name= W2CF_Symtab_Nameof_St(st);
00899 
00900    ASSERT_DBG_FATAL(TY_kind(funtype) == KIND_FUNCTION,
00901                     (DIAG_W2F_UNEXPECTED_SYMBOL, "ST2F_func_header"));
00902 
00903    return_ty = W2X_Unparse_Target->Func_Return_Type(funtype);
00904 
00905    /* Append the function name */
00906 
00907    Append_Token_String(header_tokens, W2CF_Symtab_Nameof_St(st));
00908 
00909    /* Emit the parameter name-list, if one is present, and skip any
00910     * implicit "length" parameters associated with character strings.
00911     * Such implicit parameters should be at the end of the parameter list.
00912     */
00913 
00914    first_param = ST2F_FIRST_PARAM_IDX(funtype);
00915 
00916    if (params[first_param] != NULL)
00917    {
00918       Append_Token_Special(header_tokens, '(');
00919       for (param = first_param; 
00920            param < num_params - implicit_parms; 
00921            param++)
00922       {
00923          if (!ST_is_return_var(params[param]))  
00924                  Append_Token_String(header_tokens, 
00925                               W2CF_Symtab_Nameof_St(params[param]));
00926          else {
00927               rslt = params[param];
00928               needcom = 0;
00929               }
00930  
00931          if (STAB_PARAM_HAS_IMPLICIT_LENGTH(params[param])) 
00932          {
00933             implicit_parms++;
00934 
00935             /* is function returning character_TY? if length follows    */
00936             /* address - skip over it, but account for ',' in arg list  */
00937 
00938             if ((param == first_param) && (params[param+1] != NULL)) 
00939             {
00940               if (ST_is_value_parm(params[param]) && ST_is_value_parm(params[param+1])) 
00941               {
00942                 if (return_ty != (TY_IDX) 0 && TY_kind(return_ty) == KIND_VOID ) 
00943                 {
00944                   param ++ ;
00945                   params[param] = NULL; 
00946                   implicit_parms--;
00947                 }
00948               }
00949             }
00950          }
00951 
00952          if (param+implicit_parms+1 < num_params && needcom)
00953                    Append_Token_Special(header_tokens, ',');
00954          needcom = 1;
00955     }
00956       Append_Token_Special(header_tokens, ')');
00957    }
00958    else if (!PU_is_mainpu(Get_Current_PU()) &&
00959              !ST_is_in_module(st) &&
00960              !ST_is_block_data(st) ||
00961              TY_kind(return_ty) != KIND_VOID)   // module&&block data cannot have "()" 
00962 
00963    {
00964       /* Use the "()" notation for "no parameters", except for
00965        * the main program definition.
00966        */
00967       Append_Token_Special(header_tokens, '(');
00968       Append_Token_Special(header_tokens, ')');
00969    }
00970 
00971 /* need to see if the result variable has same name with the function's 
00972  * name,if it does,don't declare the result variable
00973  */
00974   
00975     if (rslt !=NULL       && 
00976          strcasecmp(W2CF_Symtab_Nameof_St(rslt),W2CF_Symtab_Nameof_St(st))) { 
00977         has_result = 1;
00978         Append_Token_String(header_tokens,"result(");
00979         Append_Token_String(header_tokens,
00980                              W2CF_Symtab_Nameof_St(rslt));
00981         Append_Token_Special(header_tokens, ')');
00982      }
00983    
00984    /* Prepend one of the keywords ENTRY, PROGRAM, FUNCTION, or
00985     * SUBROUTINE to the function name, as is appropriate.
00986     */
00987 
00988    if (PU_is_mainpu(Get_Current_PU()))
00989    {
00990       Prepend_Token_String(header_tokens, "PROGRAM");
00991    }
00992    else if (return_ty != (TY_IDX) 0 && TY_kind(return_ty) != KIND_VOID)
00993    {
00994      if (is_altentry)
00995        Prepend_Token_String(header_tokens, "ENTRY");
00996      else
00997      {
00998        Prepend_Token_String(header_tokens, "Function");
00999 
01000      if (PU_recursive(Get_Current_PU())) 
01001        Prepend_Token_String(header_tokens, "RECURSIVE");
01002        
01003       if (!has_result && (TY_kind(return_ty)!= KIND_ARRAY ||
01004                                 !TY_is_character(TY_AR_etype(return_ty))))
01005               add_rsl_type=1;
01006       }
01007    }
01008    else /* subroutine */
01009    {
01010       if (is_altentry)
01011          Prepend_Token_String(header_tokens, "ENTRY");
01012       else
01013       if (ST_is_in_module(st) && !PU_is_nested_func(Pu_Table[ST_pu(st)])){
01014          Prepend_Token_String(header_tokens, "MODULE");  
01015          is_module_program_unit = TRUE;
01016        }
01017       else
01018       if (ST_is_block_data(st))
01019          Prepend_Token_String(header_tokens, "BLOCK DATA");
01020       else { 
01021          Prepend_Token_String(header_tokens, "SUBROUTINE");
01022          if (PU_recursive(Get_Current_PU()))
01023            Prepend_Token_String(header_tokens, "RECURSIVE");
01024       }
01025    }
01026 
01027   
01028     wn=PU_Body;
01029     stmt = WN_first(wn);
01030     int k;
01031     const char *st_name;
01032     const char *st_name1;
01033 
01034 /* add a use stmt corresponding to an added module in *.w2f.f
01035  * to solve the real kind problems
01036  * if the block is alter entry,do nothing.
01037  *--------fzhao
01038  */
01039    if (!is_altentry) {
01040      Append_F77_Indented_Newline(header_tokens, 1/*empty-lines*/, NULL/*label*/);
01041      Append_Token_String(header_tokens, "use w2f__types");
01042     }
01043 
01044     while (stmt) {
01045       if (WN_operator(stmt)==OPR_USE){
01046        st_name = W2CF_Symtab_Nameof_St(WN_st(stmt));
01047        Append_F77_Indented_Newline(header_tokens, 1/*empty-lines*/, NULL/*label*/);
01048        Append_Token_String(header_tokens, "use");
01049        Append_Token_String(header_tokens, st_name);
01050        if (WN_rtype(stmt) == MTYPE_B) // signals presence of the ONLY predicate
01051          Append_Token_String(header_tokens, ",only:");
01052        else { 
01053          if ( WN_kid_count(stmt) ) { 
01054            Append_Token_String(header_tokens, ",");
01055          }
01056        }
01057        
01058        for(k=0;k< WN_kid_count(stmt);k=k+2 ) {
01059          
01060          st_name = W2CF_Symtab_Nameof_St(WN_st(WN_kid(stmt,k)));
01061          st_name1= W2CF_Symtab_Nameof_St(WN_st(WN_kid(stmt,k+1)));
01062          if (k==0)
01063            ;
01064          else
01065            Append_Token_String(header_tokens,",");
01066          if (strcmp(st_name,st_name1)) {
01067            Append_Token_String(header_tokens,st_name);
01068            Append_Token_String(header_tokens,"=>");
01069            Append_Token_String(header_tokens, st_name1);
01070          } 
01071          else
01072            Append_Token_String(header_tokens,st_name);
01073        } 
01074       }
01075       stmt = WN_next(stmt);
01076     }  /*while*/
01077 
01078    if (num_params)
01079        ReorderParms(params,num_params-implicit_parms);
01080    param_tokens = New_Token_Buffer();
01081 
01082    if (!is_altentry)
01083    {
01084       /* Emit parameter declarations, indented and on a new line */
01085       Append_F77_Indented_Newline(header_tokens, 1, NULL/*label*/);
01086       Append_Token_String(header_tokens, "IMPLICIT NONE");
01087 
01088       if (is_module_program_unit){
01089           Append_F77_Indented_Newline(header_tokens, 1, NULL/*label*/);
01090           Append_Token_String(header_tokens, "SAVE");
01091           is_module_program_unit = FALSE;
01092         } 
01093 
01094       for (param = first_param; param < num_params -implicit_parms; param++) {
01095 
01096          Append_F77_Indented_Newline(param_tokens, 1, NULL/*label*/);
01097          if (params[param] )  {
01098             if (strcasecmp(W2CF_Symtab_Nameof_St(params[param]),W2CF_Symtab_Nameof_St(st))) {
01099 
01100               ST2F_decl_translate(param_tokens, params[param]);
01101 
01102              if (ST_is_optional_argument( params[param])) {
01103                 Append_F77_Indented_Newline(param_tokens, 1, NULL/*label*/);
01104                 Append_Token_String(param_tokens,"OPTIONAL ");
01105                 Append_Token_String(param_tokens,
01106                               W2CF_Symtab_Nameof_St(params[param]));
01107              }
01108              if (ST_is_intent_in_argument( params[param])) {
01109                 TOKEN_BUFFER temp_tokens = New_Token_Buffer();
01110                 Append_F77_Indented_Newline(temp_tokens, 1, NULL/*label*/);
01111                 Append_Token_String(temp_tokens,"INTENT(IN) ");
01112                 Append_Token_String(temp_tokens,
01113                               W2CF_Symtab_Nameof_St(params[param]));
01114                 Append_And_Reclaim_Token_List(param_tokens, &temp_tokens);
01115 
01116               }
01117              if (ST_is_intent_out_argument( params[param])) {
01118                  Append_F77_Indented_Newline(param_tokens, 1, NULL/*label*/);
01119                  Append_Token_String(param_tokens,"INTENT(OUT) ");
01120                  Append_Token_String(param_tokens,
01121                               W2CF_Symtab_Nameof_St(params[param]));
01122              }
01123 
01124            } 
01125         else
01126              if (!strcasecmp(W2CF_Symtab_Nameof_St(rslt),W2CF_Symtab_Nameof_St(st)))
01127                      ST2F_decl_translate(param_tokens, params[param]);
01128        }
01129    }
01130 
01131     }
01132     
01133     if (add_rsl_type){
01134       TOKEN_BUFFER temp_tokens = New_Token_Buffer();
01135        Append_F77_Indented_Newline(param_tokens, 1, NULL/*label*/);
01136        if (TY_Is_Pointer(return_ty))
01137            TY2F_translate(temp_tokens, Stab_Mtype_To_Ty(TY_mtype(return_ty)));
01138        else {
01139            if (TY_kind(return_ty)==KIND_ARRAY)  {
01140                   if (TY_is_character(TY_AR_etype(return_ty)))
01141                              ;
01142                    else
01143                          TY2F_translate(temp_tokens,TY_AR_etype(return_ty));
01144                   }
01145            else
01146                 TY2F_translate(temp_tokens, return_ty);
01147             }
01148        Append_Token_String(temp_tokens, W2CF_Symtab_Nameof_St(st));
01149        Append_And_Reclaim_Token_List(param_tokens, &temp_tokens);
01150     }
01151 
01152    Append_Token_Special(tokens, '\n');
01153    Append_F77_Indented_Newline(tokens, 0, NULL);
01154    Append_And_Reclaim_Token_List(tokens, &header_tokens);
01155 
01156 } /* ST2F_func_header */
01157 
01158 void
01159 ST2F_Use_Preg(TOKEN_BUFFER tokens,
01160               TY_IDX       preg_ty,
01161               PREG_IDX     preg_idx)
01162 {
01163    /* Append the name of the preg to the token-list and declare the
01164     * preg in the current PU context unless it is already declared.
01165     */
01166    const char *preg_name;
01167 
01168    preg_ty = PUinfo_Preg_Type(preg_ty, preg_idx);
01169    preg_name = W2CF_Symtab_Nameof_Preg(preg_ty, preg_idx);
01170 
01171    /* Declare the preg, if it has not already been declared */
01172    if (!PUinfo_Is_Preg_Declared(preg_ty, preg_idx))
01173    {
01174       ST2F_Define_Preg(preg_name, preg_ty);
01175       PUinfo_Set_Preg_Declared(preg_ty, preg_idx);
01176    }
01177 
01178    Append_Token_String(tokens, preg_name);
01179 } /* ST2F_Use_Preg */
01180 
01181 void 
01182 ST2F_Declare_Tempvar(TY_IDX ty, UINT idx)
01183 {
01184    TOKEN_BUFFER tmp_tokens = New_Token_Buffer();
01185    UINT         current_indent = Current_Indentation();
01186 
01187    Set_Current_Indentation(PUinfo_local_decls_indent);
01188    Append_F77_Indented_Newline(PUinfo_local_decls, 1, NULL/*label*/);
01189    if (TY_Is_Pointer(ty))
01190    {
01191       /* Assume we never need to dereference the pointer, or else we
01192        * need to maintain a map from tmp_idx->pointee_idx (new temporary
01193        * for pointee_idx), so declare this temporary variable to be of
01194        * an integral type suitable for a pointer value.
01195        */
01196       ty = Stab_Mtype_To_Ty(Pointer_Mtype);
01197    }
01198    Append_Token_String(tmp_tokens, W2CF_Symtab_Nameof_Tempvar(idx)); /* name */
01199    TY2F_translate(tmp_tokens, ty);                                   /* type */
01200   if (ST_is_in_module(Scope_tab[Current_scope].st) &&
01201       !PU_is_nested_func(Pu_Table[ST_pu(Scope_tab[Current_scope].st)]))
01202      {
01203        Append_F77_Indented_Newline(tmp_tokens, 1, NULL/*label*/);
01204        Append_Token_String(tmp_tokens,"PRIVATE ");
01205        Append_Token_String(tmp_tokens, W2CF_Symtab_Nameof_Tempvar(idx));
01206      }
01207 
01208    Append_And_Reclaim_Token_List(PUinfo_local_decls, &tmp_tokens);
01209    Set_Current_Indentation(current_indent);
01210 } /* ST2F_Declare_Tempvar */
01211 
01212 
01213 static BOOL
01214 ST2F_Is_Dummy_Procedure(ST *st)
01215 {
01216   /* Does this ST represent a dummy procedure ? */
01217 
01218   BOOL dummy = FALSE;
01219 
01220   if (ST_sclass(st) == SCLASS_FORMAL && ST_is_value_parm(st))
01221   {
01222       TY_IDX ty = ST_type(st);
01223 
01224       if (TY_kind(ty) == KIND_POINTER)
01225         if (TY_kind(TY_pointed(ty)) == KIND_FUNCTION)
01226           dummy = TRUE ;
01227   }
01228   return dummy ;
01229 }
01230 
01231 
01232 static void
01233 ST2F_Declare_Return_Type(TOKEN_BUFFER tokens,TY_IDX return_ty, const char *name)
01234 {
01235   /* The TY represents a dummy procedure or a function return type */
01236 
01237   if (return_ty != (TY_IDX) 0) 
01238   {
01239     if (TY_kind(return_ty) != KIND_VOID)
01240     {
01241         TOKEN_BUFFER decl_tokens = New_Token_Buffer();
01242         
01243         Append_F77_Indented_Newline(tokens, 1, NULL/*label*/);
01244         Append_Token_String(decl_tokens, name);
01245 
01246         /* Use integral type for pointer returns */
01247 
01248         if (TY_Is_Pointer(return_ty))
01249           TY2F_translate(decl_tokens, Stab_Mtype_To_Ty(TY_mtype(return_ty)));
01250         else  {
01251               TY2F_translate(decl_tokens, return_ty);
01252          }
01253         TY2F_Prepend_Structures(decl_tokens);
01254         Append_And_Reclaim_Token_List(tokens, &decl_tokens);
01255     }
01256   }
01257 }
01258 
01259 void
01260 ST2F_output_keyword(TOKEN_BUFFER tokens, ST * st)
01261 {
01262   TCON          strcon = STC_val(st);
01263   INT32         strlen ;
01264   INT32         stridx ;
01265   const char    *strbase;
01266   char          *keyword;
01267 
01268   strlen  = Targ_String_Length(strcon);
01269   strbase = Targ_String_Address(strcon);
01270   keyword = (char *) alloca(strlen +1);
01271   for (stridx = 0; stridx<strlen;stridx++)
01272        keyword[stridx] = strbase[stridx];
01273   keyword[stridx] = '\0';
01274   Append_Token_String(tokens,keyword);
01275 #if 0 
01276      TCON2F_trans_to_keyword(tokens, STC_val(st));
01277 #endif
01278      
01279 }
01280