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 /* -*-Mode: c++;-*- (Tell emacs to use c++ mode) */ 00037 00038 #ifndef symtab_defs_INCLUDED 00039 #define symtab_defs_INCLUDED 00040 00041 #include <string.h> /* for memset() */ 00042 00043 // Note: 00044 // 00045 // The comments in this file are intentionally brief. For detail description, 00046 // please refer to the "WHIRL Symbol Table Specification", which is the only 00047 // document actively maintained. 00048 00049 00050 enum ST_CLASS 00051 { 00052 CLASS_UNK = 0, 00053 CLASS_VAR = 1, // data variable 00054 CLASS_FUNC = 2, // addrress of a function. 00055 CLASS_CONST = 3, // constant value 00056 CLASS_PREG = 4, // pseudo register 00057 CLASS_BLOCK = 5, // base to a block of data 00058 CLASS_NAME = 6, // just hold an ST name 00059 CLASS_MODULE = 7, 00060 CLASS_TYPE = 8, // holds user defined type name 00061 CLASS_PARAMETER = 9, 00062 CLASS_COUNT = 10 // total number of classes 00063 }; // ST_CLASS 00064 00065 00066 enum ST_SCLASS 00067 { 00068 // the values should not overlap with those in ST_CLASS for error checking 00069 SCLASS_UNKNOWN = 0, 00070 SCLASS_AUTO = 1, // stack variable 00071 SCLASS_FORMAL = 2, // formal parameter 00072 SCLASS_FORMAL_REF = 3, // reference parameter 00073 SCLASS_PSTATIC = 4, // PU scope static data 00074 SCLASS_FSTATIC = 5, // file scope static data 00075 SCLASS_COMMON = 6, // common block (linker allocated) 00076 SCLASS_EXTERN = 7, // unallocated external data or text 00077 SCLASS_UGLOBAL = 8, // uninitialized global data 00078 SCLASS_DGLOBAL = 9, // initialized global data 00079 SCLASS_TEXT = 10, // executable code 00080 SCLASS_REG = 11, // register variable 00081 SCLASS_CPLINIT = 12, // cplinit 00082 SCLASS_EH_REGION = 13, // eh region 00083 SCLASS_EH_REGION_SUPP = 14, // eh region supp 00084 SCLASS_DISTR_ARRAY = 15, // distributed array 00085 SCLASS_COMMENT = 16, // comment section 00086 SCLASS_THREAD_PRIVATE_FUNCS = 17, // thread-private constr/destr funcs 00087 SCLASS_MODULE = 18, // For keep module as a storage class 00088 // instead of generating common block 00089 SCLASS_COMMON1 = 19, 00090 00091 SCLASS_COUNT = 20 // total number of classes 00092 00093 00094 }; // ST_SCLASS 00095 00096 00097 enum ST_EXPORT 00098 { 00099 EXPORT_LOCAL = 0, // Not exported, e.g. C static 00100 EXPORT_LOCAL_INTERNAL = 1, // Statics that do not have address 00101 // passed outside of a.out/DSO. 00102 EXPORT_INTERNAL = 2, // Exported, only visible and used 00103 // within the containing 00104 // DSO/executable, i.e. not even 00105 // passed outside using a pointer. 00106 EXPORT_HIDDEN = 3, // Exported, but name is hidden 00107 // within the containing 00108 // DSO/executable. However, the 00109 // address may be exported from the 00110 // DSO via a pointer. 00111 EXPORT_PROTECTED = 4, // Exported from DSO, but 00112 // non-preemptible. 00113 EXPORT_PREEMPTIBLE = 5, // Exported and preemptible. 00114 EXPORT_OPTIONAL = 6, // STO_OPTIONAL case in "sys/elf.h" 00115 EXPORT_INTRINSIC = 7, // FORTRAN 90 intrinsic function 00116 EXPORT_COUNT = 8 // Must be last for consistency 00117 // checking 00118 }; // ST_EXPORT 00119 00120 00121 enum ST_FLAGS 00122 { 00123 ST_IS_WEAK_SYMBOL = 0x00000001, // Weak external name 00124 ST_IS_SPLIT_COMMON = 0x00000002, // part of a splitted common 00125 ST_IS_NOT_USED = 0x00000004, // Symbol is not referenced 00126 ST_IS_INITIALIZED = 0x00000008, // Symbol is initialized 00127 ST_IS_RETURN_VAR = 0x00000010, // CLASS_VAR: Return value 00128 ST_IS_VALUE_PARM = 0x00000020, // CLASS_VAR: Value parm 00129 ST_PROMOTE_PARM = 0x00000040, // CLASS_VAR: Promote C formal 00130 ST_KEEP_NAME_W2F = 0x00000080, // CLASS_VAR: don't mangle name 00131 ST_IS_DATAPOOL = 0x00000100, // CLASS_VAR: represents datapool 00132 ST_IS_RESHAPED = 0x00000200, // lno may reshape the ST 00133 ST_EMIT_SYMBOL = 0x00000400, // emit the empty dummy symbol 00134 ST_HAS_NESTED_REF = 0x00000800, // has ref in nested pu 00135 ST_INIT_VALUE_ZERO = 0x00001000, // has initial value of zero 00136 ST_GPREL = 0x00002000, // force object to be gp-rel 00137 ST_NOT_GPREL = 0x00004000, // force object to not be gp-rel 00138 ST_IS_NAMELIST = 0x00008000, // namelist table 00139 ST_IS_F90_TARGET = 0x00010000, // F90 target 00140 ST_DECLARED_STATIC = 0x00020000, // VMS formals declared static 00141 ST_IS_EQUIVALENCED = 0x00040000, // is part of an equivalence 00142 ST_IS_FILL_ALIGN = 0x00080000, // has fill/align pragma. 00143 ST_IS_OPTIONAL_ARGUMENT = 0x00100000, // F90 OPTIONAL arguments 00144 ST_PT_TO_UNIQUE_MEM = 0x00200000, // a pointer that is not aliased 00145 ST_IS_TEMP_VAR = 0x00400000, // compiler generated temp. variable 00146 ST_IS_CONST_VAR = 0x00800000, // read-only variable 00147 ST_ADDR_SAVED = 0x01000000, // address saved 00148 ST_ADDR_PASSED = 0x02000000, // address passed 00149 ST_IS_THREAD_PRIVATE = 0x04000000, // Symbol is allocated in XLOCAL 00150 // data segment 00151 ST_PT_TO_COMPILER_GENERATED_MEM = 0x08000000, // a pointer to compiler- 00152 // allocated memory space 00153 ST_IS_SHARED_AUTO = 0x10000000, // SCLASS_AUTO and accessed with 00154 // SHARED scope in an MP region 00155 ST_ASSIGNED_TO_DEDICATED_PREG = 0x20000000, // assigned to dedicated preg 00156 // specified in offset 00157 ST_ASM_FUNCTION_ST = 0x40000000, // ST is CLASS_NAME asm string with 00158 // file scope. 00159 ST_HAS_NAMED_SECTION = 0x80000000 // has named section attribute 00160 // new flags must go into flags_ext field. 00161 }; // ST_FLAGS 00162 00163 enum ST_EXT_FLAGS 00164 { 00165 ST_IS_POINTER = 0x0001, 00166 ST_IS_ALLOCATABLE = 0x0002, 00167 ST_IS_IN_MODULE = 0x0004, 00168 ST_IS_EXTERNAL = 0x0008, 00169 ST_IS_BLOCK_DATA = 0x0010, 00170 ST_IS_INTENT_IN_ARGUMENT = 0x0020, 00171 ST_IS_INTENT_OUT_ARGUMENT = 0x0040, 00172 ST_IS_ASSIGN_INTERFACE = 0x0080, 00173 ST_IS_OPERATOR_INTERFACE = 0x0100, 00174 ST_IS_U_OPERATOR_INTERFACE = 0x0200, 00175 ST_IS_PRIVATE = 0x0400, 00176 ST_IS_M_IMPORTED = 0x0800, 00177 ST_IS_IMPLEM_LEVEL_TEMP = 0x1000, 00178 ST_IS_PARAMETER = 0x2000, 00179 /* key */ 00180 ST_ONE_PER_PU = 0x4000, // Only 1 instance per pu 00181 ST_COPY_CONSTRUCTOR_ST = 0x8000, // ST is copy constructor function 00182 ST_INITV_IN_OTHER_ST = 0x10000, // ST is being used as an initianliation offset by other symbol 00183 ST_IS_INITIALIZED_IN_F90 =0x20000, 00184 ST_IS_DELETED =0x40000, 00185 ST_IS_COARRAY_CONCURRENT =0x80000, 00186 ST_KEEP_IN_OPENAD =0x100000 00187 00188 }; // ST_EXT_FLAGS 00189 00190 #if 0 00191 enum ST_EXT_FLAGS 00192 { 00193 ST_IS_POINTER = 0x01, 00194 ST_IS_ALLOCATABLE = 0x02, 00195 ST_IS_IN_MODULE = 0x04, 00196 ST_IS_EXTERNAL = 0x08, 00197 ST_IS_BLOCK_DATA = 0x10 00198 }; // ST_EXT_FLAGS 00199 # endif 00200 00201 // symbol table element 00202 class ST 00203 { 00204 public: 00205 union { 00206 STR_IDX name_idx; // index to the name string 00207 TCON_IDX tcon; // constant value 00208 } u1; 00209 00210 mUINT32 flags; // misc. attributes 00211 00212 // mUINT8 flags_ext; // more attributes 00213 mUINT8 unused; 00214 00215 ST_CLASS sym_class : 8; // class info 00216 ST_SCLASS storage_class : 8; // storage info 00217 ST_EXPORT export_class : 8; // export class of the symbol 00218 00219 union { 00220 TY_IDX type; // idx to high-level type 00221 PU_IDX pu; // idx to program unit table 00222 BLK_IDX blk; // idx to block table 00223 } u2; 00224 00225 mUINT64 offset; // offset from base 00226 00227 ST_IDX base_idx; // base of the allocated block 00228 00229 ST_IDX st_idx; // my own st_idx 00230 00231 mUINT64 flags_ext; //need 64bits for one word? 00232 00233 // operations 00234 00235 ST () {Fail_FmtAssertion("ST default constructor must not be called.");} 00236 00237 void Verify(UINT level) const; 00238 00239 void Print(FILE *f, BOOL verbose = TRUE) const; 00240 00241 }; // ST 00242 00243 00244 00245 // Give information about a field in a struct. The TY of the struct type 00246 // points to the FLD entry for the first field. The remaining fields 00247 // follow in consecutive FLD entries, until a flag indicates it is the last 00248 // field. 00249 00250 enum FLD_FLAGS 00251 { 00252 FLD_LAST_FIELD = 0x0001, // last field in a struct 00253 FLD_EQUIVALENCE = 0x0002, // fortran equivalence 00254 FLD_BEGIN_UNION = 0x0004, // begin a union 00255 FLD_END_UNION = 0x0008, // end a union 00256 FLD_BEGIN_MAP = 0x0010, // begin a map (fortran) 00257 FLD_END_MAP = 0x0020, // end a map 00258 FLD_IS_BIT_FIELD = 0x0040, // is bit field 00259 FLD_IS_POINTER = 0x0080 // is f90_pointer 00260 }; 00261 00262 struct FLD 00263 { 00264 STR_IDX name_idx; 00265 00266 TY_IDX type; 00267 00268 mUINT64 ofst; // offset within the struct in bytes 00269 00270 mUINT8 bsize; // bit field size in bits 00271 mUINT8 bofst; // bit field offset starting at 00272 // byte specified by ofst 00273 mUINT16 flags; // misc. attributes 00274 00275 ST_IDX st; // used if an st exists for this fld 00276 00277 // operations 00278 00279 FLD (); 00280 00281 void Verify (UINT64 record_size) const; 00282 00283 void Print (FILE *f) const; 00284 00285 }; // FLD 00286 00287 00288 typedef TY_IDX TYLIST; // for now, it's just a list of TY_IDX 00289 00290 00291 // Give information about a dimension of an array. The TY of the array type 00292 // points to the ARB entry for the first dimension. The remaining dimensions 00293 // follow in consecutive ARB entries until a flag indicates it is the last 00294 // dimension. 00295 enum ARB_FLAGS 00296 { 00297 ARB_CONST_LBND = 0x0001, // constant lower bound 00298 ARB_CONST_UBND = 0x0002, // constant upper bound 00299 ARB_CONST_STRIDE = 0x0004, // constant stride 00300 ARB_FIRST_DIMEN = 0x0008, // first dimension 00301 ARB_LAST_DIMEN = 0x0010, // last dimension 00302 ARB_EMPTY_LBND = 0x0020, 00303 ARB_EMPTY_UBND = 0x0040, 00304 ARB_STAR_UBND = 0x0080, 00305 ARB_EMPTY_STRIDE = 0x0100 00306 }; 00307 00308 struct ARB 00309 { 00310 mUINT16 flags; // misc. attributes 00311 mUINT16 dimension; // number of dimensions 00312 00313 // mUINT32 unused; // must be zero'ed 00314 mUINT16 co_dimension; // number of co_dimensions 00315 mUINT16 unused; // must be zero'ed 00316 00317 union { 00318 mINT64 lbnd_val; // constant lower bound value 00319 struct { 00320 ST_IDX lbnd_var; // variable that stores the 00321 // non-constant lower bound 00322 mINT32 unused; // filler, must be zero'ed 00323 } var; 00324 } u1; 00325 00326 union { 00327 mINT64 ubnd_val; // constant upper bound value 00328 struct { 00329 ST_IDX ubnd_var; // variable that stores the 00330 // non-constant upper bound 00331 mINT32 unused; // filler, must be zero'ed 00332 } var; 00333 } u2; 00334 00335 union { 00336 mINT64 stride_val; // constant stride 00337 struct { 00338 ST_IDX stride_var; // variable that stores the 00339 // non-constant stride 00340 mINT32 unused; // filler, must be zero'ed 00341 } var; 00342 } u3; 00343 00344 // access functions 00345 INT64 Lbnd_val () const { return u1.lbnd_val; } 00346 void Set_lbnd_val (INT64 val) { u1.lbnd_val = val; } 00347 00348 ST_IDX Lbnd_var () const { return u1.var.lbnd_var; } 00349 void Set_lbnd_var (ST_IDX st) { 00350 u1.var.lbnd_var = st; 00351 u1.var.unused = 0; 00352 } 00353 00354 INT64 Ubnd_val () const { return u2.ubnd_val; } 00355 void Set_ubnd_val (INT64 val) { u2.ubnd_val = val; } 00356 00357 ST_IDX Ubnd_var () const { return u2.var.ubnd_var; } 00358 void Set_ubnd_var (ST_IDX st) { 00359 u2.var.ubnd_var = st; 00360 u2.var.unused = 0; 00361 } 00362 00363 INT64 Stride_val () const { return u3.stride_val; } 00364 void Set_stride_val (INT64 val) { u3.stride_val = val; } 00365 00366 ST_IDX Stride_var () const { return u3.var.stride_var; } 00367 void Set_stride_var (ST_IDX st) { 00368 u3.var.stride_var = st; 00369 u3.var.unused = 0; 00370 } 00371 00372 00373 // operations 00374 00375 ARB () { memset (this, '\0', sizeof(ARB)); } 00376 00377 void Verify (mUINT16 dim) const; 00378 00379 void Print (FILE *f) const; 00380 00381 }; // ARB 00382 00383 00384 enum LABEL_KIND 00385 { 00386 LKIND_DEFAULT = 0, 00387 LKIND_ASSIGNED = 1, // in ASSIGNED statement 00388 LKIND_BEGIN_EH_RANGE = 2, 00389 LKIND_END_EH_RANGE = 3, 00390 LKIND_BEGIN_HANDLER = 4, 00391 LKIND_END_HANDLER = 5, 00392 LKIND_TAG = 6, // symbolic address, never branched to 00393 LKIND_INTERNAL = 7, // internally generated 00394 LKIND_LOOP_GEN = 8, // generated for loop control flow 00395 LKIND_SELECT_GEN = 9, // generated for SELECT statements 00396 LKIND_COUNT = 10 // total number of kinds 00397 }; 00398 00399 enum LABEL_FLAGS 00400 { 00401 LABEL_TARGET_OF_GOTO_OUTER_BLOCK = 1, 00402 LABEL_ADDR_SAVED = 2, 00403 LABEL_ADDR_PASSED = 4 00404 }; 00405 00406 struct LABEL 00407 { 00408 STR_IDX name_idx; 00409 mUINT32 flags:24; 00410 LABEL_KIND kind:8; 00411 00412 // operations 00413 00414 LABEL () {Fail_FmtAssertion("LABEL default constructor must not be called.");} 00415 00416 LABEL (STR_IDX idx, LABEL_KIND k) : name_idx (idx), kind (k) {} 00417 00418 void Verify(UINT level) const; 00419 00420 void Print (FILE *f) const; 00421 }; // LABEL 00422 00423 00424 struct PREG 00425 { 00426 STR_IDX name_idx; 00427 00428 // operations 00429 PREG(void) 00430 { 00431 Fail_FmtAssertion("PREG default constructor must not be called."); 00432 } 00433 00434 PREG (STR_IDX idx) : name_idx (idx) { } 00435 00436 void Verify(UINT level) const; 00437 00438 void Print (FILE *f) const; 00439 00440 }; // PREG 00441 00442 00443 // misc. ST attributes 00444 enum ST_ATTR_KIND 00445 { 00446 ST_ATTR_UNKNOWN = 0, 00447 ST_ATTR_DEDICATED_REGISTER = 1, // physical register number 00448 ST_ATTR_SECTION_NAME = 2, // name of sections where defined. 00449 ST_ATTR_KIND_COUNT = 3 // total number of kinds 00450 }; 00451 00452 struct ST_ATTR 00453 { 00454 ST_IDX st_idx; 00455 ST_ATTR_KIND kind; 00456 union { 00457 mUINT32 value; // generic 32-bit value 00458 mPREG_NUM reg_id; 00459 STR_IDX section_name; 00460 } u; 00461 00462 // operations 00463 ST_ATTR () { 00464 Fail_FmtAssertion("ST_ATTR default constructor must not be called."); 00465 } 00466 00467 ST_ATTR (ST_IDX idx, ST_ATTR_KIND akind, UINT32 val) : 00468 st_idx (idx), kind (akind) { 00469 u.value = val; 00470 } 00471 00472 00473 void Verify (UINT level) const; 00474 00475 void Print (FILE* f) const; 00476 }; // ST_ATTR 00477 00478 00479 00480 /* Kinds of types: */ 00481 enum TY_KIND 00482 { 00483 KIND_INVALID = 0, // Invalid 00484 KIND_SCALAR = 1, // integer/floating point 00485 KIND_ARRAY = 2, // array 00486 KIND_STRUCT = 3, // struct/union 00487 KIND_POINTER = 4, // pointer 00488 KIND_FUNCTION = 5, // function/procedure 00489 KIND_VOID = 6, // C void type 00490 KIND_LAST = 7 00491 }; 00492 00493 00494 enum TY_FLAGS 00495 { 00496 TY_IS_CHARACTER = 0x0001, /* type is a character (fortran) */ 00497 TY_IS_LOGICAL = 0x0002, /* Type is logical (fortran) */ 00498 TY_IS_UNION = 0x0004, /* Struct or class type is union */ 00499 TY_IS_PACKED = 0x0008, /* Struct or class type is packed */ 00500 TY_PTR_AS_ARRAY = 0x0010, /* Treat pointer as array */ 00501 TY_ANONYMOUS = 0x0020, /* Anonymous structs/classes/unions */ 00502 TY_SPLIT = 0x0040, /* Split from a larger common block 00503 * equivalence (block_split) */ 00504 TY_IS_F90_POINTER = 0x0080, /* If the type is an F90 pointer */ 00505 TY_NOT_IN_UNION = 0x0100, /* If the type cannot be part of a union */ 00506 TY_NO_ANSI_ALIAS = 0x0200, // ANSI alias rules don't applied 00507 TY_IS_NON_POD = 0x0400, // type is non pod (for C++ classes) 00508 TY_IS_F90_ASSUMED_SHAPE = 0x0800, 00509 TY_IS_F90_ASSUMED_SIZE = 0x1000, 00510 TY_IS_F90_DEFERRED_SHAPE = 0x2000, 00511 TY_IS_EXTERNAL = 0x4000, 00512 TY_IS_SEQUENCE = 0x8000, 00513 TY_IS_SHARED = 0x10000, // UPC shared type 00514 TY_IS_STRICT = 0x20000, 00515 TY_IS_RELAXED = 0x40000, 00516 TY_IS_CO_ARRAY = 0x80000, 00517 TY_IS_WRITTEN = 0x100000, //make w2c to output the type definition 00518 /* key */ 00519 TY_RETURN_IN_MEM = 0x200000 // Functions must return objects of this 00520 // type in memory. 00521 00522 }; 00523 00524 00525 // TY flags that are valid only for KIND_FUNCTION 00526 enum TY_PU_FLAGS 00527 { 00528 TY_RETURN_TO_PARAM = 0x00000001, // return value through first param 00529 TY_IS_VARARGS = 0x00000002, // variable number of arguments 00530 TY_HAS_PROTOTYPE = 0x00000004 // has ansi-style prototype 00531 }; 00532 00533 #define UPC_INDEFINITE_BLOCK_SIZE -1 00534 00535 00536 class TY 00537 { 00538 public: 00539 mUINT64 size; // size of the type in bytes 00540 00541 TY_KIND kind : 8; // kind of type 00542 mTYPE_ID mtype : 8; // WHIRL data type 00543 mUINT32 flags; // misc. attributes 00544 00545 union { 00546 FLD_IDX fld; 00547 TYLIST_IDX tylist; 00548 ARB_IDX arb; 00549 } u1; // idx to FLD_TAB, TYLIST_TAB, etc. 00550 00551 STR_IDX name_idx; // name 00552 00553 union { 00554 TY_IDX etype; // type of array element (array only) 00555 TY_IDX pointed; // pointed-to type (pointers only) 00556 mUINT32 pu_flags; // attributes for KIND_FUNCTION 00557 ST_IDX copy_constructor; // copy constructor X(X&) (record only) 00558 } u2; 00559 00560 mUINT32 block_size; // block size for UPC shared data 00561 // access function for unions 00562 00563 FLD_IDX Fld () const { return u1.fld; } 00564 void Set_fld (FLD_IDX idx) { u1.fld = idx; } 00565 00566 TYLIST_IDX Tylist () const { return u1.tylist; } 00567 void Set_tylist (TYLIST_IDX idx) { u1.tylist = idx; } 00568 00569 ARB_IDX Arb () const { return u1.arb; } 00570 void Set_arb (ARB_IDX idx) { u1.arb = idx; } 00571 00572 TY_IDX Etype () const 00573 { 00574 Is_True(kind == KIND_ARRAY, 00575 ("non-KIND_ARRAY type has no element type")); 00576 return u2.etype; 00577 } 00578 void Set_etype (TY_IDX idx) { u2.etype = idx; } 00579 00580 TY_IDX Pointed () const 00581 { 00582 Is_True(kind == KIND_POINTER, 00583 ("non-KIND_POINTER type doesn't point")); 00584 return u2.pointed; 00585 } 00586 void Set_pointed (TY_IDX idx) { u2.pointed = idx; } 00587 00588 ST_IDX Copy_constructor () const 00589 { 00590 Is_True(kind == KIND_STRUCT, 00591 ("non-KIND_STRUCT type has no copy constructor")); 00592 return u2.copy_constructor; 00593 } 00594 void Set_copy_constructor (ST_IDX idx) { u2.copy_constructor = idx; } 00595 00596 PU_IDX Pu_flags () const { return u2.pu_flags; } 00597 void Set_pu_flag (TY_PU_FLAGS f) { u2.pu_flags |= f; } 00598 void Clear_pu_flag (TY_PU_FLAGS f) { u2.pu_flags &= ~f; } 00599 00600 // operations 00601 00602 TY (); 00603 00604 void Verify(UINT level) const; 00605 00606 void Print (FILE *f) const; 00607 00608 }; // TY 00609 00610 00611 // PU_FLAGS: cannot use enum as some of the the values are > max unsigned int 00612 00613 #define PU_IS_PURE 0x00000001 // pure function 00614 #define PU_NO_SIDE_EFFECTS 0x00000002 // no side effect 00615 #define PU_IS_INLINE_FUNCTION 0x00000004 // inline keyword specified 00616 #define PU_NO_INLINE 0x00000008 // noinline pragma specified 00617 #define PU_MUST_INLINE 0x00000010 // must inline 00618 #define PU_NO_DELETE 0x00000020 // nodelete pragma specified 00619 #define PU_HAS_EXC_SCOPES 0x00000040 // has eh regions, or would have 00620 // if exceptions were enabled 00621 #define PU_IS_NESTED_FUNC 0x00000080 // is a nested function 00622 #define PU_HAS_NON_MANGLED_CALL 0x00000100 // PU has a call in which no 00623 // reshaped arrays are passed 00624 #define PU_ARGS_ALIASED 0x00000200 // f77 arguments are aliased 00625 #define PU_NEEDS_FILL_ALIGN_LOWERING 0x00000400 // needs fill/align lowering 00626 #define PU_NEEDS_T9 0x00000800 // needs T9 00627 #define PU_HAS_VERY_HIGH_WHIRL 0x00001000 // PU has very high whirl in it 00628 #define PU_HAS_ALTENTRY 0x00002000 // PU has alternate entries 00629 #define PU_RECURSIVE 0x00004000 // in recursive path 00630 #define PU_IS_MAINPU 0x00008000 // is entry point of program 00631 #define PU_UPLEVEL 0x00010000 // Other PU nested in this one 00632 #define PU_MP_NEEDS_LNO 0x00020000 // PU needs LNO processing 00633 #define PU_HAS_ALLOCA 0x00040000 // PU has alloca in it 00634 #define PU_IN_ELF_SECTION 0x00080000 // PU is in its own Elf section 00635 #define PU_HAS_MP 0x00100000 // Symtab has MP region/do 00636 // within it 00637 #define PU_MP 0x00200000 // PU is an MP region/do 00638 #define PU_HAS_NAMELIST 0x00400000 // PU has namelist 00639 #define PU_HAS_RETURN_ADDRESS 0x00800000 // __return_address was used 00640 #define PU_HAS_REGION 0x01000000 // PU has regions in it 00641 #define PU_HAS_INLINES 0x02000000 // PU has inlined code in it 00642 #define PU_CALLS_SETJMP 0x04000000 // PU has calls to setjmp(2) 00643 #define PU_CALLS_LONGJMP 0x08000000 // PU has calls to longjmp(2) 00644 #define PU_IPA_ADDR_ANALYSIS 0x10000000 // IPA has done address analysis 00645 #define PU_SMART_ADDR_ANALYSIS 0x20000000 // Unnecessary addr flags are 00646 // reset 00647 00648 #define PU_HAS_SYSCALL_LINKAGE 0x40000000 // preserve input regs 00649 #define PU_HAS_GLOBAL_PRAGMAS 0x80000000 // PU is a dummy pu with global 00650 // pragmas 00651 #define PU_HAS_USER_ALLOCA 0x0000000100000000LL 00652 // PU has user alloca in it 00653 #define PU_HAS_UNKNOWN_CONTROL_FLOW 0x0000000200000000LL 00654 // PU has unknown control flow 00655 // which disables tail call 00656 // optimization 00657 #define PU_IS_THUNK 0x0000000400000000LL 00658 // pu is a C++ thunk 00659 #define PU_DECL_VIEW 0x0000000800000000LL 00660 // pu is a multiply copy 00661 // for declare "external" 00662 #define PU_NEED_UNPARSED 0x0000001000000000LL 00663 // pu flag for unparser to 00664 // discard some unwanted PU 00665 #define PU_NEEDS_MANUAL_UNWINDING 0x0000002000000000LL 00666 // PU has cleanups in outermost 00667 // scope and hence needs to 00668 // call _Unwind_Resume itself 00669 #ifdef TARG_X8664 00670 # define PU_FF2C_ABI 0x0000004000000000LL 00671 // PU use g77 linkage 00672 // convention for returns of 00673 // complex and float 00674 #endif 00675 00676 00677 enum PU_SRC_LANG_FLAGS 00678 { 00679 PU_UNKNOWN_LANG = 0x00, // UNKNOWN 00680 PU_MIXED_LANG = 0x01, // MIXED 00681 PU_C_LANG = 0x02, // C 00682 PU_CXX_LANG = 0x04, // C++ 00683 PU_F77_LANG = 0x08, // F77 00684 PU_F90_LANG = 0x10, // F90 00685 PU_JAVA_LANG = 0x20 // JAVA 00686 }; 00687 00688 struct PU 00689 { 00690 TARGET_INFO_IDX target_idx; // idx to table for target-specific 00691 // information 00692 00693 TY_IDX prototype; // function prototype 00694 SYMTAB_IDX lexical_level; // lexical level (of nested proc). 00695 mUINT8 gp_group; // gp_group id 00696 mUINT8 src_lang; // source language 00697 00698 /* 00699 * Solaris CC workaround 00700 * 00701 * There are several issues on this bit field 'unused'. First, Solaris CC 00702 * doesn't allow long long bit-field. So we'll have to change it to long. 00703 * Second, Solaris CC has different implementation on bit field, such that 00704 * if we define "mUINT32 unused : 40", the total size of PU will be 32 00705 * bytes instead of 24 bytes! Although it seems to be okay for 'mfef90', 00706 * it does cause Seg Fault on 'ir_b2a'. One simple way is to define 00707 * 'unused' as 32-bit long, and it's up to the compiler to acutally make 00708 * PU 24 bytes. See symtab_verify.cxx for the use of "unused".. 00709 * 00710 */ 00711 // TODO: can put flags in 40-bit unused field and remove 64-bit flag field. 00712 // TODO: do this when can make incompatible change. 00713 #if defined(_SOLARIS_SOLARIS) && !defined(__GNUC__) 00714 mUINT32 unused : 32; 00715 #else 00716 mUINT64 unused : 40; // for alignment for flags 00717 #endif 00718 00719 mUINT64 flags; // misc. attributes about this func. 00720 00721 // operations 00722 00723 PU (); 00724 00725 void Verify(UINT level) const; 00726 00727 void Print (FILE *f) const; 00728 00729 }; // PU 00730 00731 00732 // BLK only exists for CLASS_BLOCK. 00733 // It is used for data layout in be. 00734 // Only reason it is not local to be is that 00735 // the IPA global symbol table will need the info. 00736 class BLK 00737 { 00738 private: 00739 00740 mUINT64 size; // size of the block 00741 mUINT16 align; // alignment of the block: 1,2,4,8 00742 mUINT16 flags; // block flags 00743 mUINT16 section_idx; // section index (0 if not a section) 00744 mUINT16 scninfo_idx; // scninfo_idx (0 if not a section) 00745 00746 public: 00747 00748 BLK () : size (0), flags (0), section_idx(0), scninfo_idx(0) {} 00749 00750 void Init (void) { memset (this, '\0', sizeof(BLK)); } 00751 00752 public: 00753 00754 // access functions 00755 00756 UINT64 Size () const { return size; } 00757 void Set_size (UINT64 s) { size = s; } 00758 00759 UINT16 Align () const { return align; } 00760 void Set_align (UINT16 s) { align = s; } 00761 00762 UINT16 Section_idx () const { return section_idx; } 00763 void Set_section_idx (UINT16 s) { section_idx = s; } 00764 UINT16 Scninfo_idx () const { return scninfo_idx; } 00765 void Set_scninfo_idx (UINT16 s) { scninfo_idx = s; } 00766 00767 UINT16 Flags () const { return flags; } 00768 BOOL Is_set (UINT16 f) const { return flags & f; } 00769 void Set_flags (UINT16 f) { flags |= f; } 00770 void Clear_flags (UINT16 f) { flags &= ~f; } 00771 void Clear_all_flags () { flags = 0; } 00772 00773 void Print (FILE *f) const; 00774 }; // BLK 00775 00776 // BLK flags 00777 #define BLK_SECTION 0x0001 // block for elf section 00778 #define BLK_ROOT_BASE 0x0002 // block should not be merged 00779 #define BLK_IS_BASEREG 0x0004 // block that maps into reg 00780 #define BLK_DECREMENT 0x0008 // grow block by decrementing 00781 #define BLK_EXEC 0x0010 // (ELF) executable instructions 00782 #define BLK_NOBITS 0x0020 // (ELF) occupies no space in file 00783 #define BLK_MERGE 0x0040 // (ELF) merge duplicates in ld 00784 #define BLK_COMPILER_LAYOUT 0x0080 // children symbols are not connected 00785 00786 00787 // place holder for misc. file-level info 00788 00789 enum FILE_INFO_FLAGS 00790 { 00791 FI_IPA = 0x1, // IPA generated file 00792 FI_NEEDS_LNO = 0x2, // needs to run LNO 00793 FI_HAS_INLINES = 0x4, // some PUs have PU_HAS_INLINES set 00794 FI_HAS_MP = 0x8 // need to process MP constructs 00795 }; 00796 00797 struct FILE_INFO 00798 { 00799 mUINT32 flags; // misc. attributes 00800 mUINT8 gp_group; // gp group id 00801 mUINT32 unused : 24; // filler, must be zero 00802 00803 void Verify() const; 00804 void Print (FILE *f) const; 00805 FILE_INFO () : flags (0), gp_group (0), unused (0) {} 00806 00807 }; 00808 00809 00810 // Type definitions of the symbol tables 00811 00812 typedef SEGMENTED_ARRAY<PU> PU_TAB; 00813 typedef RELATED_SEGMENTED_ARRAY<ST> ST_TAB; 00814 typedef SEGMENTED_ARRAY<TY> TY_TAB; 00815 typedef SEGMENTED_ARRAY<FLD> FLD_TAB; 00816 typedef SEGMENTED_ARRAY<TYLIST> TYLIST_TAB; 00817 typedef SEGMENTED_ARRAY<ARB> ARB_TAB; 00818 typedef RELATED_SEGMENTED_ARRAY<LABEL> LABEL_TAB; 00819 typedef RELATED_SEGMENTED_ARRAY<PREG> PREG_TAB; 00820 typedef SEGMENTED_ARRAY<ST_ATTR> ST_ATTR_TAB; 00821 typedef SEGMENTED_ARRAY<BLK> BLK_TAB; 00822 typedef SEGMENTED_ARRAY<TCON,64> TCON_TAB; 00823 typedef SEGMENTED_ARRAY<INITO> INITO_TAB; 00824 typedef SEGMENTED_ARRAY<INITV> INITV_TAB; 00825 00826 typedef PU_TAB::iterator PU_ITER; 00827 typedef ST_TAB::iterator ST_ITER; 00828 typedef TY_TAB::iterator TY_ITER; 00829 typedef FLD_TAB::iterator FLD_ITER; 00830 typedef TYLIST_TAB::iterator TYLIST_ITER; 00831 typedef ARB_TAB::iterator ARB_ITER; 00832 typedef LABEL_TAB::iterator LABEL_ITER; 00833 typedef PREG_TAB::iterator PREG_ITER; 00834 typedef ST_ATTR_TAB::iterator ST_ATTR_ITER; 00835 typedef BLK_TAB::iterator BLK_ITER; 00836 typedef TCON_TAB::iterator TCON_ITER; 00837 typedef INITO_TAB::iterator INITO_ITER; 00838 typedef INITV_TAB::iterator INITV_ITER; 00839 00840 00841 struct SCOPE 00842 { 00843 MEM_POOL *pool; // mem pool for local tables 00844 ST* st; // ST * for the current pu 00845 ST_TAB *st_tab; 00846 LABEL_TAB *label_tab; 00847 PREG_TAB *preg_tab; 00848 INITO_TAB *inito_tab; 00849 ST_ATTR_TAB *st_attr_tab; 00850 00851 void Init (ST_TAB *s) { 00852 // for global symtab 00853 pool = NULL; 00854 st_tab = s; 00855 st = NULL; 00856 label_tab = NULL; 00857 preg_tab = NULL; 00858 inito_tab = NULL; 00859 st_attr_tab = NULL; 00860 } 00861 00862 void Init (ST_TAB *s, LABEL_TAB *l, PREG_TAB *p, INITO_TAB *io, 00863 ST_ATTR_TAB* d, MEM_POOL *mp = Malloc_Mem_Pool) { 00864 pool = mp; 00865 st = NULL; 00866 st_tab = s; 00867 label_tab = l; 00868 preg_tab = p; 00869 inito_tab = io; 00870 st_attr_tab = d; 00871 00872 } 00873 00874 00875 }; // SCOPE 00876 00877 // predefined Scope indices 00878 #define GLOBAL_SYMTAB (1) // file scope global symtab 00879 #define CURRENT_SYMTAB (Current_scope) 00880 00881 struct SCOPE_TAB_SYMTAB_ACCESS { 00882 SCOPE_TAB_SYMTAB_ACCESS(void) { } 00883 00884 ST_TAB *operator()(SCOPE **scope_tab, SYMTAB_IDX level) 00885 { return (*scope_tab)[level].st_tab; } 00886 }; 00887 00888 struct SCOPE_TAB_INITO_ACCESS { 00889 SCOPE_TAB_INITO_ACCESS(void) { } 00890 00891 INITO_TAB *operator()(SCOPE **scope_tab, SYMTAB_IDX level) 00892 { return (*scope_tab)[level].inito_tab; } 00893 }; 00894 00895 // The global scope table 00896 extern SCOPE *Scope_tab; 00897 00898 // One instance of the following class per compilation. 00899 typedef TABLE_INDEXED_BY_LEVEL8_AND_INDEX24<ST, ST_IDX, SYMTAB_IDX, 00900 SCOPE *, &Scope_tab, 00901 SCOPE_TAB_SYMTAB_ACCESS> 00902 SYMBOL_TABLE; 00903 00904 typedef TABLE_INDEXED_BY_LEVEL8_AND_INDEX24<INITO, INITO_IDX, SYMTAB_IDX, 00905 SCOPE *, &Scope_tab, 00906 SCOPE_TAB_INITO_ACCESS> 00907 INITO_TABLE; 00908 00909 struct LABEL_TABLE 00910 { 00911 inline LABEL& operator[] (LABEL_IDX idx); 00912 inline LABEL& operator() (SYMTAB_IDX level, LABEL_IDX idx); 00913 }; 00914 00915 struct PREG_TABLE 00916 { 00917 inline PREG& operator[] (PREG_IDX idx); 00918 inline PREG& operator() (SYMTAB_IDX level, PREG_IDX idx); 00919 }; 00920 00921 struct ST_ATTR_TABLE 00922 { 00923 inline ST_ATTR& operator[] (ST_ATTR_IDX idx); 00924 inline ST_ATTR& operator() (SYMTAB_IDX level, ST_ATTR_IDX idx); 00925 }; 00926 00927 struct TYPE_TABLE 00928 { 00929 inline TY& operator[] (TY_IDX idx); 00930 inline TY_TAB* operator& (); 00931 }; 00932 00933 // declaration of global tables 00934 extern FILE_INFO File_info; 00935 extern PU_TAB Pu_Table; 00936 extern SYMBOL_TABLE St_Table; 00937 extern TY_TAB Ty_tab; 00938 extern TYPE_TABLE Ty_Table; 00939 extern FLD_TAB Fld_Table; 00940 extern TYLIST_TAB Tylist_Table; 00941 extern ARB_TAB Arb_Table; 00942 extern STRING_TABLE Str_Table; 00943 extern TCON_TAB Tcon_Table; 00944 extern INITV_TAB Initv_Table; 00945 extern INITO_TABLE Inito_Table; 00946 extern PREG_TABLE Preg_Table; 00947 extern ST_ATTR_TABLE St_Attr_Table; 00948 extern LABEL_TABLE Label_Table; 00949 // some BLK_TAB items are really local, but make global to ease management 00950 extern BLK_TAB Blk_Table; 00951 00952 // global variables 00953 00954 extern SYMTAB_IDX Current_scope; 00955 extern PU* Current_pu; 00956 00957 00958 00959 00960 // headers that describe the layout of the symtab structures in files 00961 // changing any of these requires incrementing the WHIRL revision number 00962 00963 // symbol table header types 00964 enum SHDR_TYPE 00965 { 00966 SHDR_UNK = 0, // uninitialized 00967 SHDR_FILE = 1, 00968 SHDR_ST = 2, 00969 SHDR_TY = 3, 00970 SHDR_PU = 4, 00971 SHDR_FLD = 5, 00972 SHDR_ARB = 6, 00973 SHDR_TYLIST = 7, 00974 SHDR_TCON = 8, 00975 SHDR_STR = 9, 00976 SHDR_LABEL = 10, 00977 SHDR_PREG = 11, 00978 SHDR_INITO = 12, 00979 SHDR_INITV = 13, 00980 SHDR_BLK = 14, 00981 SHDR_ST_ATTR= 15 00982 }; // SHDR_TYPE 00983 00984 00985 struct SYMTAB_HEADER 00986 { 00987 mUINT64 offset; // offset from beginning of section 00988 mUINT64 size; // size in bytes 00989 mUINT32 entsize; // size of each entry if fixed 00990 // zero if entry size variable 00991 mUINT16 align; // alignment 00992 mUINT16 type; // type of table 00993 00994 void Init (UINT64 _offset, UINT64 _size, UINT32 _entsize, 00995 UINT16 _align, SHDR_TYPE _type) { 00996 offset = _offset; 00997 size = _size; 00998 entsize = _entsize; 00999 align = _align; 01000 type = _type; 01001 } 01002 01003 }; // SYMTAB_HEADER 01004 01005 01006 #define GLOBAL_SYMTAB_TABLES (13) // # of tables in global symtab: 01007 // FILE_INFO, ST, TY, PU, FLD, ARB, 01008 // TYLIST, TCON, STR, INITO, INITV, 01009 // BLK, and ST_ATTR 01010 #define LOCAL_SYMTAB_TABLES (5) // # of tables in local symtab: 01011 // ST, LABEL, PREG, INITO, and ST_ATTR 01012 01013 template <UINT table_size> 01014 struct SYMTAB_HEADER_TABLE 01015 { 01016 mUINT32 size; // size of myself in bytes 01017 mUINT32 entries; // number of SYMTAB_HEADER entries 01018 01019 SYMTAB_HEADER header[table_size]; 01020 01021 typedef SYMTAB_HEADER_TABLE<table_size> self; 01022 01023 SYMTAB_HEADER_TABLE () { 01024 size = sizeof(self); 01025 entries = table_size; 01026 memset (header, '\0', sizeof(header)); 01027 } 01028 01029 }; // SYMTAB_HEADER_TABLE 01030 01031 typedef SYMTAB_HEADER_TABLE<GLOBAL_SYMTAB_TABLES> GLOBAL_SYMTAB_HEADER_TABLE; 01032 typedef SYMTAB_HEADER_TABLE<LOCAL_SYMTAB_TABLES> LOCAL_SYMTAB_HEADER_TABLE; 01033 01034 #endif /* symtab_defs_INCLUDED */ 01035