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