/* ** symbols basic types ** if the values are changed check : init'd arrays in globals.c */ #define BTundef 0 #define BTchar 1 #define BTshort 2 #define BTint 3 #define BTlong 4 #define BTenumuse 5 #define BTfloat 6 #define BTdouble 7 #define BTldouble 8 #define BTseg 9 #define BTBASIC 9 /* used elsewhere to indicate the last basic type */ #define BTvoid 10 #define BTenum 11 #define BTstruct 12 #define BTunion 13 #define BTstuse 14 #define BTunuse 15 #define BT_MASK 0x0f /* basic type mask */ /* ** the following are also used in indirection strings as modifiers ** to the basic indirections. ** NOTE THIS DOESN'T really work for C600, but for just one case. ** if a typedef has 'near' on it, 'consolidate_types' will consider ** it to be a 'signed' bit, and remove it, thus, near never gets ** added to whatever the typedef is used on. */ #define BT_UNSIGNED 0x0010 /* unsigned keyword used */ #define BT_SIGNED 0x0020 /* signed keyword used */ #define SU_MASK 0x0030 /* signed/unsigned mask */ #define BT_NEAR 0x0040 /* near keyword used */ #define BT_FAR 0x0080 /* far keyword used */ #define BT_HUGE 0x00c0 /* huge keyword used */ #define NFH_MASK 0x00c0 /* near/far/huge mask */ #define BT_INTERRUPT 0x0100 /* interrupt seen */ #define BT_SAVEREGS 0x0200 /* dynalink seen */ #define BT_EXPORT 0x0400 /* export seen */ #define BT_LOADDS 0x0800 /* loadds seen */ #define CODEMOD_MASK 0x0f00 /* code modifiers */ #define BT_CONST 0x1000 /* constant keyword used */ #define BT_VOLATILE 0x2000 /* volatile keyword used */ #define CV_MASK 0x3000 /* const/volatile mask */ #define BT_CDECL 0x4000 /* cdecl keyword used */ #define BT_FORTRAN 0x8000 /* fortran keyword used */ #define BT_PASCAL 0xc000 /* pascal keyword used */ #define LANGUAGE_MASK 0xc000 /* cdecl/fortran/pascal mask */ #define MODIFIER_MASK (NFH_MASK | LANGUAGE_MASK | CODEMOD_MASK | CV_MASK) #define ALL_MODIFIERS (MODIFIER_MASK | SU_MASK) /* ** macros for getting/setting basic type information ** Q_* to query the flag. ** S_* to set the flag. ** the Q_near/far/huge things are defined later, and are called IS_*. */ #define IS_BTBASIC(P) ((P) <= BTBASIC) #define IS_BTINTEGRAL(P) ((P) <= BTenumuse) #define IS_BTFLOAT(P) ((BTfloat <= (P)) && ((P) <= BTldouble)) #define IS_BTVOID(P) ((P) == BTvoid) #define IS_BASIC(P) (IS_BTBASIC(Q_BTYPE(P))) #define IS_INTEGRAL(P) (IS_BTINTEGRAL(Q_BTYPE(P))) #define IS_FLOAT(P) (IS_BTFLOAT(Q_BTYPE(P))) #define IS_VOID(P) (IS_BTVOID(Q_BTYPE(P))) #define IS_MULTIBYTE(P) ((BTstruct <= (P)) && ((P) <= BTunuse)) #define IS_UNSIGNED(P) ((P) & BT_UNSIGNED) #define IS_SIGNED(P) ((P) & BT_SIGNED) #define CLR_SIGNED(P) ((P) &= ~BT_SIGNED) #define S_UNSIGNED(P) ((P) |= BT_UNSIGNED) #define S_SIGNED(P) ((P) |= BT_SIGNED) #define S_CONST(P) ((P) |= BT_CONST) #define S_VOLATILE(P) ((P) |= BT_VOLATILE) #define S_NEAR(P) ((P) |= BT_NEAR) #define S_FAR(P) ((P) |= BT_FAR) #define S_HUGE(P) ((P) |= BT_HUGE) #define S_CDECL(P) ((P) |= BT_CDECL) #define S_FORTRAN(P) ((P) |= BT_FORTRAN) #define S_PASCAL(P) ((P) |= BT_PASCAL) #define S_INTERRUPT(P) ((P) |= BT_INTERRUPT) #define S_SAVEREGS(P) ((P) |= BT_SAVEREGS) #define Q_BTYPE(P) ((P) & ( BT_MASK )) #define S_BTYPE(P,V) ((P) = (((P) & ( ~ BT_MASK )) | V)) struct s_flist { /* formal parameter list of types */ ptype_t fl_type; /* type of formal */ pflist_t fl_next; /* next one */ }; #define FL_NEXT(P) ((P)->fl_next) #define FL_TYPE(P) ((P)->fl_type) union u_ivalue { abnd_t ind_subscr; /* array subscript size */ psym_t ind_formals; /* formal symbol list */ pflist_t ind_flist; /* formal type list */ psym_t ind_basesym; /* segment we're based on */ ptype_t ind_basetype; /* type we're based on */ phln_t ind_baseid; /* id we're based on */ }; #define PIVALUE_ISUB(P) ((P)->ind_subscr) #define PIVALUE_IFORMALS(P) ((P)->ind_formals) #define PIVALUE_IFLIST(P) ((P)->ind_flist) #define PIVALUE_BASEDSYM(P) ((P)->ind_basesym) #define PIVALUE_BASEDTYPE(P) ((P)->ind_basetype) #define PIVALUE_BASEDID(P) ((P)->ind_baseid) #define IVALUE_ISUB(P) (PIVALUE_ISUB(&(P))) #define IVALUE_IFORMALS(P) (PIVALUE_IFORMALS(&(P))) #define IVALUE_IFLIST(P) (PIVALUE_IFLIST(&(P))) #define IVALUE_BASEDSYM(P) (PIVALUE_BASEDSYM(&(P))) #define IVALUE_BASEDTYPE(P) (PIVALUE_BASEDTYPE(&(P))) #define IVALUE_BASEDID(P) (PIVALUE_BASEDID(&(P))) struct s_indir { btype_t ind_type; /* what kind ? */ pindir_t ind_next; /* next one */ ivalue_t ind_info; /* subscript/function's params */ }; #define INDIR_INEXT(P) ((P)->ind_next) #define INDIR_ITYPE(P) ((P)->ind_type) #define INDIR_INFO(P) ((P)->ind_info) #define INDIR_ISUB(P) (IVALUE_ISUB(INDIR_INFO(P))) #define INDIR_IFORMALS(P) (IVALUE_IFORMALS(INDIR_INFO(P))) #define INDIR_IFLIST(P) (IVALUE_IFLIST(INDIR_INFO(P))) #define INDIR_BASEDSYM(P) (IVALUE_BASEDSYM(INDIR_INFO(P))) #define INDIR_BASEDTYPE(P) (IVALUE_BASEDTYPE(INDIR_INFO(P))) #define INDIR_BASEDID(P) (IVALUE_BASEDID(INDIR_INFO(P))) /* ** optimal choices for these things. ** however, everyone uses macros to test them, so if i'm wrong, ** it should be easy to change the values, but think well !!! */ #define IN_FUNC 0x00 #define IN_PFUNC 0x01 #define IN_ARRAY 0x02 #define IN_PDATA 0x03 #define IN_VOIDLIST 0x04 #define IN_VARARGS 0x08 #define IN_MASK (IN_ARRAY | IN_PDATA | IN_PFUNC | IN_FUNC) #define IN_ADDRESS (IN_ARRAY | IN_PDATA | IN_PFUNC) #define IN_DATA_ADDRESS (IN_ARRAY & IN_PDATA) /* yes, i meant '&' */ #define IN_POINTER (IN_PFUNC & IN_PDATA) /* yes, i meant '&' */ #if IN_DATA_ADDRESS == 0 #error IN_DATA_ADDRESS is ZERO #endif #if IN_POINTER == 0 #error IN_POINTER is ZERO #endif #define IS_ARRAY(I) (((I) & IN_MASK) == IN_ARRAY) #define IS_PDATA(I) (((I) & IN_MASK) == IN_PDATA) #define IS_PFUNC(I) (((I) & IN_MASK) == IN_PFUNC) #define IS_FUNC(I) (((I) & IN_MASK) == IN_FUNC) #define IS_EXTRACT(I) ((I) & IN_POINTER) #define IS_DATA_ADDRESS(I) ((I) & IN_DATA_ADDRESS) #define IS_ADDRESS(I) ((I) & IN_ADDRESS) #define IS_INDIR(I) ((I) & IN_MASK) #define MASK_INDIR(I) ((I) & IN_MASK) #define IS_VOIDLIST(I) ((I) & IN_VOIDLIST) #define IS_VARARGS(I) ((I) & IN_VARARGS) #define IS_NFH(I) ((I) & NFH_MASK) #define IS_NEARNFH(I) ((I) == BT_NEAR) #define IS_FARNFH(I) ((I) == BT_FAR) #define IS_HUGENFH(I) ((I) == BT_HUGE) #define IS_BASEDNFH(I) ((I) >= BT_BASED) #define IS_BASEDSELFNFH(I) ((I) == BT_BASEDSELF) #define IS_BASEDIDNFH(I) ((I) == BT_BASEDID) #define IS_BASEDSYMNFH(I) ((I) == BT_BASEDSYM) #define IS_BASEDTYPENFH(I) ((I) == BT_BASEDTYPE) #define IS_NEAR(I) (IS_NEARNFH(IS_NFH(I))) #define IS_FAR(I) (IS_FARNFH(IS_NFH(I))) #define IS_HUGE(I) (IS_HUGENFH(IS_NFH(I))) #define IS_BASED(I) (IS_BASEDNFH(IS_NFH(I))) #define IS_BASEDSELF(I) (IS_BASEDSELFNFH(IS_NFH(I))) #define IS_BASEDID(I) (IS_BASEDIDNFH(IS_NFH(I))) #define IS_BASEDSYM(I) (IS_BASEDSYMNFH(IS_NFH(I))) #define IS_BASEDTYPE(I) (IS_BASEDTYPENFH(IS_NFH(I))) #define IS_INTERRUPT(I) ((I) & BT_INTERRUPT) #define IS_SAVEREGS(I) ((I) & BT_SAVEREGS) #define IS_EXPORT(I) ((I) & BT_EXPORT) #define IS_LOADDS(I) ((I) & BT_LOADDS) #define IS_CODEMOD(I) ((I) & CODEMOD_MASK) #define IS_CONST(I) ((I) & BT_CONST) #define IS_VOLATILE(I) ((I) & BT_VOLATILE) #define IS_MODIFIED(I) ((I) & (MODIFIER_MASK)) #define ANY_MODIFIER(I) ((I) & (ALL_MODIFIERS)) #define INTERF(I) (MASK_INDIR(I) + (((I) & NFH_MASK) > 4)) #define S_ITYPE(I,V) ((I) = ((I) & ( ~ IN_MASK )) | (V)) #define S_INFH(I,V) ((I) = ((I) & ( ~ NFH_MASK )) | (V)) /* ** type info for symbols */ struct s_type { btype_t ty_bt; /* base type specifiers */ pindir_t ty_indir; /* indirection string */ p1key_t ty_dtype; /* derived type */ psym_t ty_esu; /* enum/structure/union/static defining type */ USHORT ty_index; /* unique index of type for debugger */ }; /* ** help getting type info. P is pointer to TYPE (struct s_type). ** TYPE contains the basic type, adjectives and an optional pointer ** to a symbol which is an enumeration, structure, union which is the type ** of this TYPE. */ #define TY_BTYPE(P) ((P)->ty_bt) /* basic type */ #define TY_DTYPE(P) ((P)->ty_dtype) /* derived type */ #define TY_ESU(P) ((P)->ty_esu) /* ptr to parent enum/struct/union */ #define TY_INDIR(P) ((P)->ty_indir) /* indirection string */ #define TY_TINDEX(P) ((P)->ty_index) /* type index */ #define TY_INEXT(P) (INDIR_INEXT(TY_INDIR(P))) #define TY_ITYPE(P) (INDIR_ITYPE(TY_INDIR(P))) #define TY_ISUB(P) (INDIR_ISUB(TY_INDIR(P))) #define TY_IFORMALS(P) (INDIR_IFORMALS(TY_INDIR(P))) #define TY_IFLIST(P) (INDIR_IFLIST(TY_INDIR(P))) typedef struct s_indir_entry indir_entry_t; typedef struct s_type_entry type_entry_t; struct s_indir_entry { indir_entry_t *ind_next; indir_t ind_type; }; struct s_type_entry { type_entry_t *te_next; type_t te_type; }; #define TYPE_TABLE_SIZE 0x100 #define INDIR_TABLE_SIZE 0x040 /* ** HASH_MASK : is a value which consists of the bits in common ** between upper and lower case. we mask each char we read with this ** to sum them for a hash value. we do this so that all names consisting ** of the same chars (case insensitive), will hash to the same location. */ #define HASH_MASK 0x5f #define DATASEGMENT 0 #define TEXTSEGMENT 1