Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
ty2c.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  *    See ty2c.h for a description of the exported functions and 
00046  *    variables.
00047  *
00048  * ====================================================================
00049  * ====================================================================
00050  */
00051 #ifdef _KEEP_RCS_ID
00052 #endif /* _KEEP_RCS_ID */
00053 
00054 #include "whirl2c_common.h"
00055 #include "PUinfo.h"
00056 #include "ty2c.h"
00057 #include "tcon2c.h"
00058 #include "unparse_target.h"
00059 
00060 #if defined(__GNUC__) && (__GNUC__ == 3) 
00061 # define USING_HASH_SET 1
00062 # include <ext/hash_set>
00063   using namespace __gnu_cxx;
00064 #elif defined(__sgi) && !defined(__GNUC__)
00065 # define USING_HASH_SET 1
00066 # include <hash_set>
00067 #else
00068 # include <set>
00069 #endif
00070 
00071 /*------------------ macros, types, and local state -------------------*/
00072 /*---------------------------------------------------------------------*/
00073 
00074 
00075 /* Scalar_C_Names[] is a mapping from a scalar mtype to the builtin
00076  * C type we have chosen to represent it.  This mapping relies on
00077  * a certain ordinal numbering between the MTYPE definitions in 
00078  * common/tdt/mtypes.h, and any changes in that ordering must be
00079  * reflected in a corresponding change here.
00080  */
00081 typedef struct SCALAR_C_NAME
00082 {
00083    const char *real_name;
00084    const char *pseudo_name;
00085 } SCALAR_C_NAME;
00086 
00087 
00088 /* This name is used to wrap a union around a block containing
00089  * equivalence fields.  Should only occur when translating
00090  * Fortran to C.
00091  */
00092 const char TY2C_Aligned_Block_Name[] = "__block";
00093 
00094 #define MTYPE_PREDEF MTYPE_F16
00095 
00096 static char Name_Unknown_Type[] = "__UNKNOWN_TYPE";
00097 static const SCALAR_C_NAME Scalar_C_Names[MTYPE_PREDEF+1] =
00098    {{"void",               Name_Unknown_Type},  /* MTYPE_UNKNOWN 0 */
00099     {"char",               "_BOOLEAN"},         /* MTYPE_B = 1 */
00100     {"signed char",        "_INT8"},            /* MTYPE_I1 = 2 */
00101     {"signed short",       "_INT16"},           /* MTYPE_I2 = 3 */
00102     {"signed int",         "_INT32"},           /* MTYPE_I4 = 4 */
00103     {"signed long long",   "_INT64"},           /* MTYPE_I8 = 5 */
00104     {"unsigned char",      "_UINT8"},           /* MTYPE_U1 = 6 */
00105     {"unsigned short",     "_UINT16"},          /* MTYPE_U2 = 7 */
00106     {"unsigned int",       "_UINT32"},          /* MTYPE_U4 = 8 */
00107     {"unsigned long long", "_UINT64"},          /* MTYPE_U8 = 9 */
00108     {"float",              "_IEEE32"},          /* MTYPE_F4 = 10 */
00109     {"double",             "_IEEE64"},          /* MTYPE_F8 = 11 */
00110     {Name_Unknown_Type,    "_IEEE80"},          /* MTYPE_F10 = 12 */
00111     {Name_Unknown_Type,    "_IEEE128"}  /* MTYPE_F16 = 13 = MTYPE_PREDEF */
00112    }; /* Scalar_C_Names */
00113 
00114 
00115 /* The following is a mapping from some special types to their
00116  * names.  This allows us to predefine them and give them a
00117  * name of our choice (by means of a typedef).  These variables 
00118  * are initialized by TY2C_initialize().  GET_SPECIAL_TYPENAME
00119  * returns the type name if the given mtype is one that we
00120  * treat specially; otherwise, it returns NULL.
00121  */
00122 const char Special_Void_TypeName[] = "void";
00123 const char Special_String_TypeName[] = "_STRING";
00124 const char Special_Quad_TypeName[] = "_QUAD";
00125 const char Special_Complex32_TypeName[] = "_COMPLEX32";
00126 const char Special_Complex64_TypeName[] = "_COMPLEX64";
00127 const char Special_ComplexQD_TypeName[] = "_COMPLEXQD";
00128 
00129 #define GET_SPECIAL_TYPENAME(mtype)\
00130    ((mtype) == MTYPE_V? Special_Void_TypeName : \
00131     ((mtype) == MTYPE_STR? Special_String_TypeName : \
00132      ((mtype) == MTYPE_FQ? Special_Quad_TypeName : \
00133       ((mtype) == MTYPE_C4? Special_Complex32_TypeName : \
00134        ((mtype) == MTYPE_C8? Special_Complex64_TypeName : \
00135         ((mtype) == MTYPE_CQ? Special_ComplexQD_TypeName : \
00136          (const char *)NULL))))))
00137 
00138 #define PTR_OR_ALIGNED_WITH_STRUCT(fld_ty, struct_align) \
00139    (TY_Is_Pointer(fld_ty) || TY_align(fld_ty) <= struct_align)
00140 
00141 /* Some forward declarations */
00142 static void TY2C_scalar(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00143 static void TY2C_array(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00144 static void TY2C_struct(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00145 static void TY2C_function(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00146 static void TY2C_pointer(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00147 static void TY2C_void(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00148 static void TY2C_invalid(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00149 
00150 
00151 /* TY2C_Handle[] maps a TY_kind to a function that translates
00152  * a type of the given type into C code.  Should the ordinal
00153  * numbering of the KIND change in "../common/com/stab.h", then
00154  * a corresponding change must be made here.
00155  */
00156 typedef void (*TY2C_HANDLER_FUNC)(TOKEN_BUFFER, TY_IDX, CONTEXT);
00157 
00158 static const TY2C_HANDLER_FUNC 
00159    TY2C_Handle[KIND_LAST/*TY_KIND*/] =
00160 {
00161    &TY2C_invalid,   /* KIND_INVALID */
00162    &TY2C_scalar,    /* KIND_SCALAR */
00163    &TY2C_array,     /* KIND_ARRAY */
00164    &TY2C_struct,    /* KIND_STRUCT */
00165    &TY2C_pointer,   /* KIND_POINTER */
00166    &TY2C_function,  /* KIND_FUNCTION */
00167    &TY2C_void,      /* KIND_VOID */
00168 };
00169 
00170 
00171 /*------------------------- exported objects --------------------------*/
00172 /*---------------------------------------------------------------------*/
00173 
00174 
00175 /* These must match the names given in "stab.c" for the complex types. 
00176  */
00177 const char *TY2C_Complex_Realpart_Name = "realpart";
00178 const char *TY2C_Complex_Imagpart_Name = "imagpart";
00179 extern int compiling_upc_flag ;
00180 
00181 /*--------------------- hidden utility routines -----------------------*/
00182 /*---------------------------------------------------------------------*/
00183 
00184 static void 
00185 Write_Scalar_Typedef(FILE       *ofile, 
00186                      const char *real_type, 
00187                      const char *new_name)
00188 {
00189    TOKEN_BUFFER tdef = New_Token_Buffer();
00190 
00191    Append_Token_String(tdef, "typedef");
00192    Append_Token_String(tdef, real_type);
00193    Append_Token_String(tdef, new_name);
00194    Append_Token_Special(tdef, ';');
00195    Append_Indented_Newline(tdef, 1);
00196    Write_And_Reclaim_Tokens(ofile, NULL, &tdef);
00197 } /* Write_Scalar_Typedef */
00198 
00199 
00200 static void 
00201 Write_Typedef(FILE       *ofile, 
00202               TY_IDX      ty, 
00203               const char *type_name)
00204 {
00205    TOKEN_BUFFER tdef = New_Token_Buffer();
00206    CONTEXT      context;
00207    
00208    CONTEXT_reset(context);
00209    
00210    Append_Token_String(tdef, type_name);
00211    TY2C_Handle[(TY_KIND)TY_kind(ty)](tdef, ty, context);
00212    Prepend_Token_String(tdef, "typedef");
00213    Append_Token_Special(tdef, ';');
00214    Append_Indented_Newline(tdef, 1);
00215 
00216    /* Put an empty line before this declaration and write it out */
00217    Prepend_Indented_Newline(tdef, 1);
00218    Write_And_Reclaim_Tokens(ofile, NULL, &tdef);
00219 } /* Write_Typedef */
00220 
00221 
00222 static void 
00223 TY2C_prepend_qualifiers(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00224 {
00225    if (!CONTEXT_unqualified_ty2c(context))
00226    {
00227       if (TY_is_const(ty))
00228          Prepend_Token_String(decl_tokens, "const");
00229       if (TY_is_volatile(ty))
00230          Prepend_Token_String(decl_tokens, "volatile");
00231       if (TY_is_restrict(ty))
00232          Prepend_Token_String(decl_tokens, "restrict");
00233    }
00234 } /* TY2C_prepend_qualifiers */
00235 
00236 
00237 static INT64
00238 get_field_gap(FLD_HANDLE this_fld, FLD_HANDLE next_fld, INT64 max_size,
00239               BOOL is_union) 
00240 {
00241    /* Return the minimum of the actual size of this_field and
00242     * the difference in offsets between this and the next field, 
00243     * unless there is no next_fld or we are dealing with a union 
00244     * of fields, in which case we assume the field-size must be 
00245     * less than or equal to the given max_size.
00246     */
00247    INT64 field_gap = TY_size(FLD_type(this_fld));
00248    
00249    if (!is_union        && 
00250        !next_fld.Is_Null() &&
00251        field_gap != FLD_ofst(next_fld)-FLD_ofst(this_fld))
00252    {
00253       field_gap = FLD_ofst(next_fld) - FLD_ofst(this_fld);
00254    }
00255    if (field_gap > max_size || (!is_union && next_fld.Is_Null ()))
00256    {
00257       field_gap = max_size;
00258    }
00259    return field_gap;
00260 } /* get_field_gap */
00261 
00262 
00263 static FLD_HANDLE
00264 skip_till_next_field(FLD_HANDLE  this_fld, 
00265                      const INT64 struct_align,
00266                      const INT64 struct_size,
00267                      BOOL        is_union)
00268 {
00269    /* Walk through the field-list until we find a field with
00270     * a larger offset than the first field, which is aligned
00271     * commensurate with its type but not with stricter (higher)
00272     * alignment requirements than the struct-type as a whole.  
00273     * I.e. until we find a field which can safely be accessed 
00274     * using C "->" or "." notation.
00275     */
00276    FLD_HANDLE next_fld = FLD_next(this_fld);
00277    
00278    if (!is_union)
00279    {
00280       /* Skip until we get to a next_fld which is neither packed
00281        * tighter than the struct itself nor is misaligned (we only 
00282        * allow this for pointers to handle INITVKIND_SYMOFF 
00283        * initializers).
00284        */
00285       while (!next_fld.Is_Null () &&
00286              (FLD_ofst(this_fld) >= FLD_ofst(next_fld) ||
00287               !PTR_OR_ALIGNED_WITH_STRUCT(FLD_type(next_fld), struct_align) ||
00288               (!TY_Is_Pointer(FLD_type(next_fld)) &&
00289                FLD_ofst(next_fld) % TY_align(FLD_type(next_fld)) != 0) ||
00290               (!is_union &&
00291                FLD_Is_Bitfield(next_fld, 
00292                                FLD_next(next_fld),
00293                                struct_size - FLD_ofst(next_fld)))))
00294       {
00295          next_fld = FLD_next(next_fld);
00296       }
00297    }
00298    return next_fld;
00299 } /* skip_till_next_field */
00300 
00301 
00302 static void
00303 TY2C_prepend_filler_field(TOKEN_BUFFER decl_tokens, INT64 byte_size)
00304 {
00305    /* Declare a filler field, uniquely named "fill".
00306     */
00307    TOKEN_BUFFER field_tokens;
00308    
00309    field_tokens = New_Token_Buffer();
00310    Append_Token_String(field_tokens,
00311                        Scalar_C_Names[MTYPE_U1].pseudo_name);
00312    Append_Token_String(field_tokens, W2CF_Symtab_Unique_Name("fill"));
00313    Append_Token_Special(field_tokens, '[');
00314    TCON2C_translate(field_tokens, Host_To_Targ(MTYPE_I8, byte_size));
00315    Append_Token_Special(field_tokens, ']');
00316    Append_Token_Special(field_tokens, ';');
00317    Prepend_Indented_Newline(field_tokens, 1);
00318    Prepend_And_Reclaim_Token_List(decl_tokens, &field_tokens);
00319 } /* TY2C_prepend_filler_field */
00320 
00321 
00322 static void
00323 TY2C_prepend_FLD_list(TOKEN_BUFFER decl_tokens,
00324                       FLD_HANDLE   fld,
00325                       const BOOL   is_union,
00326                       const INT64  struct_align,
00327                       const INT64  struct_size,
00328                       CONTEXT      context)
00329 {
00330    /* Add the fields in the field-list (fld) in the correct order,
00331     * where we handle bitfields and packed structures by declaring
00332     * container or "filler" fields.  Such fillers must never be 
00333     * referenced, so we must recognize them uniformly both at places
00334     * of reference and here at the point of declaration.  Insert an
00335     * indented newline before each field.  Note that for bitfields we 
00336     * cannot assume anything about the structure alignment, since 
00337     * this is dependent on the container types, so we pass the 
00338     * structure alignment in here explicitly.  Assert(fld != NULL)!!
00339     */
00340    TOKEN_BUFFER fld_tokens;
00341    INT64        fld_gap;
00342    const INT64  remaining_bytes = struct_size - FLD_ofst(fld);
00343    
00344    FLD_HANDLE next_fld = skip_till_next_field(fld,
00345                                               struct_align,
00346                                               struct_size,
00347                                               is_union);
00348    fld_gap = get_field_gap(fld, next_fld, remaining_bytes, is_union);
00349       
00350    /* Do the next field before this one, since fields are prepended 
00351     * (rather than appended) to the token buffer.  Note that filler-
00352     * fields to precede the next_fld should be prepended after having
00353     * prepended the next_fld.
00354     */
00355    if (!next_fld.Is_Null ())
00356    {
00357       if (is_union)
00358          TY2C_prepend_FLD_list(decl_tokens, 
00359                                next_fld,
00360                                TRUE,  /* is_union */
00361                                struct_align,
00362                                struct_size,
00363                                context);
00364       else
00365          TY2C_prepend_FLD_list(decl_tokens,
00366                                next_fld,
00367                                FALSE, /* is_union */
00368                                struct_align,
00369                                struct_size, 
00370                                context);
00371    }
00372  
00373    /* Add the tokens for the field declaration in a right-to-left
00374     * manner.  Note that we cannot redeclare bitfields accurately,
00375     * since the TY information is too incomplete to allow this.
00376     */
00377    if (!PTR_OR_ALIGNED_WITH_STRUCT(FLD_type(fld), struct_align) ||
00378        (!is_union &&
00379         FLD_Is_Bitfield(fld, FLD_next(fld), remaining_bytes)))
00380    {
00381       /* Fill up this space with a filler-field */
00382       if (fld_gap > 0)
00383          TY2C_prepend_filler_field(decl_tokens, fld_gap);
00384    }
00385    else /* A regular field, at least we think so */
00386    {
00387       /* Insert filler to succede this fld, since such fillers are
00388        * not handled in the processing of the next field.
00389        */
00390       if (!is_union && fld_gap > TY_size(FLD_type(fld)))
00391       {
00392          TY2C_prepend_filler_field(decl_tokens, 
00393                                    fld_gap - TY_size(FLD_type(fld)));
00394       }
00395       
00396       /* Emit this_fld declaration */
00397       fld_tokens = New_Token_Buffer();
00398       Append_Token_String(fld_tokens, W2CF_Symtab_Nameof_Fld(fld));
00399       TY2C_translate(fld_tokens, FLD_type(fld), context);
00400       Append_Token_Special(fld_tokens, ';');
00401       Prepend_And_Reclaim_Token_List(decl_tokens, &fld_tokens);
00402       Prepend_Indented_Newline(decl_tokens, 1);
00403    } /*if*/
00404 } /* TY2C_prepend_FLD_list */
00405 
00406 
00407 static void
00408 TY2C_Prepend_Alignment_Type(TOKEN_BUFFER tokens, INT64 align)
00409 {
00410    CONTEXT c;
00411 
00412    CONTEXT_reset(c);
00413    switch (align)
00414    {
00415    case 1:
00416       TY2C_translate(tokens, Stab_Mtype_To_Ty(MTYPE_U1), c);
00417       break;
00418    case 2:
00419       TY2C_translate(tokens, Stab_Mtype_To_Ty(MTYPE_U2), c);
00420       break;
00421    case 4:
00422       TY2C_translate(tokens, Stab_Mtype_To_Ty(MTYPE_U4), c);
00423       break;
00424    case 8:
00425       TY2C_translate(tokens, Stab_Mtype_To_Ty(MTYPE_U8), c);
00426       break;
00427    case 16:
00428       TY2C_translate(tokens, Stab_Mtype_To_Ty(MTYPE_FQ), c);
00429       break;
00430    default:
00431       Is_True(FALSE, 
00432               ("Unexpected alignment (%lld) in TY2C_Prepend_Alignment_Type()",
00433                align));
00434    }
00435 } /* TY2C_Prepend_Alignment_Type */
00436 
00437 
00438 static void
00439 TY2C_prototype_params(TOKEN_BUFFER decl_tokens, 
00440                       TYLIST_IDX   params, 
00441                       CONTEXT      context)
00442 {
00443    TOKEN_BUFFER param_tokens;
00444 
00445    if (Tylist_Table[params] == 0)
00446    {
00447       Append_Token_String(decl_tokens, "void");
00448    }
00449    else
00450    {
00451       while (Tylist_Table[params] != 0)
00452       {
00453          param_tokens = New_Token_Buffer();
00454          TY2C_translate(param_tokens, TYLIST_item(Tylist_Table[params]),
00455                         context);
00456          Append_And_Reclaim_Token_List(decl_tokens, &param_tokens);
00457          params = TYLIST_next(params);
00458          if (Tylist_Table[params] != 0)
00459             Append_Token_Special(decl_tokens, ',');
00460       }
00461    }
00462 } /* TY2C_prototype_params */
00463 
00464 
00465 /*---------- hidden routines to handle each kind of type --------------*/
00466 /*---------------------------------------------------------------------*/
00467 
00468 static void 
00469 TY2C_scalar(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00470 {
00471    Is_True(TY_Is_String(ty) ||
00472            TY_mtype(ty) <= MTYPE_PREDEF, ("Illegal type in TY2C_scalar()"));
00473    Is_True(TY_mtype(ty) != MTYPE_UNKNOWN, ("Unknown type in TY2C_scalar()"));
00474 
00475    if (TY_Is_String(ty))
00476    {
00477       Prepend_Token_String(decl_tokens,
00478                            Scalar_C_Names[MTYPE_U1].pseudo_name);
00479       Append_Token_Special(decl_tokens, '[');
00480       Append_Token_Special(decl_tokens, ']');
00481    }
00482    else
00483    {
00484      //WEI:
00485      //For shared_ptr_idx, we want to print the name directly
00486      if (ty == shared_ptr_idx || strcmp(TY_name(ty),"shared_ptr_struct") == 0) {
00487        Prepend_Token_String(decl_tokens, "upcr_shared_ptr_t");
00488      } else if (ty == pshared_ptr_idx || strcmp(TY_name(ty),"pshared_ptr_struct") == 0) {
00489        Prepend_Token_String(decl_tokens, "upcr_pshared_ptr_t");
00490      } else if (Type_Is_Shared_Ptr(ty)) {
00491        //WEI: sometimes we may see a shared variable whose type is not changed
00492        //to {p}shared_ptr_idx (usually happens with a function parameter).  We fix them here
00493        Prepend_Token_String(decl_tokens, (TY_To_Sptr_Idx(ty) == pshared_ptr_idx) ? "upcr_pshared_ptr_t" : "upcr_shared_ptr_t");
00494      } else {
00495        Prepend_Token_String(decl_tokens, 
00496                            Scalar_C_Names[TY_mtype(ty)].pseudo_name);
00497      }
00498    }
00499    TY2C_prepend_qualifiers(decl_tokens, ty, context);
00500 } /* TY2C_scalar */
00501 
00502 
00503 static void 
00504 TY2C_array(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00505 {
00506    if (Stab_Array_Has_Dynamic_Bounds(ty))
00507    {
00508       /* The array has dynamic bounds, unknown at compile-time,
00509        * so declare it as a pointer type in a context that cannot
00510        * accept incomplete types, and declare it as an incomplete
00511        * array otherwise. 
00512        *
00513        * Is_True(TY_size(ty) == 0,
00514        *      ("Expected size of dynamic array to be zero (size=%llu)",
00515        *       (UINT64)TY_size(ty)));
00516        */
00517       if (CONTEXT_incomplete_ty2c(context))
00518       {
00519          /* We can have incomplete C types here, so just declare it as 
00520           * an incomplete array of one dimension.  Dynamic arrays are
00521           * indexed as though they have one dimension, so this should
00522           * work just fine.
00523           */
00524          Append_Token_Special(decl_tokens, '[');
00525          Append_Token_Special(decl_tokens, ']');
00526 
00527          /* In C, the element type of an incomplete array must be 
00528           * a complete type
00529           */
00530          CONTEXT_reset_incomplete_ty2c(context);
00531       }
00532       else
00533       {
00534          /* Declare it as a pointer type, since it must be a dynamic or 
00535           * allocatable Fortran array.
00536           */
00537          Prepend_Token_Special(decl_tokens, '*');
00538          if (TY_Is_Array_Or_Function(TY_AR_etype(ty)))
00539             WHIRL2C_parenthesize(decl_tokens);
00540 
00541          /* Allow incomplete element type */
00542          CONTEXT_set_incomplete_ty2c(context);
00543       }
00544    }
00545    else
00546    {
00547       INT32 dim;
00548       INT64 num_elts;
00549    
00550       /* Emit the array dimensions.  TODO:  If the stride is different
00551        * from the element type size, need to adjust the num_elts.
00552        */
00553       for (dim = 0; dim < TY_AR_ndims(ty); dim++)
00554       {
00555          Append_Token_Special(decl_tokens, '[');
00556 
00557          /* If we need to take the stride (in bytes) into account, then we
00558           * must divide the following by:
00559           *
00560           *    (TY_AR_stride_val(ty, dim)/TY_size(TY_AR_etype(ty)))
00561           */
00562          num_elts = (TY_AR_ubnd_val(ty, dim) - TY_AR_lbnd_val(ty, dim) + 1);
00563 
00564          if (num_elts > 0)
00565             TCON2C_translate(decl_tokens, 
00566                              Host_To_Targ(MTYPE_I8, num_elts));
00567 
00568          Append_Token_Special(decl_tokens, ']');
00569       }
00570          
00571       /* In C, the element type of an incomplete array must be 
00572        * a complete type
00573        */
00574       CONTEXT_reset_incomplete_ty2c(context);
00575    }
00576 
00577    //WEI: if elt type is a struct, make sure it's output as incomplete
00578    if (TY_kind(TY_AR_etype(ty)) == KIND_STRUCT) {
00579      CONTEXT_set_incomplete_ty2c(context);
00580    }
00581    
00582    /* Add the element type tokens and combine the array and element
00583     * qualifiers.
00584     */
00585    TY2C_translate(decl_tokens, TY_AR_etype(ty), context);
00586    TY2C_prepend_qualifiers(decl_tokens, ty, context);
00587 } /* TY2C_array */
00588 
00589 //static std::hash_set<const char*, hash<const char*>, eqstr> struct_decl;
00590 
00591 static void TY2C_complete_struct(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context) {
00592 
00593    /* 
00594     *  We need to get the alignment right for structs containing
00595     * equivalence fields; i.e. overlapping fields, only one of which
00596     * will be declared by whirl2f.  One way to accomplish this is
00597     * to wrap the whole struct within a union and give the union the
00598     * name of the struct, the struct field an anonymous type and
00599     * a name "__block", and enforce the alignment with the a
00600     * second union field with the name "__align".  As an example,
00601     * consider the struct S (having an equivalence field):
00602     *
00603     *   struct S1 {....}
00604     *
00605     * We translate this into:
00606     *
00607     *   union S1 {
00608     *     struct {
00609     *       ....
00610     *     } __block;
00611     *     UINT64 __align;
00612     *   }
00613     *
00614     * Access expressions to this struct must accordingly denote
00615     * the "__block" portion of the union.
00616     */
00617 
00618     CONTEXT fld_context;
00619     BOOL    is_equivalenced = Stab_Is_Equivalenced_Struct(ty);
00620 
00621     if (!TY_flist(Ty_Table[ty]).Is_Null ()) {
00622       fld_context = context;
00623       CONTEXT_reset_unqualified_ty2c(fld_context);
00624       CONTEXT_reset_incomplete_ty2c(fld_context);
00625       
00626       if (is_equivalenced)
00627         {
00628           /* Prepend the end-of-union character, on a new line following
00629            * the list of its two fields, and force the alignment
00630            * with a new field.
00631            */
00632           Prepend_Token_Special(decl_tokens, '}');
00633           Prepend_Indented_Newline(decl_tokens, 1);
00634           Increment_Indentation();
00635           Prepend_Token_Special(decl_tokens, ';');
00636           Prepend_Token_String(decl_tokens, "__align");
00637           TY2C_Prepend_Alignment_Type(decl_tokens, TY_align(ty));
00638           Prepend_Indented_Newline(decl_tokens, 1);
00639           Prepend_Token_Special(decl_tokens, ';');
00640           Prepend_Token_String(decl_tokens, TY2C_Aligned_Block_Name);
00641         }
00642       
00643       /* Prepend the end-of-struct character, on a new line following
00644        * the list of fields.
00645        */
00646       Prepend_Token_Special(decl_tokens, '}');
00647       Prepend_Indented_Newline(decl_tokens, 1);
00648       
00649       /* prepend fields, where each field is preceeded by a newline 
00650        * and is indented.
00651        */
00652       Increment_Indentation();
00653       TY2C_prepend_FLD_list(decl_tokens, 
00654                             TY_flist(Ty_Table[ty]),
00655                             TY_is_union(ty),
00656                             TY_align(ty),
00657                             TY_size(ty),
00658                             fld_context);
00659       Decrement_Indentation();
00660 
00661       /* Prepend the start-of-struct character*/
00662       Prepend_Token_Special(decl_tokens, '{');
00663 
00664       if (is_equivalenced)
00665       {
00666          /* Prepend the start-of-union character, followed by a newline
00667           * to precede the struct and alignment fields.
00668           */
00669          Prepend_Token_String(decl_tokens, TY_is_union(ty)? "UNION": "struct");
00670          Prepend_Indented_Newline(decl_tokens, 1);
00671          Decrement_Indentation();
00672          Prepend_Token_Special(decl_tokens, '{');
00673       }
00674       Prepend_Token_String(decl_tokens, W2CF_Symtab_Nameof_Ty(ty));
00675     } else if (TY_size(ty) == 1) {
00676       /* A special struct with no fields, which may sometimes
00677        * occur for C++ lowered into C.
00678        */
00679       Prepend_Token_Special(decl_tokens, '}');
00680       Prepend_Indented_Newline(decl_tokens, 1);
00681       
00682       Prepend_Token_Special(decl_tokens, ';');
00683       Prepend_Token_String(decl_tokens, W2CF_Symtab_Unique_Name("dummy"));
00684       TY2C_translate(decl_tokens, Stab_Mtype_To_Ty(MTYPE_U1), context);
00685       
00686       Increment_Indentation();
00687       Prepend_Indented_Newline(decl_tokens, 1);
00688       Prepend_Token_Special(decl_tokens, '{');
00689       Prepend_Token_String(decl_tokens, W2CF_Symtab_Nameof_Ty(ty));
00690       Decrement_Indentation();
00691     }
00692 
00693     if (TY_is_union(ty) || is_equivalenced)
00694       Prepend_Token_String(decl_tokens, "union");
00695     else
00696       Prepend_Token_String(decl_tokens, "struct");
00697 }
00698 
00699 /* code to avoid duplication of struct output.  This could happen e.g. if the struct type is used both for 
00700    shaerd and non-shared variables */
00701 struct eqstr {
00702   bool operator()(const char* s1, const char* s2) const
00703   {
00704     return strcmp(s1, s2) == 0;
00705   }
00706 };
00707 
00708 static hash_set<const char*, hash<const char*>, eqstr> struct_names;
00709 
00710 //If the given type is a user-defined struct, 
00711 //This function outputs it complete declaration to the w2c.h file
00712 static void TY2C_Output_Struct_Type(TY_IDX ty,
00713                              INT lines_between_decls,
00714                              CONTEXT context) {
00715 
00716   if (TY_is_translated_to_c(ty) || struct_names.find(TY_name(ty)) != struct_names.end()
00717        || TY_is_written(ty) == 0 ) {
00718     //don't output duplicate struct definitions
00719     return;
00720   }
00721 
00722   if (TY_kind(ty) == KIND_STRUCT && !is_upcr_ptr(ty)) {
00723     struct_names.insert(TY_name(ty));
00724 
00725     //First go through all of its fields and see if there are any struct types we need to output
00726     for (FLD_HANDLE fld = TY_fld(ty); ;fld = FLD_next(fld)) {
00727       TY2C_Output_Struct_Type(FLD_type(fld), lines_between_decls, context);
00728       if (FLD_last_field(fld)) {
00729         break;
00730       }
00731     }
00732 
00733     TOKEN_BUFFER tmp_tokens = New_Token_Buffer(); 
00734     
00735 
00736     CONTEXT_reset_incomplete_ty2c(context); 
00737     Set_TY_is_translated_to_c(ty);  //need to force all later struct type decl to be incomplete
00738     TY2C_complete_struct(tmp_tokens, ty, context);
00739     Append_Token_Special(tmp_tokens, ';'); 
00740     Append_Indented_Newline(tmp_tokens, lines_between_decls);
00741     Write_And_Reclaim_Tokens(W2C_File[W2C_DOTH_FILE], 
00742                              NULL,
00743                              &tmp_tokens);
00744   }
00745 }
00746 
00747 
00748 /*FMZ: the function "TY2C_Translate_Structure" for output the 
00749  *     definition of a structure/union into the ***.w2c.h file
00750  *     -----June 30,2004
00751  */
00752 static void
00753 TY2C_Translate_Structure(TY_IDX ty,CONTEXT context)
00754 {
00755    TOKEN_BUFFER fld_tokens, struct_tokens;
00756    FLD_ITER     fld_iter;
00757    const UINT   current_indent = Current_Indentation();
00758    TY& ty_rt  = Ty_Table[ty];
00759 
00760 /*
00761    ASSERT_DBG_FATAL(TY_kind(ty_rt) == KIND_STRUCT, 
00762                     (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
00763                      TY_kind(ty_rt), "TY2C_Translate_Structure"));
00764 */
00765 
00766    struct_tokens = New_Token_Buffer();
00767 
00768    /* header of the structure */
00769    if (TY_is_union(ty))
00770        Append_Token_String(struct_tokens, "union");
00771    else 
00772        Append_Token_String(struct_tokens, "struct");
00773 
00774    Append_Token_String(struct_tokens, 
00775                        Concat3_Strings(" ", W2CF_Symtab_Nameof_Ty(ty), " {"));
00776 
00777    /* body of the structure */
00778    Increment_Indentation();
00779    FLD_IDX flist = ty_rt.Fld();
00780 
00781    if (flist != 0) {
00782      fld_iter = Make_fld_iter(TY_flist(ty_rt));
00783      do
00784        {
00785              FLD_HANDLE fld (fld_iter);
00786 
00787              Append_Indented_Newline(struct_tokens,1);
00788 
00789              /* Declare this field */
00790              fld_tokens = New_Token_Buffer();
00791              Append_Token_String(fld_tokens,FLD_name(fld_iter)); 
00792 
00793              TY2C_translate(fld_tokens, FLD_type(fld),context);
00794              Append_Token_Special(fld_tokens,';');
00795 
00796              Append_And_Reclaim_Token_List(struct_tokens, &fld_tokens);
00797 
00798         } while (!FLD_last_field (fld_iter++)) ;
00799       }
00800 
00801    /* the tail of the structure */
00802    Decrement_Indentation();
00803    Append_Indented_Newline(struct_tokens,1);
00804    Append_Token_String(struct_tokens, " } ;");
00805    Append_Indented_Newline(struct_tokens,1);
00806 
00807    CONTEXT_reset_incomplete_ty2c(context);
00808 
00809    Append_Indented_Newline(struct_tokens, 1);
00810 
00811    Write_And_Reclaim_Tokens(W2C_File[W2C_DOTH_FILE],
00812                              NULL,
00813                              &struct_tokens);
00814 
00815 
00816 } /* TY2C_Translate_Structure */
00817 
00818 /*
00819  * WEI: This function is modified to output only incomplete struct types.
00820  * Complete struct type will be output by TY2C_complete_struct, through TY2C_Output_Struct_Type
00821  */
00822 /* FMZ:This function is modified again.Complete struct type will be output
00823  * by "TY2C_Translate_Structure" --- June 30,2004
00824   */
00825 static void 
00826 TY2C_struct(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00827 {
00828   
00829  const UINT   current_indent = Current_Indentation();
00830 
00831   if (!TY_is_translated_to_c(ty)) {
00832     //Add this struct type to the global w2c.h
00833     CONTEXT_reset_incomplete_ty2c (context);
00834 //FMZ     TY2C_Output_Struct_Type(ty, 1, context);
00835 
00836      Set_Current_Indentation(0);
00837      //structure definition starts from the 1st column
00838 
00839      Set_TY_is_translated_to_c(ty);
00840      //need to force all later struct type decl to be incomplete
00841 
00842      TY2C_Translate_Structure(ty,context);
00843 
00844      Set_Current_Indentation(current_indent);
00845 
00846     }
00847   
00848   if (Compile_Upc) {
00849     //WEI: special case for shared types
00850     if (strcmp(W2CF_Symtab_Nameof_Ty(ty),"pshared_ptr_struct") == 0) {
00851       Prepend_Token_String(decl_tokens, "upcr_pshared_ptr_t");
00852       TY2C_prepend_qualifiers(decl_tokens, ty, context);
00853       return;
00854     }
00855     if (strcmp(W2CF_Symtab_Nameof_Ty(ty),"shared_ptr_struct") == 0) {
00856       Prepend_Token_String(decl_tokens, "upcr_shared_ptr_t");
00857       TY2C_prepend_qualifiers(decl_tokens, ty, context);
00858       return;
00859     }
00860    }
00861 
00862   if (TY_is_translated_to_c(ty)){  
00863       Prepend_Token_String(decl_tokens, W2CF_Symtab_Nameof_Ty(ty));
00864       BOOL    is_equivalenced = Stab_Is_Equivalenced_Struct(ty);
00865     //  if (TY_is_union(ty) || is_equivalenced) //fzhao
00866       if (TY_is_union(ty) )
00867         Prepend_Token_String(decl_tokens, "union");
00868       else
00869         Prepend_Token_String(decl_tokens, "struct");
00870   
00871       TY2C_prepend_qualifiers(decl_tokens, ty, context);
00872     }
00873 
00874 
00875  } /* TY2C_struct */
00876 
00877 
00878 static void 
00879 TY2C_function(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00880 {
00881    TYLIST_IDX params = TY_parms(ty);
00882 
00883    /* A function cannot be qualified! */
00884    CONTEXT_reset_unqualified_ty2c(context);
00885 
00886    /* WEI: struct types in a function had better be incomplete */
00887    CONTEXT_set_incomplete_ty2c(context);
00888 
00889    /* Append the parameter type list to the right of the decl_tokens */
00890    Append_Token_Special(decl_tokens, '(');
00891    if (TY_has_prototype(ty))
00892    {
00893       TY2C_prototype_params(decl_tokens, params, context);
00894       if (TY_is_varargs(ty))
00895       {
00896          Append_Token_Special(decl_tokens, ',');
00897          Append_Token_String(decl_tokens, "...");
00898       }
00899    }
00900    Append_Token_Special(decl_tokens, ')');
00901 
00902    /* Prepend the return type as the type of the decl_tokens */
00903    TY2C_translate(decl_tokens, W2X_Unparse_Target->Func_Return_Type(ty), context);
00904 } /* TY2C_function */
00905 
00906 
00907 static void 
00908 TY2C_pointer(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00909 {
00910 
00911   TY_IDX sptr_idx = 0;
00912    /* Add qualifiers to the rhs of the '*' and to the left of the
00913     * decl_tokens.
00914     */
00915    TY2C_prepend_qualifiers(decl_tokens, ty, context);
00916 
00917    //WEI: If ty is a local pointer to shared, don't output *
00918    //i.e., we want shared_ptr_t, not shared_ptr_t*
00919    if (!TY_is_shared(TY_pointed(ty))) {
00920      Prepend_Token_Special(decl_tokens, '*');
00921    } else
00922      //Shouldn't see shared ptr types in this stage - BE bug
00923      //However, until we fix it, patch these here.
00924      if(Type_Is_Shared_Ptr(ty)) {
00925        sptr_idx = TY_To_Sptr_Idx(ty);
00926      }
00927 
00928 
00929    if (TY_Is_Array_Or_Function(TY_pointed(ty)))
00930       WHIRL2C_parenthesize(decl_tokens);
00931    
00932    CONTEXT_reset_unqualified_ty2c(context); /* Always qualify pointee type */
00933    CONTEXT_set_incomplete_ty2c(context); /* Pointee can be incomplete */
00934    if(!sptr_idx)
00935      TY2C_translate(decl_tokens, TY_pointed(ty), context);
00936    else 
00937      TY2C_translate(decl_tokens, sptr_idx, context);
00938 } /* TY2C_pointer */
00939 
00940 
00941 static void 
00942 TY2C_void(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00943 {
00944    Prepend_Token_String(decl_tokens, Special_Void_TypeName);
00945    TY2C_prepend_qualifiers(decl_tokens, ty, context);
00946 } /* TY2C_void */
00947 
00948 
00949 static void 
00950 TY2C_invalid(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00951 {
00952    Is_True(FALSE, ("Invalid TY kind (%d) for translation to C", TY_kind(ty)));
00953 } /* TY2C_invalid */
00954 
00955 
00956 /*------------------------ exported routines --------------------------*/
00957 /*---------------------------------------------------------------------*/
00958 
00959 void 
00960 TY2C_initialize(CONTEXT context)
00961 {
00962    /* Since /usr/include/whirl2c.h has declared typedefs for the 
00963     * complex and string types, we need to ensure that they are 
00964     * not declared again:
00965     */
00966    Set_TY_is_translated_to_c(Be_Type_Tbl(MTYPE_STRING));
00967    Set_TY_is_translated_to_c(Be_Type_Tbl(MTYPE_C4));
00968    Set_TY_is_translated_to_c(Be_Type_Tbl(MTYPE_C8));
00969    Set_TY_is_translated_to_c(Be_Type_Tbl(MTYPE_CQ));
00970 } /* TY2C_initialize */
00971 
00972 
00973 void 
00974 TY2C_finalize(void)
00975 {
00976    return; /* nothing to do */
00977 } /* TY2C_finalize */
00978 
00979 
00980 void 
00981 TY2C_translate(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00982 {
00983    /* Note that "decl_tokens" can either be the variable name or a
00984     * string representing an enclosing type.
00985     */
00986    const char *special_name = GET_SPECIAL_TYPENAME(TY_mtype(ty));
00987 
00988    if (special_name != NULL)
00989    {
00990       Prepend_Token_String(decl_tokens, special_name);
00991       TY2C_prepend_qualifiers(decl_tokens, ty, context);
00992    }
00993    else
00994    {
00995       Is_True((TY_KIND)TY_kind(ty) < KIND_LAST && TY_kind(ty) > KIND_INVALID, 
00996               ("Unexpected TY_kind (%d) in TY2C_translate()", TY_kind(ty)));
00997       TY2C_Handle[(TY_KIND)TY_kind(ty)](decl_tokens, ty, context);
00998    }
00999 } /* TY2C_translate */
01000 
01001 
01002 void 
01003 TY2C_translate_unqualified(TOKEN_BUFFER decl_tokens, TY_IDX ty)
01004 {
01005    /* Any qualification on the top-level type should be ignored.
01006     */
01007    CONTEXT context;
01008 
01009    CONTEXT_reset(context);
01010    CONTEXT_set_unqualified_ty2c(context);
01011    //WEI: in this cast the struct type should definitely be incomplete
01012    if (Compile_Upc && TY_kind(ty) == KIND_STRUCT) {
01013      CONTEXT_set_incomplete_ty2c(context);
01014    }
01015 
01016    TY2C_translate(decl_tokens, ty, context);
01017 } /* TY2C_translate_unqualified */
01018 
01019 
01020 TY2C_FLD_INFO
01021 TY2C_get_field_info(TY_IDX struct_ty,      /* base type */
01022                     TY_IDX desired_ty,     /* preferred field type */
01023                     MTYPE  desired_mty,    /* preferred field mtype */
01024                     INT64  desired_offset) /* required field mtype */
01025 {
01026    /* Try to find a field at any level of nesting, which is at
01027     * the given offset from the base of the struct_ty and
01028     * (preferably) of type field_ty or (less preferably) of mtype 
01029     * field_mty.
01030     *
01031     * possibly (?) TODO:  enhance this to be more similar to 
01032     * Construct_Fld_Path in ty2f.h.
01033     */
01034    TY_IDX        this_ty;
01035    FLD_HANDLE       this_fld;
01036    FLD_HANDLE       next_fld;
01037    TY2C_FLD_INFO this_fld_info;
01038    const INT64   struct_size = TY_size(struct_ty);
01039    const INT64   struct_align = TY_align(struct_ty);
01040    BOOL          found_ty = FALSE, found_mty = FALSE;
01041 
01042    /* Search for a field at, or just before, the given offset */
01043    this_fld = TY_flist(Ty_Table[struct_ty]);
01044    if (!this_fld.Is_Null () && !TY_is_union(struct_ty))
01045    {
01046       /* Set "this_field" to the field closest to the given offset, such
01047        * that FLD_ofst(this_field) <= desired_offset and next_fld==NULL
01048        * or FLD_ofst(next_field) > desired_offset.
01049        */
01050       for (next_fld = skip_till_next_field(this_fld, 
01051                                            struct_align,
01052                                            struct_size,
01053                                            FALSE/*is_union*/);
01054            !next_fld.Is_Null() && FLD_ofst(next_fld) <= desired_offset;
01055            next_fld = skip_till_next_field(next_fld, 
01056                                            struct_align,
01057                                            struct_size,
01058                                            FALSE/*is_union*/))
01059       {
01060          this_fld = next_fld;
01061       }
01062    }
01063    else if (!this_fld.Is_Null ())
01064    {
01065       next_fld = skip_till_next_field(this_fld, 
01066                                       struct_align,
01067                                       struct_size,
01068                                       TRUE/*is_union*/);
01069    }
01070    
01071    /* Search for a field of the correct type at the *exact* offset.
01072     * If a struct/union/class field is encountered, of a different
01073     * type than the one we are looking for, then try recursively if
01074     * possible.
01075     */
01076    while (!found_ty && !this_fld.Is_Null () &&
01077           FLD_ofst(this_fld) <= desired_offset)
01078    {
01079       this_ty = FLD_type(this_fld);
01080 
01081       if (!PTR_OR_ALIGNED_WITH_STRUCT(this_ty, struct_align) ||
01082           (!TY_is_union(struct_ty) &&
01083            FLD_Is_Bitfield(this_fld, FLD_next(this_fld), 
01084                            struct_size - FLD_ofst(this_fld))))
01085       {
01086          /* A bitfield: Note that we cannot redeclare bitfields
01087           * accurately, and we therefore cannot access them directly
01088           * either.  Continue down the list of fields to see if
01089           * there is a non-bitfield unioned with this one.
01090           */
01091       }
01092       else if (desired_offset == FLD_ofst(this_fld) && 
01093                Stab_Identical_Types(desired_ty, this_ty, 
01094                                     FALSE, /* check_quals */
01095                                     TRUE,  /* check_scalars */
01096                                     TRUE)) /* ptrs_as_scalars */
01097       {
01098          /* A perfect match, so initiate the field_info */
01099          this_fld_info.found_fld = this_fld;
01100          this_fld_info.select_tokens = New_Token_Buffer();
01101          Append_Token_String(this_fld_info.select_tokens,
01102                              W2CF_Symtab_Nameof_Fld(this_fld));
01103          found_ty = TRUE;
01104       }
01105       else if (TY_Is_Structured(this_ty))
01106       {
01107          /* Try to find a nested field that matches.  Subtract the
01108           * offset of this field from the offset searched for in
01109           * the nested struct.
01110           */
01111          this_fld_info = 
01112             TY2C_get_field_info(this_ty, 
01113                                 desired_ty, 
01114                                 desired_mty, 
01115                                 desired_offset-FLD_ofst(this_fld));
01116          if (!this_fld_info.found_fld.Is_Null ())
01117          {
01118             /* prepend this name to select the path returned */
01119             Prepend_Token_Special(this_fld_info.select_tokens, '.');
01120             Prepend_Token_String(this_fld_info.select_tokens,
01121                                  W2CF_Symtab_Nameof_Fld(this_fld));
01122             found_ty = TRUE;
01123          }
01124       }
01125       else if (desired_offset == FLD_ofst(this_fld) && 
01126                desired_mty == TY_mtype(this_ty))
01127       {
01128          /* An imperfect match, so initiate the found_fld, but keep 
01129           * searching ...
01130           */
01131          this_fld_info.found_fld = this_fld;
01132          found_mty = TRUE;
01133       }
01134       if (!found_ty)
01135       {
01136          this_fld = next_fld;
01137          if (!this_fld.Is_Null ())
01138             next_fld = skip_till_next_field(this_fld,
01139                                             struct_align,
01140                                             struct_size,
01141                                             TY_is_union(struct_ty));
01142       }
01143    } /* while */
01144    
01145    if (!found_ty && found_mty)
01146    {
01147       /* An imperfect match was the best we found, so initiate the
01148        * field_info.
01149        */
01150       this_fld_info.select_tokens = New_Token_Buffer();
01151       Append_Token_String(this_fld_info.select_tokens,
01152                           W2CF_Symtab_Nameof_Fld(this_fld_info.found_fld));
01153    }
01154    if (found_ty || found_mty)
01155    {
01156       /* If we have an equivalence field, we must dereference through
01157        * the artificial union we have created to declare the struct
01158        * of appropriate alignment.  See also "TY2C_struct()".
01159        */
01160       if (Stab_Is_Equivalenced_Struct(struct_ty))
01161       {
01162          Prepend_Token_Special(this_fld_info.select_tokens, '.');
01163          Prepend_Token_String(this_fld_info.select_tokens, 
01164                               TY2C_Aligned_Block_Name);
01165       }
01166    }
01167    else if (!found_ty)
01168    {
01169       this_fld_info.found_fld = FLD_HANDLE(0);
01170    }
01171    return this_fld_info;
01172 } /* TY2C_get_field_info */
01173 
01174 
01175 BOOL
01176 TY2C_builtin(TY_IDX ty)
01177 {
01178    const char *name = GET_SPECIAL_TYPENAME(TY_mtype(ty));
01179 
01180    return (name != NULL ||
01181            (TY_mtype(ty) <= MTYPE_PREDEF && 
01182             (TY_mtype(ty) != MTYPE_UNKNOWN || TY_kind(ty) == KIND_INVALID) &&
01183             Scalar_C_Names[TY_mtype(ty)].pseudo_name != NULL));
01184 } /* TY2C_builtin */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines