Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
init2c.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 /* ====================================================================
00037  * ====================================================================
00038  *
00039  *
00040  * Revision history:
00041  *  07-Oct-94 - Original Version
00042  *
00043  * Description:
00044  *
00045  *    Translates initializers (INITOs) to C.  Exports the
00046  *    function:
00047  *
00048  *        INITO2C_translate()
00049  *
00050  * ====================================================================
00051  * ====================================================================
00052  */
00053 #ifdef _KEEP_RCS_ID
00054 #endif /* _KEEP_RCS_ID */
00055 
00056 #include "whirl2c_common.h"
00057 #include "st2c.h"
00058 #include "ty2c.h"
00059 #include "tcon2c.h"
00060 #include "init2c.h"
00061 
00062 
00063             /* Hidden Utility functions */
00064             /*--------------------------*/
00065 
00066 #define INITV_repeat(x) \
00067        ((INITV_kind(Initv_Table[x]) == INITVKIND_ZERO ||  \
00068          INITV_kind(Initv_Table[x]) == INITVKIND_ONE ||  \
00069          INITV_kind(Initv_Table[x]) == INITVKIND_VAL) ?  \
00070                  INITV_repeat2(Initv_Table[x]) : INITV_repeat1(Initv_Table[x]))
00071 
00072 inline TCON
00073 TCON_For_Initv(INITV_IDX initv)
00074 {
00075    TCON tcon;
00076 
00077    switch (INITV_kind(initv))
00078    {
00079       case INITVKIND_ZERO:
00080          tcon = Host_To_Targ(INITV_mtype(Initv_Table[initv]), 0);
00081          break;
00082       case INITVKIND_ONE:
00083          tcon = Host_To_Targ(INITV_mtype(Initv_Table[initv]), 1);
00084          break;
00085       case INITVKIND_VAL:
00086          tcon = INITV_tc_val(Initv_Table[initv]);
00087          break;
00088       default:
00089          Is_True(FALSE, ("Unexpected initv kind in TCON_For_Initv()"));
00090          break;
00091    }
00092    return tcon;
00093 } /* TCON_For_Initv */
00094 
00095 static void 
00096 INIT2C_Next_Initv(INITV_IDX *inv, INT *inv_repeat)
00097 {
00098    /* Get the next initializer.
00099     */
00100    (*inv_repeat)--;
00101    if (*inv_repeat <= 0)
00102    {
00103       *inv = INITV_next(*inv);
00104       *inv_repeat = (*inv != 0) ? INITV_repeat(*inv) : 0;
00105    }
00106 } /* INIT2C_Next_Initv */
00107 
00108 
00109 static void
00110 INITV2C_translate(TOKEN_BUFFER tokens, 
00111                   TY_IDX       ty, 
00112                   INITV_IDX    initv); /* Defined below */
00113 
00114 static void
00115 INITV2C_symoff(TOKEN_BUFFER tokens, 
00116                TY_IDX       ty, 
00117                INITV_IDX    initv)
00118 {
00119    /* Translate a INITVKIND_SYMOFF to C, ignoring repeats, where
00120     * the data location being initialized is typed as "ty".
00121     */
00122    TOKEN_BUFFER  tmp_tokens;
00123    CONTEXT       dummy_context;
00124    BOOL          use_implicit_array_addressing, casted_address;
00125    ST_IDX        initv_st = INITV_st(Initv_Table[initv]);
00126    TY_IDX        sym_ty = (ST_class(initv_st) == CLASS_FUNC) ? 
00127                           ST_pu_type(initv_st) : ST_type(initv_st);
00128    TY2C_FLD_INFO fld_info;
00129    fld_info.select_tokens = NULL;
00130    fld_info.found_fld = FLD_HANDLE();
00131    Is_True(TY_Is_Pointer_Or_Scalar(ty)||TY_Is_Array(ty)
00132             || TY_Is_Struct(ty) , 
00133            ("Unexpected lhs type in INITV2C_symoff()"));
00134    Is_True(ST_sym_class(St_Table[initv_st]) != CLASS_PREG, 
00135            ("Unexpected st class in INITV2C_symoff()"));      
00136    /* See if we can use implicit array addressing (only relevant for 
00137     * zero offset).
00138     */
00139    use_implicit_array_addressing = 
00140       (TY_Is_Pointer(ty)   &&
00141        TY_Is_Array(sym_ty) &&
00142        Stab_Identical_Types(TY_pointed(ty), 
00143                             TY_AR_etype(sym_ty), 
00144                             FALSE,   /*check_quals*/
00145                             TRUE,    /*check_scalars*/
00146                             FALSE)); /*ptrs_as_scalars*/
00147 
00148    /* When using implicit_array_addressing, the symbol we address
00149     * is an element of the array.
00150     */
00151    if (use_implicit_array_addressing)
00152       sym_ty = TY_AR_etype(sym_ty);
00153 
00154    /* Generate a type cast to a non-pointer or incompatible pointer
00155     * type.
00156     */
00157    casted_address = (!use_implicit_array_addressing &&
00158                      (!TY_Is_Pointer(ty) ||
00159                       !Stab_Identical_Types(TY_pointed(ty), 
00160                                             sym_ty, 
00161                                             FALSE,    /*check_quals*/
00162                                             TRUE,     /*check_scalars*/
00163                                             FALSE))); /*ptrs_as_scalars*/
00164 
00165 /* Since this function is used to dumpout the constant string
00166  * we don't need to add the prefix of type to each element.
00167  *--------fzhao
00168  */
00169 # if 0 
00170    if (casted_address)
00171    {
00172       tmp_tokens = New_Token_Buffer();
00173       TY2C_translate_unqualified(tmp_tokens, ty);
00174       WHIRL2C_parenthesize(tmp_tokens);
00175       Append_And_Reclaim_Token_List(tokens, &tmp_tokens);
00176    }
00177 #endif
00178 
00179    /* Get the address expression */
00180    tmp_tokens = New_Token_Buffer();
00181    CONTEXT_reset(dummy_context);
00182    if (INITV_ofst(Initv_Table[initv]) == 0)
00183    {
00184       if (ST_sym_class(St_Table[initv_st]) == CLASS_CONST)
00185       {
00186          TCON2C_translate(tmp_tokens, STC_val(&St_Table[initv_st]));
00187       }
00188       else
00189       {
00190          if (!use_implicit_array_addressing)
00191             Append_Token_Special(tmp_tokens, '&');
00192          ST2C_use_translate(tmp_tokens, &St_Table[initv_st], dummy_context);
00193       }
00194    }
00195    else if (INITV_ofst(Initv_Table[initv]) % TY_size(sym_ty) == 0)
00196    {
00197       /* Use indexing expression to do the address calculation */
00198       ST2C_use_translate(tmp_tokens, &St_Table[initv_st], dummy_context);
00199       Prepend_Token_Special(tmp_tokens, '&');
00200 
00201       Append_Token_Special(tmp_tokens, '[');
00202       Append_Token_String(tmp_tokens, 
00203       Number_as_String(INITV_ofst(Initv_Table[initv])/TY_size(sym_ty), "%lld"));
00204       Append_Token_Special(tmp_tokens, ']');
00205    }
00206    else /* Need to use byte or struct offsets */
00207    {     
00208       /* We fall into this case for struct selection and
00209        * more complex expression, such as "a[17].field3[21]".
00210        */
00211       ST2C_use_translate(tmp_tokens, &St_Table[initv_st], dummy_context);
00212       Prepend_Token_Special(tmp_tokens, '&');
00213 
00214       if (TY_Is_Struct(sym_ty) && TY_Is_Pointer(ty))
00215       {
00216          /* Try to use field selection */
00217          fld_info = TY2C_get_field_info(sym_ty,
00218                                         TY_pointed(ty),
00219                                         MTYPE_V,  /* Only find field of ty */
00220                                         INITV_ofst(Initv_Table[initv]));
00221          if (!fld_info.found_fld.Is_Null ())
00222          {
00223             Append_Token_Special(tmp_tokens, '.');
00224             Append_And_Reclaim_Token_List(tmp_tokens, &fld_info.select_tokens);
00225          }
00226       }
00227       
00228       if (fld_info.found_fld.Is_Null ())
00229       {
00230          /* Cast to a (char*), do offset calculation, and cast to (void*) */
00231          Prepend_Token_Special(tmp_tokens, ')');
00232          Prepend_Token_Special(tmp_tokens, '*');
00233          Prepend_Token_String(tmp_tokens, "char");
00234          Prepend_Token_Special(tmp_tokens, '(');
00235          Append_Token_Special(tmp_tokens, '+');
00236          Append_Token_String(tmp_tokens, 
00237                              Number_as_String(INITV_ofst(Initv_Table[initv]),
00238                                                       "%lld"));
00239          WHIRL2C_parenthesize(tmp_tokens);
00240          if (!casted_address)
00241          {
00242             WHIRL2C_parenthesize(tmp_tokens);
00243             Prepend_Token_Special(tmp_tokens, ')');
00244             Prepend_Token_Special(tmp_tokens, '*');
00245             Prepend_Token_String(tmp_tokens, "void");
00246             Prepend_Token_Special(tmp_tokens, '(');
00247          }
00248       }
00249    }
00250    Append_And_Reclaim_Token_List(tokens, &tmp_tokens);
00251 } /* INITV2C_symoff */
00252 
00253 static void
00254 INITV2C_symoff_help(TOKEN_BUFFER tokens,
00255                TY_IDX       ty,
00256                INITV_IDX    initv)
00257 {
00258   TCON tcon;
00259   INITV_IDX  next_initv;
00260 
00261      if (TY_Is_Structured(ty)) {
00262         Append_Token_Special(tokens,'{');
00263         INITV2C_symoff(tokens, ty, initv);
00264         next_initv = INITV_next(initv);
00265         while(next_initv !=0){
00266           if(INITV_kind (next_initv)== INITVKIND_VAL){
00267                  Append_Token_Special(tokens,',');
00268                  tcon = TCON_For_Initv(next_initv);
00269                  TCON2C_translate(tokens, tcon);
00270            } 
00271           else 
00272           if(INITV_kind (next_initv)== INITVKIND_SYMOFF){
00273                  Append_Token_Special(tokens,',');
00274                  INITV2C_symoff(tokens, ty, next_initv);
00275                   
00276           }
00277 
00278            next_initv = INITV_next(next_initv);
00279          }
00280          Append_Token_Special(tokens,'}');
00281       }
00282     else if (TY_Is_Array(ty)) {
00283         Append_Token_Special(tokens,'{');
00284         INITV2C_symoff(tokens, ty, initv);
00285         next_initv = INITV_next(initv);
00286         while(next_initv !=0){
00287         if(INITV_kind (next_initv)== INITVKIND_VAL){
00288                  Append_Token_Special(tokens,',');
00289                  tcon = TCON_For_Initv(next_initv);
00290                  TCON2C_translate(tokens, tcon);
00291            } else
00292           if(INITV_kind (next_initv)== INITVKIND_SYMOFF){
00293                  Append_Token_Special(tokens,',');
00294                  INITV2C_symoff(tokens, ty, next_initv);
00295            
00296           }
00297 
00298            next_initv = INITV_next(next_initv);
00299          }
00300          Append_Token_Special(tokens,'}');
00301       }
00302     else
00303      
00304          INITV2C_symoff(tokens, ty, initv);
00305 
00306 }
00307 
00308 
00309 
00310 static void
00311 INITV2C_val(TOKEN_BUFFER tokens,
00312             TY_IDX       ty, 
00313             INITV_IDX    initv)
00314 {
00315    /* Translate an INITVKIND_ZERO, INITVKIND_ONE, or INITVKIND_VAL to C,
00316     * ignoring repeats, where the data location being initialized is
00317     * typed as "ty".
00318     */
00319    TOKEN_BUFFER tmp_tokens;
00320    TCON tcon = TCON_For_Initv(initv);
00321    INITV_IDX  next_initv;
00322 
00323 // "struct" and "union" variables appeared in the Tcons if declared as "static" variables
00324 // and "array" variable too---fzhao
00325 
00326    Is_True(TY_Is_Pointer_Or_Scalar(ty) || TY_Is_Array_Of_Chars(ty) || 
00327                 TY_Is_Structured(ty)|| TY_Is_Array(ty),
00328            ("Unexpected lhs type in INITV2C_val()"));
00329       
00330    /* Make sure the types are assignment compatible, by casting pointer
00331     * constants when necessary.  No casting is necessary for NULL
00332     * pointers.
00333     */
00334    if (TY_Is_Pointer(ty) && Targ_To_Host(tcon) != 0LL)
00335    {
00336       tmp_tokens = New_Token_Buffer();
00337       TY2C_translate_unqualified(tmp_tokens, ty);
00338       WHIRL2C_parenthesize(tmp_tokens);
00339       Append_And_Reclaim_Token_List(tokens, &tmp_tokens);
00340    }
00341 
00342 
00343    /* Translate the constant value */
00344 
00345    /* If  the type is struct,then there might be more than 
00346       one constant values in this INITO table entry,dumpout
00347       all the values-----fzhao
00348      */
00349    if (TY_Is_Structured(ty)) {
00350         Append_Token_Special(tokens,'{');
00351         TCON2C_translate(tokens, tcon);
00352         next_initv = INITV_next(initv);
00353         while(next_initv !=0){
00354           if(INITV_kind (next_initv)== INITVKIND_VAL)  {
00355                  Append_Token_Special(tokens,',');
00356                  tcon = TCON_For_Initv(next_initv);
00357                  TCON2C_translate(tokens, tcon);
00358            }
00359            next_initv = INITV_next(next_initv);
00360          }
00361          Append_Token_Special(tokens,'}');
00362       }
00363     else if (TY_Is_Array(ty)) {
00364         Append_Token_Special(tokens,'{');
00365         TCON2C_translate(tokens, tcon);
00366         next_initv = INITV_next(initv);
00367         while(next_initv !=0){
00368           if(INITV_kind (next_initv)== INITVKIND_VAL)  {
00369                  Append_Token_Special(tokens,',');
00370                  tcon = TCON_For_Initv(next_initv);
00371                  TCON2C_translate(tokens, tcon);
00372            }
00373            next_initv = INITV_next(next_initv);
00374          }
00375          Append_Token_Special(tokens,'}');
00376       }
00377     else
00378       TCON2C_translate(tokens, tcon);
00379 
00380 } /* INITV2C_val */
00381 
00382 
00383 static void
00384 INITV2C_array_dimension(TOKEN_BUFFER tokens,
00385                         TY_IDX       etype, 
00386                         INITV_IDX    next_initv,
00387                         INT          this_dim, /* one based dimension */
00388                         INT          num_dims)
00389 {
00390    INITV_IDX inv;
00391    INT    repeat;
00392 
00393    /* The front-end may generate multi-dimensional arrays for arrays
00394     * of arrays.  
00395     *
00396     * Walk through the list of (comma separated) initializers 
00397     * for the aggregate initializer, ignoring padding.
00398     */
00399    Append_Token_Special(tokens, '{');
00400    for (inv = next_initv; inv != 0; inv = INITV_next(inv))
00401    {
00402       /* Handle repetitions */
00403       for (repeat = INITV_repeat(inv); repeat > 0; repeat--)
00404       {
00405          if (INITV_kind(Initv_Table[inv]) != INITVKIND_PAD)
00406          {
00407             /* Avoid preceeding the first initializer with a comma */
00408             if (inv != next_initv || repeat < INITV_repeat(inv))
00409                Append_Token_Special(tokens, ',');
00410             
00411             if (this_dim < num_dims &&
00412                 INITV_kind(Initv_Table[inv]) == INITVKIND_BLOCK)
00413                INITV2C_array_dimension(tokens, 
00414                                        etype, 
00415                                        INITV_blk(inv),
00416                                        this_dim+1,
00417                                        num_dims);
00418             else
00419                INITV2C_translate(tokens, etype, inv);
00420          } /* if */
00421       } /* for */
00422    } /* for */
00423    Append_Token_Special(tokens, '}');
00424 } /* INITV2C_array_dimension */
00425 
00426 
00427 static void
00428 INITV2C_block_array(TOKEN_BUFFER tokens,
00429                     TY_IDX       ty, 
00430                     INITV_IDX    initv)
00431 {
00432    /* Translate a INITVKIND_BLOCK for an array to C, where the 
00433     * location being initialized is typed as "ty" (KIND_ARRAY).
00434     */
00435    INITV_IDX first_inv = INITV_blk(initv);
00436    TY_IDX    etype = TY_AR_etype(ty);
00437    INT    ndims = TY_AR_ndims(ty);
00438    
00439    if (!TY_Is_Array(etype) && !TY_Is_String(etype) &&
00440        INITV_kind(Initv_Table[first_inv]) == INITVKIND_VAL &&
00441        TCON_ty(INITV_tc_val(Initv_Table[first_inv])) == MTYPE_STRING)
00442    {
00443       Is_True((TY_size(ty) ==
00444                Targ_String_Length(INITV_tc_val(Initv_Table[first_inv]))) ||
00445               (INITV_next(first_inv) != 0 &&
00446                INITV_kind(Initv_Table[INITV_next(first_inv)]) == INITVKIND_PAD),
00447               ("Expected padding to follow incomplete string initializer"));
00448       INITV2C_translate(tokens, ty, first_inv);
00449    }
00450    else /* Not incomplete string initializer */
00451    {
00452       if (first_inv != 0 && 
00453           INITV_kind(Initv_Table[first_inv]) == INITVKIND_PAD &&
00454           INITV_next(first_inv) == 0)
00455       {
00456          /* Handle the special case of just having padding as an 
00457           * initializer.
00458           */
00459          Append_Token_Special(tokens, '{');
00460          Append_Token_String(tokens, "0L");
00461          Append_Token_Special(tokens, '}');
00462       }
00463       else
00464       {
00465          INITV2C_array_dimension(tokens, etype, first_inv,  1, ndims);
00466       } /* if */
00467    } /* if */
00468 } /* INITV2C_block_array */
00469 
00470 
00471 static void
00472 INITV2C_struct_fill(TOKEN_BUFFER tokens,
00473                     INITV_IDX   *current_inv, 
00474                     INT         *inv_repeat,
00475                     INT64       *current_offset, 
00476                     INT64        desired_offset)
00477 {
00478    /* Using the inv sequence of initializers, initialize
00479     * a byte-array with bytes up to the desired offset.
00480     * Thus, the number of bytes initialized will be limited
00481     * by the inv list and the "desired_offset-current_offset".
00482     * Padding will be viewed as zero initializers.  Update
00483     * the current_inv, the inv_repeat, and the current_offset.
00484     */
00485    union Tcon_Bytes
00486    {
00487       struct
00488       {
00489          UINT32 u1;
00490          UINT32 u2;
00491          UINT32 u3;
00492          UINT32 u4;
00493          UINT32 u5;
00494          UINT32 u6;
00495          UINT32 u7;
00496          UINT32 u8;
00497       } val;
00498       mUINT8 byte[32];
00499    } tcon_bytes;
00500 
00501    INT      pad_byte;
00502    INT      tcon_size;
00503    TCON     tcon;
00504    
00505    Is_True(*current_inv != 0 && *current_offset < desired_offset,
00506            ("Incorrect call to INITV2C_struct_fill()"));
00507 
00508    Append_Token_Special(tokens, '{');
00509    while (*current_offset < desired_offset && *current_inv != 0)
00510    {
00511       /* Expect only padding and integral val INITVs */
00512       switch (INITV_kind(Initv_Table[*current_inv]))
00513       {
00514       case INITVKIND_UNK:
00515          Is_True(FALSE, ("Unknown initv kind in INITV2C_struct_fill()"));
00516          break;
00517 
00518       case INITVKIND_SYMOFF:
00519          Is_True(FALSE, ("SYMOFF initv kind in INITV2C_struct_fill()"));
00520          break;
00521       
00522       case INITVKIND_ZERO:
00523       case INITVKIND_ONE:
00524       case INITVKIND_VAL:
00525          tcon = TCON_For_Initv(*current_inv);
00526          tcon_size = TY_size(Stab_Mtype_To_Ty(TCON_ty(tcon)));
00527          if (tcon_size < sizeof(tcon.vals.uval.u0))
00528          {
00529             /* Shift the relevant bytes into the appropriate position */
00530             tcon_bytes.val.u1 = 
00531                (tcon.vals.uval.u0 << 
00532                 8*(sizeof(tcon.vals.uval.u0) - tcon_size));
00533          }
00534          else
00535          {
00536             /* Assign all eight 32 bits words of the tcon value to 
00537              * tcon_bytes.
00538              */
00539             tcon_bytes.val.u1 = tcon.vals.uval.u0;
00540             tcon_bytes.val.u2 = tcon.vals.uval.u1;
00541             tcon_bytes.val.u3 = tcon.vals.uval.u2;
00542             tcon_bytes.val.u4 = tcon.vals.uval.u3;
00543             tcon_bytes.val.u5 = tcon.cmplxval.ival.v0;
00544             tcon_bytes.val.u6 = tcon.cmplxval.ival.v1;
00545             tcon_bytes.val.u7 = tcon.cmplxval.ival.v2;
00546             tcon_bytes.val.u8 = tcon.cmplxval.ival.v3;
00547          }
00548          
00549          /* The tcon bytes of relevance are now in tcon_bytes */
00550          for (pad_byte = 0; pad_byte < tcon_size; pad_byte++)
00551          {
00552             if (pad_byte > 0)
00553                Append_Token_Special(tokens, ',');
00554             Append_Token_String(tokens, 
00555                Number_as_String(tcon_bytes.byte[pad_byte], "%llu"));
00556          }
00557          *current_offset += tcon_size;
00558          break;
00559 
00560       case INITVKIND_BLOCK:
00561          Is_True(FALSE, ("BLOCK initv kind in INITV2C_struct_fill()"));
00562          break;
00563 
00564       case INITVKIND_PAD:
00565          /* View padding as zero initialized */
00566          for (pad_byte = INITV_pad(Initv_Table[*current_inv]);
00567               pad_byte > 0;
00568               pad_byte--)
00569          {
00570             Append_Token_String(tokens, "0");
00571             if (pad_byte > 1)
00572                Append_Token_Special(tokens, ',');
00573          }
00574          *current_offset += INITV_pad(Initv_Table[*current_inv]);
00575          break;
00576 
00577       default:
00578          Is_True(FALSE, ("Unexpected initv kind in INITV2C_struct_fill()"));
00579          break;
00580 
00581       } /* switch */
00582       
00583       INIT2C_Next_Initv(current_inv, inv_repeat);
00584       
00585       /* Seperate the last filler byte emitted from the next one
00586        * with a comma.
00587        */
00588       if (*current_offset < desired_offset && *current_inv != 0)
00589          Append_Token_Special(tokens, ',');
00590 
00591    } /*while*/
00592    Append_Token_Special(tokens, '}');
00593 } /* INITV2C_struct_fill */
00594 
00595 
00596 static void
00597 INITV2C_block_struct(TOKEN_BUFFER tokens,
00598                      TY_IDX       ty, 
00599                      INITV_IDX    initv)
00600 {
00601    /* Translate a INITVKIND_BLOCK for a struct to C, where the
00602     * location being initialized is typed as "ty" (KIND_STRUCT).
00603     */
00604    INITV_IDX     inv, first_inv = INITV_blk(initv);
00605    INT           inv_repeat;
00606    INT64         local_offset;
00607    FLD_HANDLE    fld;
00608    TY2C_FLD_INFO fld_info;
00609    BOOL          a_field_is_initialized = FALSE;
00610 
00611    /* Walk through the list of (comma separated) initializers 
00612     * for the aggregate initializer, ignoring padding.
00613     */
00614    Append_Token_Special(tokens, '{');
00615    if (first_inv != 0 && 
00616        INITV_kind(Initv_Table[first_inv]) == INITVKIND_PAD &&
00617        INITV_next(first_inv) == 0)
00618    {
00619       /* Handle the special case of just having padding as an 
00620        * initializer.
00621        */
00622       Append_Token_String(tokens, "0L");
00623    }
00624    else
00625    {
00626       /* Walk through the list of structure fields, initializing
00627        * field separating padding, but leaving padding at the end
00628        * of a struct uninitialized.
00629        */
00630       local_offset = 0;
00631       inv = first_inv;
00632       inv_repeat =  (inv != 0) ? INITV_repeat(inv) : 0;
00633       for (fld = TY_flist(Ty_Table[ty]); 
00634            !fld.Is_Null () && inv != 0; 
00635            fld = FLD_next(fld))
00636       {
00637          if (FLD_ofst(fld) >= local_offset)
00638          {
00639             /* This field does not overlap any previous fields.
00640              */
00641             fld_info = TY2C_get_field_info(ty,
00642                                            FLD_type(fld),
00643                                            MTYPE_V,
00644                                            FLD_ofst(fld));
00645             if (!fld_info.found_fld.Is_Null ())
00646             {
00647                /* This field is declared in the C output.
00648                 */
00649                Reclaim_Token_Buffer(&fld_info.select_tokens);
00650                if (FLD_ofst(fld) > local_offset)
00651                {
00652                   /* Insert padding before this field.
00653                    */
00654                   if (a_field_is_initialized)
00655                      Append_Token_Special(tokens, ',');
00656                   else
00657                      a_field_is_initialized = TRUE;
00658                   INITV2C_struct_fill(tokens,
00659                                       &inv, &inv_repeat,
00660                                       &local_offset, FLD_ofst(fld));
00661                }
00662                if (inv != 0)
00663                {
00664                   /* An initializer exists for this field.
00665                    */
00666                   if (a_field_is_initialized)
00667                      Append_Token_Special(tokens, ',');
00668                   else
00669                      a_field_is_initialized = TRUE;
00670 
00671                   /* Work around a Fortran bug! TODO: Rewrite this to
00672                    * be more similar to whirl2f and to work for all cases.
00673                    */
00674                   if (PU_src_lang(CURRENT_SYMTAB) == PU_F77_LANG &&
00675                       (INITV_kind(Initv_Table[inv]) == INITVKIND_ZERO ||
00676                        INITV_kind(Initv_Table[inv]) == INITVKIND_ONE  ||
00677                        INITV_kind(Initv_Table[inv]) == INITVKIND_VAL))
00678                   {
00679                      INT fld_size = TY_size(Ty_Table[FLD_type(fld)]);
00680                      TY_IDX inv_ty;
00681 
00682                      if (TY_Is_Array(FLD_type(fld)) ||
00683                          TY_Is_Structured(FLD_type(fld)))
00684                      {
00685                         Append_Token_Special(tokens, '{');
00686                      }
00687 
00688                      while (inv != 0                         &&
00689                             fld_size > 0                     &&
00690                             (INITV_kind(Initv_Table[inv]) == INITVKIND_ZERO ||
00691                              INITV_kind(Initv_Table[inv]) == INITVKIND_ONE  ||
00692                              INITV_kind(Initv_Table[inv]) == INITVKIND_VAL))
00693                      { 
00694                         inv_ty = Stab_Mtype_To_Ty(TCON_ty(TCON_For_Initv(inv)));
00695                         INITV2C_translate(tokens, inv_ty, inv);
00696                         fld_size -= TY_size(inv_ty);
00697                         INIT2C_Next_Initv(&inv, &inv_repeat);
00698                         if (fld_size > 0)
00699                            Append_Token_Special(tokens, ',');
00700                      }
00701                      if (TY_Is_Array(FLD_type(fld)) ||
00702                          TY_Is_Structured(FLD_type(fld)))
00703                      {
00704                         Append_Token_Special(tokens, '}');
00705                      }
00706                   }
00707                   else
00708                   {
00709                      INITV2C_translate(tokens, FLD_type(fld), inv);
00710                      INIT2C_Next_Initv(&inv, &inv_repeat);
00711                   }
00712 
00713                   local_offset += TY_size(FLD_type(fld));
00714                } /*if*/
00715             } /*if*/
00716          } /*if*/
00717       } /*for*/
00718       
00719       /* Explicitly apply any outstanding initializer.  We can here
00720        * Assert that (fld!=0 xor inv!=0).
00721        */
00722       if (local_offset < TY_size(ty) && inv != 0)
00723       {
00724          if (a_field_is_initialized)
00725             Append_Token_Special(tokens, ',');
00726          INITV2C_struct_fill(tokens,
00727                              &inv, &inv_repeat,
00728                              &local_offset, TY_size(ty));
00729       } /*if*/
00730    } /*if*/
00731    Append_Token_Special(tokens, '}');
00732 } /* INITV2C_block_struct */
00733 
00734 
00735 static void
00736 INITV2C_block_union(TOKEN_BUFFER tokens,
00737                     TY_IDX       ty, 
00738                     INITV_IDX    initv)
00739 {
00740    /* Translate a INITVKIND_BLOCK for a union to C, where the
00741     * location being initialized is typed as "ty" (KIND_STRUCT).
00742     */
00743    INITV_IDX first_inv = INITV_blk(initv);
00744    INITV_IDX next_inv = INITV_next(first_inv);
00745 
00746    /* Make sure only one element of the union is initialized; allow a
00747     * second initializer for the union only if it is for padding.
00748     */
00749    Is_True((next_inv == 0 ||
00750             (INITV_kind(Initv_Table[next_inv]) == INITVKIND_PAD &&
00751              INITV_next(next_inv) == 0)),
00752            ("Expected an initializer only for the first element of a union"));
00753 
00754    /* Initialize the first element of the union */
00755    Append_Token_Special(tokens, '{');
00756    INITV2C_translate(tokens, FLD_type(TY_flist(Ty_Table[ty])),
00757                      first_inv);
00758    Append_Token_Special(tokens, '}');
00759 } /* INITV2C_block_union */
00760 
00761 
00762 static void
00763 INITV2C_translate(TOKEN_BUFFER tokens, 
00764                   TY_IDX       ty, 
00765                   INITV_IDX    initv)
00766 {
00767    switch (INITV_kind(Initv_Table[initv]))
00768    {
00769    case INITVKIND_UNK:
00770       Is_True(FALSE, ("Unknown initv kind in INITV2C_translate()"));
00771       break;
00772 
00773    case INITVKIND_SYMOFF:
00774       INITV2C_symoff_help(tokens, ty, initv);
00775       break;
00776       
00777    case INITVKIND_ZERO:
00778    case INITVKIND_ONE:
00779    case INITVKIND_VAL:
00780       /* May be a scalar or a string initializer */
00781       INITV2C_val(tokens, ty, initv);
00782       break;
00783 
00784    case INITVKIND_BLOCK:
00785       /* Expect an array, a union or a struct ty.  Assert on
00786        * anything else!  Note that a string may occur as a
00787        * block initializer when it has padding.
00788        */
00789       if (TY_Is_Array(ty))
00790          INITV2C_block_array(tokens, ty, initv);
00791       else if (TY_Is_Union(ty))
00792          INITV2C_block_union(tokens, ty, initv);
00793       else if (TY_Is_Struct(ty))
00794          INITV2C_block_struct(tokens, ty, initv);
00795       else
00796          Is_True(FALSE, ("Unexpected aggregate type in INITV2C_translate()"));
00797       break;
00798 
00799    case INITVKIND_PAD:
00800       /* Simply ignore padding */
00801       break;
00802 
00803    default:
00804       Is_True(FALSE, ("Unexpected initv kind in INITV2C_translate()"));
00805       break;
00806 
00807    } /* switch */
00808 } /* INITV2C_translate */
00809 
00810    
00811 void
00812 INITO2C_translate(TOKEN_BUFFER tokens, INITO_IDX inito)
00813 {
00814    /* There is one INITO denoting the object initializer.  The INITO
00815     * points to the object it references (ST*), and the INITO_ofst
00816     * attribute (offset in data section) has no significance for 
00817     * the translation to C.
00818     */
00819 
00820    if (Stab_Is_Common_Block(INITO_st(inito)) ||
00821             Stab_Is_Equivalence_Block(INITO_st(inito)))
00822    {
00823      if ( !TY_Is_Structured(ST_type(INITO_st(inito))) )
00824            Append_Token_Special(tokens, '{');
00825       INITV2C_translate(tokens, ST_type(INITO_st(inito)), INITO_val(inito));
00826      if ( !TY_Is_Structured(ST_type(INITO_st(inito))) )
00827           Append_Token_Special(tokens, '}');
00828    }
00829    else{
00830       INITV2C_translate(tokens, ST_type(INITO_st(inito)), INITO_val(inito));
00831 
00832     }
00833 } /* INITO2C_translate */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines