Hi Sun,

Attached symtab_defs.h.

Thanks
zhuqing
2011/8/24 Sun Chan <sun.c...@gmail.com>:
> can you send me the full symtab_defs.h?
> Sun
>
> On Wed, Aug 24, 2011 at 4:56 PM, 朱庆 <zqing1...@gmail.com> wrote:
>> Hi all,
>>
>> Can gatekeeper help review following fix for bug832?
>> https://bugs.open64.net/show_bug.cgi?id=832
>>
>> small case, a.c:
>> struct obs_kernel_param {
>>  const char *str;
>> };
>>
>> const char str1[] = "acpi_parse_apic_instance=";
>> const char str2[] = "acpi_os_name";
>> struct obs_kernel_param var1
>>  __attribute__ ((aligned ((sizeof (long))))) =
>> {str1};
>>
>> struct obs_kernel_param var2
>>  __attribute__ ((aligned ((sizeof (long))))) =
>> {str2};
>>
>> when compile with opencc, nm a.o
>> 0000000000000000 D var1
>> 0000000000000010 D var2
>> compile with gcc, nm a.o
>> 0000000000000000 D var1
>> 0000000000000008 D var2
>> the offset of var1 and var2 are different, the problem with opencc is
>> :fixed align attribute does not work, this may cause some problems
>> when mix link two files with opencc and gcc.
>>
>> The fix is to add a new ST flag to record user_defined_align.
>>
>> Thanks
>> zhuqing
>>
>> ------------------------------------------------------------------------------
>> EMC VNX: the world's simplest storage, starting under $10K
>> The only unified storage solution that offers unified management
>> Up to 160% more powerful than alternatives and 25% more efficient.
>> Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev
>> _______________________________________________
>> Open64-devel mailing list
>> Open64-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/open64-devel
>>
>>
>
/*
 * Copyright (C) 2009-2010 Advanced Micro Devices, Inc.  All Rights Reserved.
 */

/*
 * Copyright (C) 2007. QLogic Corporation. All Rights Reserved.
 */

/*
 * Copyright 2003, 2004, 2005, 2006 PathScale, Inc.  All Rights Reserved.
 */

/*

  Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.

  This program is free software; you can redistribute it and/or modify it
  under the terms of version 2 of the GNU General Public License as
  published by the Free Software Foundation.

  This program is distributed in the hope that it would be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

  Further, this software is distributed without any warranty that it is
  free of the rightful claim of any third person regarding infringement 
  or the like.  Any license provided herein, whether implied or 
  otherwise, applies only to this software file.  Patent licenses, if 
  any, provided herein do not apply to combinations of this program with 
  other software, or any other product whatsoever.  

  You should have received a copy of the GNU General Public License along
  with this program; if not, write the Free Software Foundation, Inc., 59
  Temple Place - Suite 330, Boston MA 02111-1307, USA.

  Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
  Mountain View, CA 94043, or:

  http://www.sgi.com

  For further information regarding this notice, see:

  http://oss.sgi.com/projects/GenInfo/NoticeExplan

*/


/* -*-Mode: c++;-*- (Tell emacs to use c++ mode) */

#ifndef symtab_defs_INCLUDED
#define symtab_defs_INCLUDED

// Note:
//
// The comments in this file are intentionally brief.  For detail description,
// please refer to the "WHIRL Symbol Table Specification", which is the only
// document actively maintained.
//
// KEY: Any change in this file (and friends) about change in struct size
// or ordering of struct fields may need to be reflected elsewhere in the
// compiler, at least one known place of which is ipa/common/ipc_ty_hash.cxx
// and friends.
// Last notable change: changing STR_IDX from UINT32 to UINT64.


enum ST_CLASS
{
    CLASS_UNK	= 0,
    CLASS_VAR	= 1,			// data variable
    CLASS_FUNC	= 2,			// addrress of a function.
    CLASS_CONST	= 3,			// constant value
    CLASS_PREG	= 4,			// pseudo register
    CLASS_BLOCK	= 5,			// base to a block of data
    CLASS_NAME  = 6,			// just hold an ST name
    CLASS_COUNT = 7			// total number of classes
}; // ST_CLASS


enum ST_SCLASS
{
    // the values should not overlap with those in ST_CLASS for error checking
    SCLASS_UNKNOWN	= 0,
    SCLASS_AUTO		= 1,		// stack variable
    SCLASS_FORMAL	= 2,		// formal parameter
    SCLASS_FORMAL_REF	= 3,		// reference parameter
    SCLASS_PSTATIC	= 4,		// PU scope static data
    SCLASS_FSTATIC	= 5,		// file scope static data
    SCLASS_COMMON	= 6,		// common block (linker allocated)
    SCLASS_EXTERN	= 7,		// unallocated external data or text
    SCLASS_UGLOBAL	= 8,		// uninitialized global data
    SCLASS_DGLOBAL	= 9,		// initialized global data
    SCLASS_TEXT		= 10,		// executable code
    SCLASS_REG		= 11,		// register variable
    SCLASS_CPLINIT	= 12,		// cplinit
    SCLASS_EH_REGION	= 13,		// eh region
    SCLASS_EH_REGION_SUPP = 14,		// eh region supp
    SCLASS_DISTR_ARRAY	= 15,		// distributed array
    SCLASS_COMMENT	= 16,		// comment section
    SCLASS_THREAD_PRIVATE_FUNCS	= 17, // thread-private constr/destr funcs
    SCLASS_COUNT	= 18		// total number of classes

}; // ST_SCLASS


enum ST_EXPORT
{
    EXPORT_LOCAL	= 0,		// Not exported, e.g. C static
    EXPORT_LOCAL_INTERNAL = 1,		// Statics that do not have address
					// passed outside of a.out/DSO. 
    EXPORT_INTERNAL	= 2,		// Exported, only visible and used
					// within the containing
					// DSO/executable, i.e. not even
					// passed outside using a pointer.  
    EXPORT_HIDDEN	= 3,		// Exported, but name is hidden
					// within the containing
					// DSO/executable.  However, the
					// address may be exported from the
					// DSO via a pointer.  
    EXPORT_PROTECTED	= 4,		// Exported from DSO, but
					// non-preemptible. 
    EXPORT_PREEMPTIBLE	= 5,		// Exported and preemptible.
    EXPORT_OPTIONAL	= 6,		// STO_OPTIONAL case in "sys/elf.h"
    EXPORT_COUNT	= 7		// Must be last for consistency
					// checking 
}; // ST_EXPORT

#ifdef TARG_NVISA
enum ST_MEMORY
{
    MEMORY_UNKNOWN = 0,
    MEMORY_GLOBAL = 1,
    MEMORY_LOCAL = 2,
    MEMORY_SHARED = 3,
    MEMORY_CONSTANT = 4,
    MEMORY_TEXTURE = 5,
    MEMORY_PARAM = 6,
    MEMORY_COUNT = 7
}; // ST_MEMORY
#else
enum ST_TLS_MODEL {
    TLS_NONE,
    TLS_EMULATED, /* for emulated tls */
    TLS_REAL,
    TLS_GLOBAL_DYNAMIC = TLS_REAL,
    TLS_LOCAL_DYNAMIC,
    TLS_INITIAL_EXEC,
    TLS_LOCAL_EXEC,
}; // TLS_MODEL
#endif /* TARG_NVISA */

enum ST_FLAGS
{
    ST_IS_WEAK_SYMBOL	= 0x00000001,	// Weak external name
    ST_IS_SPLIT_COMMON	= 0x00000002,	// part of a splitted common
    ST_IS_NOT_USED	= 0x00000004,	// Symbol is not referenced
    ST_IS_INITIALIZED	= 0x00000008,	// Symbol is initialized
    ST_IS_RETURN_VAR	= 0x00000010,	// CLASS_VAR: Return value
    ST_IS_VALUE_PARM	= 0x00000020,	// CLASS_VAR: Value parm
    ST_PROMOTE_PARM	= 0x00000040,	// CLASS_VAR: Promote C formal
    ST_KEEP_NAME_W2F	= 0x00000080,	// CLASS_VAR: don't mangle name
    ST_IS_DATAPOOL	= 0x00000100,	// CLASS_VAR: represents datapool
    ST_IS_RESHAPED	= 0x00000200,	// lno may reshape the ST
    ST_EMIT_SYMBOL	= 0x00000400,	// emit the empty dummy symbol
    ST_HAS_NESTED_REF	= 0x00000800,	// has ref in nested pu
    ST_INIT_VALUE_ZERO	= 0x00001000,	// has initial value of zero
    ST_GPREL		= 0x00002000,	// force object to be gp-rel
    ST_NOT_GPREL	= 0x00004000,	// force object to not be gp-rel
    ST_IS_NAMELIST	= 0x00008000,	// namelist table
    ST_IS_F90_TARGET	= 0x00010000,	// F90 target
    ST_DECLARED_STATIC	= 0x00020000,	// VMS formals declared static
    ST_IS_EQUIVALENCED	= 0x00040000,	// is part of an equivalence
    ST_IS_FILL_ALIGN	= 0x00080000,	// has fill/align pragma.
    ST_IS_OPTIONAL_ARGUMENT = 0x00100000, // F90 OPTIONAL arguments
    ST_PT_TO_UNIQUE_MEM	= 0x00200000,	// a pointer that is not aliased
    ST_IS_TEMP_VAR	= 0x00400000,	// compiler generated temp. variable
    ST_IS_CONST_VAR	= 0x00800000,	// read-only variable
    ST_ADDR_SAVED	= 0x01000000,	// address saved
    ST_ADDR_PASSED	= 0x02000000,	// address passed
    ST_IS_THREAD_PRIVATE = 0x04000000,	// Symbol is allocated in XLOCAL
					// data segment
    ST_PT_TO_COMPILER_GENERATED_MEM = 0x08000000,   // a pointer to compiler-
                                        // allocated memory space
    ST_IS_SHARED_AUTO = 0x10000000,     // SCLASS_AUTO and accessed with
                                        // SHARED scope in an MP region
    ST_ASSIGNED_TO_DEDICATED_PREG = 0x20000000,	// assigned to dedicated preg
						// specified in offset
    ST_ASM_FUNCTION_ST  = 0x40000000,	// ST is CLASS_NAME asm string with
                                        // file scope.
    ST_HAS_NAMED_SECTION = 0x80000000	// has named section attribute
    // new flags must go into flags_ext field.
}; // ST_FLAGS
    
#ifdef KEY
enum ST_FLAGS_EXT
{
    ST_ONE_PER_PU = 0x01,		// Only 1 instance per pu
    ST_COPY_CONSTRUCTOR_ST =   0x02,	// ST is copy constructor function
    ST_INITV_IN_OTHER_ST   =   0x04,    // ST is being used as an initianliation offset by other symbol
    ST_IS_INITIALIZED_IN_F90 = 0x8, 
    ST_IS_METHOD_FUNC	= 0x10,         // ST is c++ method function (make sense only 
                                        // when st-class is CLASS_FUNC	
    ST_IS_THIS_PTR      = 0x20, 	// ST is "this"-pointer
    ST_IS_PURE_VFUNC    = 0x40,         // ST is pure virtual function
    ST_IS_THREAD_LOCAL  = 0x80,         // ST is Thread-Local_Storage, __thread
    ST_IS_ARRAY_REMAPPING_CANDIDATE = 0x100,
    ST_IS_ARRAY_REMAPPING_CANDIDATE_MALLOC = 0x200, // storage for the remapped
                                        // array is from malloc()
#if defined(TARG_SL)
    ST_IN_V1BUF = 0x400,                // ST is vector1 variable
    ST_IN_V2BUF = 0x800,                // ST is vector2 variable 
    ST_IN_V4BUF = 0x1000,               // ST is vector4 variable 
    ST_IN_SDRAM = 0x2000,               // ST is sdram variable 
    ST_IN_SBUF =  0x4000,               // ST is explcitly declared sbuf so 
    ST_IS_VBUF_OFFSET = 0x8000,  // represent this symbol means offset instead of a absolute address
    ST_IS_SBUF_OFFSET = 0x10000, // same as above and will be deleted for we don't have sbuf in the future.
#endif     
    ST_IS_GLOBAL_AS_LOCAL = 0x20000, // Is a global variable that can be treated as a local variable.
    ST_IS_VTABLE = 0x40000,        //st is a vtalbe
    ST_HAS_USER_ALIGN = 0x80000,
}; // ST_FLAGS_EXT
#endif

// symbol table element
class ST
{
public:
    union {
	STR_IDX name_idx;		// index to the name string
	TCON_IDX tcon;			// constant value
    } u1;

    mUINT32 flags;			// misc. attributes

    mUINT32 flags_ext;			// more attributes

    ST_CLASS sym_class : 8;		// class info
    ST_SCLASS storage_class : 8;	// storage info
    ST_EXPORT export_class : 4;		// export class of the symbol
#ifdef TARG_NVISA
    ST_MEMORY memory_space: 4;		// memory space of the symbol
#else
    ST_TLS_MODEL tls_model: 4;		// Thread-Local-Storage(TLS) model
#endif
    union {
	TY_IDX type;			// idx to high-level type
	PU_IDX pu;			// idx to program unit table
	BLK_IDX blk;			// idx to block table
    } u2;

#ifdef KEY
    // bug 14141: we need to ensure the pad bytes are zero so that
    // byte-comparison in IPA does not fail.
    mUINT32 pad;			// 4 pad bytes (initialize to zero)
#endif
    mUINT64 offset;			// offset from base

    ST_IDX base_idx;			// base of the allocated block

    ST_IDX st_idx;			// my own st_idx

    TY_IDX vtable_ty_idx;

    // operations
    
    ST ()  {Fail_FmtAssertion("ST default constructor must not be called.");}

    void Verify(UINT level) const;
    
    void Print(FILE *f, BOOL verbose = TRUE) const;
    
    BOOL operator==(ST &st) const;

    friend std::ostream& operator<<(std::ostream &os, const ST& st);

}; // ST



// Give information about a field in a struct.  The TY of the struct type
// points to the FLD entry for the first field.  The remaining fields
// follow in consecutive FLD entries, until a flag indicates it is the last
// field.

enum FLD_FLAGS
{
    FLD_LAST_FIELD	= 0x0001,	// last field in a struct
    FLD_EQUIVALENCE	= 0x0002,	// fortran equivalence
    FLD_BEGIN_UNION	= 0x0004,      	// begin a union
    FLD_END_UNION	= 0x0008,	// end a union
    FLD_BEGIN_MAP	= 0x0010,	// begin a map (fortran)
    FLD_END_MAP		= 0x0020,	// end a map
    FLD_IS_BIT_FIELD	= 0x0040,	// is bit field
    FLD_IS_ANONYMOUS    = 0x0080,       // is anonymous field
    FLD_IS_BASE_CLASS   = 0x0100,       // is a field of base class type
    FLD_IS_VIRTUAL      = 0x0200,       // is virutal (base class) field
};

struct FLD
{
    STR_IDX name_idx;

    mUINT64 ofst;			// offset within the struct in bytes

    mUINT8 bsize;			// bit field size in bits
    mUINT8 bofst;			// bit field offset starting at
					// byte specified by ofst
    mUINT16 flags;			// misc. attributes

    ST_IDX st;				// used if an st exists for this fld

    TY_IDX type;

    // operations

    FLD ();

    void Verify (UINT64 record_size) const;

    void Print (FILE *f) const;

}; // FLD


typedef TY_IDX TYLIST;			// for now, it's just a list of TY_IDX


// Give information about a dimension of an array.  The TY of the array type
// points to the ARB entry for the first dimension.  The remaining dimensions
// follow in consecutive ARB entries until a flag indicates it is the last
// dimension.
enum ARB_FLAGS
{
    ARB_CONST_LBND	= 0x0001,	// constant lower bound
    ARB_CONST_UBND	= 0x0002,	// constant upper bound
    ARB_CONST_STRIDE	= 0x0004,	// constant stride
    ARB_FIRST_DIMEN	= 0x0008,	// first dimension
    ARB_LAST_DIMEN	= 0x0010	// last dimension
};

struct ARB
{
    mUINT16 flags;			// misc. attributes
    mUINT16 dimension;			// number of dimensions

    mUINT32 unused;			// must be zero'ed

    union {
	mINT64 lbnd_val;		// constant lower bound value
	struct {
	    ST_IDX lbnd_var;		// variable that stores the
					// non-constant lower bound
	    mINT32 unused;		// filler, must be zero'ed
	} var;
    } u1;

    union {
	mINT64 ubnd_val;		// constant upper bound value
	struct {
	    ST_IDX ubnd_var;		// variable that stores the
					// non-constant upper bound
	    mINT32 unused;		// filler, must be zero'ed
	} var;
    } u2;

    union {
	mINT64 stride_val;		// constant stride
	struct {
	    ST_IDX stride_var;		// variable that stores the
					// non-constant stride
	    mINT32 unused;		// filler, must be zero'ed
	} var;
    } u3;

    // access functions
    INT64 Lbnd_val () const		{ return u1.lbnd_val; }
    void Set_lbnd_val (INT64 val)	{ u1.lbnd_val = val; }

    ST_IDX Lbnd_var () const		{ return u1.var.lbnd_var; }
    void Set_lbnd_var (ST_IDX st) {
	u1.var.lbnd_var = st;
	u1.var.unused = 0;
    }
    
    INT64 Ubnd_val () const		{ return u2.ubnd_val; }
    void Set_ubnd_val (INT64 val)	{ u2.ubnd_val = val; }

    ST_IDX Ubnd_var () const		{ return u2.var.ubnd_var; }
    void Set_ubnd_var (ST_IDX st) {
	u2.var.ubnd_var = st;
	u2.var.unused = 0;
    }
    
    INT64 Stride_val () const		{ return u3.stride_val; }
    void Set_stride_val (INT64 val)	{ u3.stride_val = val; }

    ST_IDX Stride_var () const		{ return u3.var.stride_var; }
    void Set_stride_var (ST_IDX st) {
	u3.var.stride_var = st;
	u3.var.unused = 0;
    }
    
	
    // operations

#ifdef really_call_bzero	// don't call bzero if it is poisoned
    ARB () { really_call_bzero (this, sizeof(ARB)); }
#else
    ARB () { BZERO (this, sizeof(ARB)); }
#endif

    void Verify (mUINT16 dim) const;
    
    void Print (FILE *f) const;

}; // ARB


enum LABEL_KIND
{
    LKIND_DEFAULT		= 0,
    LKIND_ASSIGNED		= 1,	// in ASSIGNED statement
    LKIND_BEGIN_EH_RANGE	= 2,
    LKIND_END_EH_RANGE		= 3,
    LKIND_BEGIN_HANDLER		= 4,
    LKIND_END_HANDLER		= 5,
    LKIND_TAG			= 6	// symbolic address, never branched to
};

enum LABEL_FLAGS
{
    LABEL_TARGET_OF_GOTO_OUTER_BLOCK	= 1,
    LABEL_ADDR_SAVED			= 2,
    LABEL_ADDR_PASSED			= 4
};

struct LABEL
{
    STR_IDX    name_idx;
    mUINT32    flags:24;
    LABEL_KIND kind:8;

    // operations
    
    LABEL () {Fail_FmtAssertion("LABEL default constructor must not be called.");}

    LABEL (STR_IDX idx, LABEL_KIND k) : name_idx (idx), kind (k) {}

    void Verify(UINT level) const;

    void Print (FILE *f) const;
}; // LABEL


struct PREG
{
    STR_IDX  name_idx;

    // operations
    PREG(void)
      {
	Fail_FmtAssertion("PREG default constructor must not be called.");
      }

    PREG (STR_IDX idx) : name_idx (idx) { }

    void Verify(UINT level) const;

    void Print (FILE *f) const;

}; // PREG


// misc. ST attributes
enum ST_ATTR_KIND
{
    ST_ATTR_UNKNOWN		= 0,
    ST_ATTR_DEDICATED_REGISTER	= 1,	// physical register number
    ST_ATTR_SECTION_NAME	= 2	// name of sections where defined.
};

class ST_ATTR
{
    public:
    ST_IDX st_idx;
    ST_ATTR_KIND kind;
    private:
    union {
	mUINT32 value;			// generic 32-bit value
	mPREG_NUM reg_id;
	STR_IDX section_name;
    } u;

    public:
    // operations
    ST_ATTR () {
	Fail_FmtAssertion("ST_ATTR default constructor must not be called.");
    }

    ST_ATTR (ST_IDX idx, ST_ATTR_KIND akind, UINT64 val) :
	st_idx (idx), kind (akind) {
	u.section_name = val;
    }

    // Access the union value
    void Set_u (UINT64 val) {
        u.section_name = val;
    }

    // Access reg_id
    void Set_reg_id (mPREG_NUM r) {
        u.reg_id = r;
    }

    mPREG_NUM Get_reg_id (void) const {
        return u.reg_id;
    }

    // Access section_name
    void Set_section_name (STR_IDX i) {
        u.section_name = i;
    }

    STR_IDX Get_section_name (void) const {
        return u.section_name;
    }
	    

    void Verify (UINT level) const;

    void Print (FILE* f) const;
}; // ST_ATTR



/* Kinds of types: */
enum TY_KIND
{
    KIND_INVALID	= 0,		// Invalid
    KIND_SCALAR		= 1,		// integer/floating point
    KIND_ARRAY		= 2,		// array
    KIND_STRUCT		= 3,		// struct/union
    KIND_POINTER	= 4,		// pointer
    KIND_FUNCTION	= 5,		// function/procedure
    KIND_VOID		= 6,		// C void type
    KIND_LAST		= 8
};


enum TY_FLAGS
{
    TY_IS_CHARACTER	= 0x0001,	/* type is a character (fortran) */
    TY_IS_LOGICAL	= 0x0002,	/* Type is logical (fortran) */
    TY_IS_UNION		= 0x0004,	/* Struct or class type is union */
    TY_IS_PACKED	= 0x0008,	/* Struct or class type is packed */
    TY_PTR_AS_ARRAY	= 0x0010,	/* Treat pointer as array */
    TY_ANONYMOUS	= 0x0020,	/* Anonymous structs/classes/unions */
    TY_SPLIT		= 0x0040,	/* Split from a larger common block
					 * equivalence (block_split) */
    TY_IS_F90_POINTER	= 0x0080,	/* If the type is an F90 pointer */
    TY_NOT_IN_UNION	= 0x0100,	/* If the type cannot be part of a union */
    TY_NO_ANSI_ALIAS	= 0x0200,	// ANSI alias rules don't applied
    TY_IS_NON_POD	= 0x0400,	// type is non pod (for C++ classes)
#ifdef KEY
    TY_RETURN_IN_MEM	= 0x0800,	// Functions must return objects of this
					// type in memory.
    TY_CONTENT_SEEN	= 0x1000,	// for differentiating between a 0-sized
    					// struct and its forward declaration;
					// used by wgen
    TY_IS_INCOMPLETE    = 0x2000,       // Type is incomplete, used by wgen to
                                        // mark VLA types when used as function
                                        // arguments.
    TY_NO_SPLIT         = 0x4000,       // May be used by any phase after
                                        // front-end for TY that should not
                                        // be split.
#endif
#ifdef TARG_NVISA
    TY_CAN_BE_VECTOR	= 0x8000,	// vector type like int4
#endif
    TY_COMPLETE_STRUCT_RELAYOUT_CANDIDATE = 0x0001, // it's OK to share this
      // with TY_IS_CHARACTER above for now, since this has to be a struct
};


// TY flags that are valid only for KIND_FUNCTION
enum TY_PU_FLAGS
{
    TY_RETURN_TO_PARAM	= 0x00000001,	// return value through first param
    TY_IS_VARARGS	= 0x00000002,	// variable number of arguments
    TY_HAS_PROTOTYPE	= 0x00000004,	// has ansi-style prototype
#ifdef TARG_X8664
    TY_HAS_SSEREG_PARM	= 0x00000008,	// SSE register parameters under i386
    TY_HAS_1_REG_PARM	= 0x00000010,	// 1 register parameter under i386
    TY_HAS_2_REG_PARM	= 0x00000020,	// 2 register parameters under i386
    TY_HAS_3_REG_PARM	= 0x00000030,	// 3 register parameters under i386
    TY_HAS_STDCALL      = 0x00000040,   // stdcall calling convention under i386
    TY_HAS_FASTCALL     = 0x00000080    // fastcall calling convention under i386
#endif
};

class TY
{
public:
    mUINT64 size;			// size of the type in bytes

    TY_KIND kind : 8;			// kind of type
    mTYPE_ID mtype : 8;			// WHIRL data type
    mUINT16 flags;			// misc. attributes

    union {
	FLD_IDX fld;
	TYLIST_IDX tylist;
	ARB_IDX arb;
    } u1;				// idx to FLD_TAB, TYLIST_TAB, etc.

    STR_IDX name_idx;			// name 

    union {
	TY_IDX etype;			// type of array element (array only)
	TY_IDX pointed;			// pointed-to type (pointers only)
	mUINT32 pu_flags;		// attributes for KIND_FUNCTION
#ifdef KEY
	ST_IDX copy_constructor;	// copy constructor X(X&) (record only)
#endif
    } u2;
	
    ST_IDX vtable;

    // access function for unions

    FLD_IDX Fld () const		{ return u1.fld; }
    void Set_fld (FLD_IDX idx)		{ u1.fld = idx; }
    
    TYLIST_IDX Tylist () const		{ return u1.tylist; }
    void Set_tylist (TYLIST_IDX idx)	{ u1.tylist = idx; }
    
    ARB_IDX Arb () const		{ return u1.arb; }
    void Set_arb (ARB_IDX idx)		{ u1.arb = idx; }

    TY_IDX Etype () const
      {
	Is_True(kind == KIND_ARRAY,
		("non-KIND_ARRAY type has no element type"));
	return u2.etype;
      }
    void Set_etype (TY_IDX idx)		{ u2.etype = idx; }
    
    TY_IDX Pointed () const
      {
	Is_True(kind == KIND_POINTER,
		("non-KIND_POINTER type doesn't point"));
	return u2.pointed;
      }
    void Set_pointed (TY_IDX idx)	{ u2.pointed = idx; }

#ifdef KEY
    ST_IDX Copy_constructor () const
      {
	Is_True(kind == KIND_STRUCT,
		("non-KIND_STRUCT type has no copy constructor"));
	return u2.copy_constructor;
      }
    void Set_copy_constructor (ST_IDX idx)	{ u2.copy_constructor = idx; }
#endif	// KEY

    ST_IDX Vtable () const
      {
	Is_True(kind == KIND_STRUCT,
		("non-KIND_STRUCT type has no vtable"));
	return vtable;
      }
    void Set_vtable (ST_IDX idx)	{ vtable = idx; }


    PU_IDX Pu_flags () const		{ return u2.pu_flags; }
    void Set_pu_flag (TY_PU_FLAGS f)	{ u2.pu_flags |= f; }
    void Clear_pu_flag (TY_PU_FLAGS f)	{ u2.pu_flags &= ~f; }

    // operations

    TY ();

    void Verify(UINT level) const;

    void Print (FILE *f) const;

}; // TY


// PU_FLAGS: cannot use enum as some of the the values are > max unsigned int

#define	PU_IS_PURE		0x00000001	// pure function
#define	PU_NO_SIDE_EFFECTS	0x00000002	// no side effect
#define	PU_IS_INLINE_FUNCTION	0x00000004	// inline keyword specified
#define	PU_NO_INLINE		0x00000008	// noinline pragma specified
#define	PU_MUST_INLINE		0x00000010	// must inline
#define	PU_NO_DELETE		0x00000020	// nodelete pragma specified
#define	PU_HAS_EXC_SCOPES	0x00000040	// has eh regions, or would have
						// if exceptions were enabled
#define	PU_IS_NESTED_FUNC	0x00000080	// is a nested function
#define	PU_HAS_NON_MANGLED_CALL	0x00000100	// PU has a call in which no
					 	// reshaped arrays are passed
#define	PU_ARGS_ALIASED		0x00000200	// f77 arguments are aliased
#define	PU_NEEDS_FILL_ALIGN_LOWERING 0x00000400	// needs fill/align lowering
#define	PU_NEEDS_T9		0x00000800	// needs T9
#define	PU_HAS_VERY_HIGH_WHIRL	0x00001000	// PU has very high whirl in it
#define	PU_HAS_ALTENTRY		0x00002000	// PU has alternate entries
#define	PU_RECURSIVE		0x00004000	// in recursive path
#define	PU_IS_MAINPU		0x00008000	// is entry point of program
#define	PU_UPLEVEL		0x00010000	// Other PU nested in this one
#define	PU_MP_NEEDS_LNO		0x00020000	// PU needs LNO processing
#define	PU_HAS_ALLOCA		0x00040000	// PU has alloca in it
#define	PU_IN_ELF_SECTION	0x00080000	// PU is in its own Elf section
#define	PU_HAS_MP		0x00100000	// Symtab has MP region/do within it
#define	PU_MP			0x00200000	// PU is an MP region/do
#define	PU_HAS_NAMELIST		0x00400000	// PU has namelist
#define	PU_HAS_RETURN_ADDRESS	0x00800000	// __return_address was used
#define	PU_HAS_REGION		0x01000000	// PU has regions in it
#define	PU_HAS_INLINES		0x02000000	// PU has inlined code in it
#define	PU_CALLS_SETJMP		0x04000000	// PU has calls to setjmp(2)
#define	PU_CALLS_LONGJMP	0x08000000	// PU has calls to longjmp(2)
#define PU_IPA_ADDR_ANALYSIS    0x10000000      // IPA has done address analysis
#define PU_SMART_ADDR_ANALYSIS  0x20000000      // Unnecessary addr flags are reset

#define	PU_HAS_SYSCALL_LINKAGE	0x40000000	// preserve input regs
#define PU_HAS_GLOBAL_PRAGMAS	0x80000000	// PU is a dummy pu with global
						//   pragmas
#define	PU_HAS_USER_ALLOCA	0x0000000100000000LL
						// PU has user alloca in it
#define	PU_HAS_UNKNOWN_CONTROL_FLOW \
                          	0x0000000200000000LL
						// PU has unknown control flow
						//  which disables tail call 
						// optimization
#define PU_IS_THUNK		0x0000000400000000LL // pu is a C++ thunk

#ifdef KEY
#define PU_NEEDS_MANUAL_UNWINDING \
                                0x0000000800000000LL // PU has cleanups in outermost scope and hence needs to call _Unwind_Resume itself
#endif

#ifdef TARG_X8664
#define PU_FF2C_ABI		0x0000001000000000LL // PU use g77 linkage convention for returns of complex and float
#endif

#ifdef KEY
#define PU_IS_EXTERN_INLINE	0x0000002000000000LL // PU is marked extern _inline_ in C
#define PU_MP_LOWER_GENERATED   0x0000004000000000LL // PU generated by mp-lowerer
#define PU_IS_MARKED_INLINE     0x0000008000000000LL
                                                   // C/C++: inline keyword used. Note
                                                   // PU_IS_INLINE_FUNCTION just
                                                   // indicates GNU inlining decision.
#define PU_NO_INSTRUMENT        0x0000010000000000LL // -finstrument-functions will skip PU
#endif

#define PU_HAS_ATTR_MALLOC      0x0000020000000000LL // __attribute__((malloc)) semantic 
#define PU_HAS_ATTR_PURE        0x0000040000000000LL // __attribute__((pure)) semantic 
#define PU_HAS_ATTR_NORETURN    0x0000080000000000LL // __attribute__((noreturn)) semantic
#define PU_IS_CONSTRUCTOR       0x0000100000000000LL  // PU is a constructor of a class
#define PU_IS_OPERATOR          0x0000200000000000LL // PU is overload of operator

#define PU_NEED_TRAMPOLINE      0x0000400000000000LL // a nested function whose address is taken
#define PU_HAS_NONLOCAL_GOTO_LABEL	\
                                0x0000800000000000LL // has a label jumped to directly from a nested function
#define PU_HAS_GOTO_OUTER_BLOCK	0x0001000000000000LL // has GOTO_OUTER_BLOCK stmt
#define PU_IS_CDECL             0x0002000000000000LL // __attribute__((cdecl)) semantic
#define PU_NOTHROW              0x0004000000000000LL // doesn't throw, e.g. decl as "void foo() throw()".
#define PU_HAS_APPLY_ARGS       0x0008000000000000LL // __builtin_apply_args
#define PU_SIMPLE_EH_RANGE      0x0010000000000000LL // there is a single eh range in PU, no clean-up or catch

enum PU_SRC_LANG_FLAGS
{
    PU_UNKNOWN_LANG	= 0x00,	// UNKNOWN 
    PU_MIXED_LANG	= 0x01,	// MIXED
    PU_C_LANG		= 0x02,	// C
    PU_CXX_LANG		= 0x04,	// C++
    PU_F77_LANG		= 0x08,	// F77
    PU_F90_LANG		= 0x10,	// F90
    PU_JAVA_LANG	= 0x20	// JAVA
};

struct PU
{
    TARGET_INFO_IDX target_idx;		// idx to table for target-specific 
					// information

    TY_IDX prototype;			// function prototype
    TY_IDX base_class;                  // the class type which this PU belongs to if this PU is a member function
    SYMTAB_IDX lexical_level;		// lexical level (of nested proc). 8-bits
    INITO_IDX misc;		        // store misc such EH related TYPE/TYPE_SPEC info. 32bits
#ifdef TARG_NVISA
    mUINT16 thread_limit;
    mUINT16 block_limit;
#endif
    mUINT8 gp_group;			// gp_group id
    mUINT8 src_lang;			// source language
    mUINT8 unused : 8;		        // for alignment 
    mUINT64 flags;			// misc. attributes about this func.

    // operations

    PU ();

    void Verify(UINT level) const;

    void Print (FILE *f) const;

}; // PU


// BLK only exists for CLASS_BLOCK.
// It is used for data layout in be.
// Only reason it is not local to be is that
// the IPA global symbol table will need the info.
class BLK
{
private:

	mUINT64 size;		// size of the block
	mUINT16 align;		// alignment of the block: 1,2,4,8
	mUINT16 flags;		// block flags
	mUINT16 section_idx;	// section index (0 if not a section)
	mUINT16 scninfo_idx;	// scninfo_idx (0 if not a section)

public:

	BLK () : size (0), section_idx(0), scninfo_idx(0), flags (0) {}

#ifdef really_call_bzero	// don't call bzero if it is poisoned
	void Init (void)	{ really_call_bzero (this, sizeof(BLK)); }
#else
	void Init (void)	{ BZERO (this, sizeof(BLK)); }
#endif

public:

    // access functions

    UINT64 Size () const	{ return size; }
    void Set_size (UINT64 s)	{ size = s; }

    UINT16 Align () const	{ return align; }
    void Set_align (UINT16 s)	{ align = s; }

    UINT16 Section_idx () const	{ return section_idx; }
    void Set_section_idx (UINT16 s)	{ section_idx = s; }
    UINT16 Scninfo_idx () const	{ return scninfo_idx; }
    void Set_scninfo_idx (UINT16 s)	{ scninfo_idx = s; }

    UINT16 Flags () const		{ return flags; }
    BOOL Is_set (UINT16 f) const	{ return flags & f; }
    void Set_flags (UINT16 f)		{ flags |= f; }
    void Clear_flags (UINT16 f)		{ flags &= ~f; }
    void Clear_all_flags ()		{ flags = 0; }

    void Print (FILE *f) const;
}; // BLK

// BLK flags
#define BLK_SECTION		0x0001 // block for elf section
#define BLK_ROOT_BASE		0x0002 // block should not be merged
#define BLK_IS_BASEREG		0x0004 // block that maps into reg
#define BLK_DECREMENT		0x0008 // grow block by decrementing
#define BLK_EXEC		0x0010 // (ELF) executable instructions
#define BLK_NOBITS		0x0020 // (ELF) occupies no space in file
#define BLK_MERGE		0x0040 // (ELF) merge duplicates in ld
#define BLK_COMPILER_LAYOUT	0x0080 // children symbols are not connected


// place holder for misc. file-level info

enum FILE_INFO_FLAGS
{
    FI_IPA		= 0x1,		// IPA generated file
    FI_NEEDS_LNO	= 0x2,		// needs to run LNO
    FI_HAS_INLINES	= 0x4,		// some PUs have PU_HAS_INLINES set
    FI_HAS_MP   	= 0x8		// need to process MP constructs
};

struct FILE_INFO
{
    mUINT32 flags;			// misc. attributes
    mUINT8 gp_group;			// gp group id
    mUINT32 unused : 24;		// filler, must be zero

    void Verify() const;
    void Print (FILE *f) const;
    FILE_INFO () : flags (0), gp_group (0), unused (0) {}

};


// Type definitions of the symbol tables

typedef SEGMENTED_ARRAY<PU>	PU_TAB;
typedef RELATED_SEGMENTED_ARRAY<ST>	ST_TAB;
typedef SEGMENTED_ARRAY<TY>	TY_TAB;
typedef SEGMENTED_ARRAY<FLD>	FLD_TAB;
typedef SEGMENTED_ARRAY<TYLIST>	TYLIST_TAB;
typedef SEGMENTED_ARRAY<ARB>	ARB_TAB;
typedef RELATED_SEGMENTED_ARRAY<LABEL>	LABEL_TAB;
typedef RELATED_SEGMENTED_ARRAY<PREG>	PREG_TAB;
typedef SEGMENTED_ARRAY<ST_ATTR>	ST_ATTR_TAB;
typedef SEGMENTED_ARRAY<BLK>	BLK_TAB;
typedef SEGMENTED_ARRAY<TCON,64> TCON_TAB;
typedef SEGMENTED_ARRAY<INITO>	INITO_TAB;
typedef SEGMENTED_ARRAY<INITV>	INITV_TAB;

typedef PU_TAB::iterator	PU_ITER;
typedef ST_TAB::iterator	ST_ITER;
typedef TY_TAB::iterator	TY_ITER;
typedef FLD_TAB::iterator	FLD_ITER;
typedef TYLIST_TAB::iterator	TYLIST_ITER;
typedef ARB_TAB::iterator	ARB_ITER;
typedef LABEL_TAB::iterator	LABEL_ITER;
typedef PREG_TAB::iterator	PREG_ITER;
typedef ST_ATTR_TAB::iterator	ST_ATTR_ITER;
typedef BLK_TAB::iterator	BLK_ITER;
typedef TCON_TAB::iterator	TCON_ITER;
typedef INITO_TAB::iterator	INITO_ITER;
typedef INITV_TAB::iterator	INITV_ITER;


struct SCOPE
{
    MEM_POOL *pool;			// mem pool for local tables
    ST* st;				// ST * for the current pu
    ST_TAB *st_tab;
    LABEL_TAB *label_tab;
    PREG_TAB *preg_tab;
    INITO_TAB *inito_tab;
    ST_ATTR_TAB *st_attr_tab;

    void Init (ST_TAB *s) {
	// for global symtab
	pool = NULL;
	st_tab = s;
	st = NULL;
	label_tab = NULL;
	preg_tab = NULL;
	inito_tab = NULL;
	st_attr_tab = NULL;
    }

    void Init (ST_TAB *s, LABEL_TAB *l, PREG_TAB *p, INITO_TAB *io,
	       ST_ATTR_TAB* d, MEM_POOL *mp = Malloc_Mem_Pool) {
	pool = mp;
	st = NULL;
	st_tab = s;
	label_tab = l;
	preg_tab = p;
	inito_tab = io;
	st_attr_tab = d;
	
    }
    

}; // SCOPE

// predefined Scope indices
#define GLOBAL_SYMTAB		(1)	// file scope global symtab
#define CURRENT_SYMTAB		(Current_scope)

struct SCOPE_TAB_SYMTAB_ACCESS {
  SCOPE_TAB_SYMTAB_ACCESS(void) { }

  ST_TAB *operator()(SCOPE **scope_tab, SYMTAB_IDX level)
    { return (*scope_tab)[level].st_tab; }
};

struct SCOPE_TAB_INITO_ACCESS {
  SCOPE_TAB_INITO_ACCESS(void) { }

  INITO_TAB *operator()(SCOPE **scope_tab, SYMTAB_IDX level)
    { return (*scope_tab)[level].inito_tab; }
};

struct SCOPE_TAB_LABEL_ACCESS {
  SCOPE_TAB_LABEL_ACCESS(void) { }

  LABEL_TAB *operator()(SCOPE **scope_tab, SYMTAB_IDX level)
    { return (*scope_tab)[level].label_tab; }
};

// The global scope table
extern SCOPE		*Scope_tab;

// One instance of the following class per compilation.
typedef TABLE_INDEXED_BY_LEVEL8_AND_INDEX24<ST, ST_IDX, SYMTAB_IDX,
                                            SCOPE *, &Scope_tab,
					    SCOPE_TAB_SYMTAB_ACCESS>
        SYMBOL_TABLE;

typedef TABLE_INDEXED_BY_LEVEL8_AND_INDEX24<INITO, INITO_IDX, SYMTAB_IDX,
                                            SCOPE *, &Scope_tab,
					    SCOPE_TAB_INITO_ACCESS>
        INITO_TABLE;

typedef TABLE_INDEXED_BY_LEVEL8_AND_INDEX24<LABEL, LABEL_IDX, SYMTAB_IDX,
                                            SCOPE *, &Scope_tab,
					    SCOPE_TAB_LABEL_ACCESS>
        LABEL_TABLE;

struct PREG_TABLE
{
  inline PREG& operator[] (PREG_IDX idx);
  inline PREG& operator() (SYMTAB_IDX level, PREG_IDX idx);
};

struct ST_ATTR_TABLE
{
  inline ST_ATTR& operator[] (ST_ATTR_IDX idx);
  inline ST_ATTR& operator() (SYMTAB_IDX level, ST_ATTR_IDX idx);
};

struct TYPE_TABLE
{
  inline TY& operator[] (TY_IDX idx);
  inline TY_TAB* operator& ();
};

// declaration of global tables
extern FILE_INFO	File_info;
extern PU_TAB		Pu_Table;
extern SYMBOL_TABLE	St_Table;
extern TY_TAB		Ty_tab;
extern TYPE_TABLE	Ty_Table;
extern FLD_TAB		Fld_Table;
extern TYLIST_TAB	Tylist_Table;
extern ARB_TAB		Arb_Table;
extern STRING_TABLE     Str_Table;
extern TCON_TAB		Tcon_Table;
extern INITV_TAB	Initv_Table;
extern INITO_TABLE	Inito_Table;
extern PREG_TABLE	Preg_Table;
extern ST_ATTR_TABLE	St_Attr_Table;
extern LABEL_TABLE	Label_Table;
// some BLK_TAB items are really local, but make global to ease management
extern BLK_TAB		Blk_Table;

// global variables

extern SYMTAB_IDX Current_scope;
extern PU* Current_pu;




// headers that describe the layout of the symtab structures in files
// changing any of these requires incrementing the WHIRL revision number

// symbol table header types
enum SHDR_TYPE
{
    SHDR_UNK	= 0,			// uninitialized
    SHDR_FILE	= 1,
    SHDR_ST	= 2,
    SHDR_TY	= 3,
    SHDR_PU	= 4,
    SHDR_FLD	= 5,
    SHDR_ARB	= 6,
    SHDR_TYLIST	= 7,
    SHDR_TCON	= 8,
    SHDR_STR	= 9,
    SHDR_LABEL	= 10,
    SHDR_PREG	= 11,
    SHDR_INITO	= 12,
    SHDR_INITV	= 13,
    SHDR_BLK 	= 14,
    SHDR_ST_ATTR= 15
}; // SHDR_TYPE


struct SYMTAB_HEADER
{
    mUINT64 offset;			// offset from beginning of section
    mUINT64 size;			// size in bytes
    mUINT32 entsize;			// size of each entry if fixed
					// zero if entry size variable
    mUINT16 align;			// alignment
    mUINT16 type;			// type of table

    void Init (UINT64 _offset, UINT64 _size, UINT32 _entsize,
	       UINT16 _align, SHDR_TYPE _type) {
	offset = _offset;
	size = _size;
	entsize = _entsize;
	align = _align;
	type = _type;
    }
    
}; // SYMTAB_HEADER


#define GLOBAL_SYMTAB_TABLES	(13)	// # of tables in global symtab:
					// FILE_INFO, ST, TY, PU, FLD, ARB,
					// TYLIST, TCON, STR, INITO, INITV,
					// BLK, and ST_ATTR
#define LOCAL_SYMTAB_TABLES	(5)	// # of tables in local symtab:
					// ST, LABEL, PREG, INITO, and ST_ATTR

template <UINT table_size>
struct SYMTAB_HEADER_TABLE
{
    mUINT32 size;			// size of myself in bytes
    mUINT32 entries;			// number of SYMTAB_HEADER entries

    SYMTAB_HEADER header[table_size];

    typedef SYMTAB_HEADER_TABLE<table_size> self;

    SYMTAB_HEADER_TABLE () {
	size = sizeof(self);
	entries = table_size;
#ifdef really_call_bzero	// don't call bzero if it is poisoned
	really_call_bzero (header, sizeof(header));
#else
	BZERO (header, sizeof(header));
#endif
    }

}; // SYMTAB_HEADER_TABLE

typedef SYMTAB_HEADER_TABLE<GLOBAL_SYMTAB_TABLES> GLOBAL_SYMTAB_HEADER_TABLE;
typedef SYMTAB_HEADER_TABLE<LOCAL_SYMTAB_TABLES> LOCAL_SYMTAB_HEADER_TABLE;

#endif /* symtab_defs_INCLUDED */

------------------------------------------------------------------------------
EMC VNX: the world's simplest storage, starting under $10K
The only unified storage solution that offers unified management 
Up to 160% more powerful than alternatives and 25% more efficient. 
Guaranteed. http://p.sf.net/sfu/emc-vnx-dev2dev
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to