diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /src/SDCCsymt.h | |
| download | sdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz | |
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'src/SDCCsymt.h')
| -rw-r--r-- | src/SDCCsymt.h | 734 |
1 files changed, 734 insertions, 0 deletions
diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h new file mode 100644 index 0000000..4b5b74e --- /dev/null +++ b/src/SDCCsymt.h @@ -0,0 +1,734 @@ +/*------------------------------------------------------------------------- + SDCCsymt.h - Header file for Symbols table related structures and MACRO's. + + Copyright (C) 1998 Sandeep Dutta . sandeep.dutta@usa.net + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +-------------------------------------------------------------------------*/ + +#ifndef SDCCSYMT_H +#define SDCCSYMT_H + +#define MAX_NEST_LEVEL 256 +#define SDCC_SYMNAME_MAX 64 +#define SDCC_NAME_MAX 3*SDCC_SYMNAME_MAX // big enough for _<func>_<var>_etc +#include "SDCChasht.h" +#include "SDCCglobl.h" +#include "dbuf.h" + +#define INTNO_MAX 255 /* maximum allowed interrupt number */ +#define INTNO_TRAP INTNO_MAX +#define INTNO_UNSPEC (INTNO_MAX+1) /* interrupt number unspecified */ + + +#define BITVAR_PAD -1 + +enum +{ + TYPEOF_INT = 1, + TYPEOF_SHORT, + TYPEOF_BOOL, + TYPEOF_CHAR, + TYPEOF_LONG, + TYPEOF_LONGLONG, + TYPEOF_FLOAT, + TYPEOF_FIXED16X16, + TYPEOF_BIT, + TYPEOF_BITFIELD, + TYPEOF_SBIT, + TYPEOF_SFR, + TYPEOF_VOID, + TYPEOF_STRUCT, + TYPEOF_ARRAY, + TYPEOF_FUNCTION, + TYPEOF_POINTER, + TYPEOF_FPOINTER, + TYPEOF_CPOINTER, + TYPEOF_GPOINTER, + TYPEOF_PPOINTER, + TYPEOF_IPOINTER, + TYPEOF_EEPPOINTER +}; + +// values for first byte (or 3 most significant bits) of generic pointer. +#if 0 +#define GPTYPE_FAR 0x00 +#define GPTYPE_NEAR 0x40 +#define GPTYPE_XSTACK 0x60 +#define GPTYPE_CODE 0x80 +#else +#define GPTYPE_FAR (port->gp_tags.tag_far) +#define GPTYPE_NEAR (port->gp_tags.tag_near) +#define GPTYPE_XSTACK (port->gp_tags.tag_xstack) +#define GPTYPE_CODE (port->gp_tags.tag_code) +#endif + +#define HASHTAB_SIZE 256 + +/* hash table bucket */ +typedef struct bucket +{ + void *sym; /* pointer to the object */ + char name[SDCC_NAME_MAX + 1]; /* name of this symbol */ + long level; /* nest level for this symbol */ + int block; /* belongs to which block */ + struct bucket *prev; /* ptr 2 previous bucket */ + struct bucket *next; /* ptr 2 next bucket */ +} +bucket; + +typedef struct structdef +{ + char tag[SDCC_NAME_MAX + 1]; /* tag part of structure */ + long level; /* Nesting level */ + int block; /* belongs to which block */ + struct symbol *fields; /* pointer to fields */ + unsigned size; /* sizeof the table in bytes */ + int type; /* STRUCT or UNION */ + bool b_flexArrayMember; /* has got a flexible array member, + only needed for syntax checks */ + struct symbol *tagsym; /* tag symbol (NULL if no tag) */ +} +structdef; + +/* noun definitions */ +typedef enum +{ + V_INT = 1, + V_FLOAT, + V_FIXED16X16, + V_BOOL, + V_CHAR, + V_VOID, + V_STRUCT, + V_LABEL, + V_BIT, + V_BITFIELD, + V_BBITFIELD, + V_SBIT, + V_DOUBLE +} +NOUN; + +/* storage class */ +typedef enum +{ + S_FIXED = 0, + S_AUTO, + S_REGISTER, + S_SFR, + S_SBIT, + S_CODE, + S_XDATA, + S_DATA, + S_IDATA, + S_PDATA, + S_LITERAL, + S_STACK, + S_XSTACK, + S_BIT, + S_EEPROM +} +STORAGE_CLASS; + +#define TYPE_TARGET_CHAR TYPE_BYTE +#define TYPE_TARGET_INT TYPE_WORD +#define TYPE_TARGET_LONG TYPE_DWORD +#define TYPE_TARGET_UCHAR TYPE_UBYTE +#define TYPE_TARGET_UINT TYPE_UWORD +#define TYPE_TARGET_ULONG TYPE_UDWORD +#define TYPE_TARGET_LONGLONG TYPE_QWORD +#define TYPE_TARGET_ULONGLONG TYPE_UQWORD + +/* specifier is the last in the type-chain */ +typedef struct specifier +{ + NOUN noun; /* CHAR INT STRUCTURE LABEL */ + STORAGE_CLASS sclass; /* REGISTER,AUTO,FIX,CONSTANT */ + struct memmap *oclass; /* output storage class */ + unsigned b_long:1; /* 1=long */ + unsigned b_longlong:1; /* 1=long long */ + unsigned b_short:1; /* 1=short int */ + unsigned b_unsigned:1; /* 1=unsigned, 0=signed */ + unsigned b_signed:1; /* just for sanity checks only*/ + bool b_implicit_sign:1; /* signedness not explicitly specified - needed to keep char a separate type from signed char and unsigned char. */ + unsigned b_static:1; /* 1=static keyword found */ + unsigned b_extern:1; /* 1=extern found */ + unsigned b_inline:1; /* inline function requested */ + unsigned b_noreturn:1; /* promised not to return */ + unsigned b_alignas:1; /* alignment */ + unsigned b_absadr:1; /* absolute address specfied */ + unsigned b_volatile:1; /* is marked as volatile */ + unsigned b_const:1; /* is a constant */ + unsigned b_restrict:1; /* is restricted */ + struct symbol *addrspace; /* is in named address space */ + unsigned b_typedef:1; /* is typedefed */ + unsigned b_isregparm:1; /* is the first parameter */ + unsigned b_isenum:1; /* is an enumerated type */ + unsigned b_bitUnnamed:1; /* is an unnamed bit-field */ + unsigned b_needspar:1; /* has to be a parameter */ + unsigned _bitStart; /* bit start position */ + unsigned _bitLength; /* bit length */ + unsigned _addr; /* address of symbol */ + unsigned _stack; /* stack offset for stacked v */ + int argreg; /* reg no for regparm */ + union + { /* Values if constant or enum */ + TYPE_TARGET_INT v_int; /* 2 bytes: int and char values */ + const char *v_char; /* char character string */ + const TYPE_TARGET_UINT *v_char16; /* char16_t character string */ + const TYPE_TARGET_ULONG *v_char32;/* char32_t character string */ + TYPE_TARGET_UINT v_uint; /* 2 bytes: unsigned int const value */ + TYPE_TARGET_LONG v_long; /* 4 bytes: long constant value */ + TYPE_TARGET_ULONG v_ulong; /* 4 bytes: unsigned long constant value */ + TYPE_TARGET_LONGLONG v_longlong; /* 8 bytes: long long constant value */ + TYPE_TARGET_ULONGLONG v_ulonglong;/* 8 bytes: unsigned long long const value */ + double v_float; /* floating point constant value */ + TYPE_TARGET_ULONG v_fixed16x16; /* 4 bytes: fixed point constant value */ + struct symbol *v_enum; /* ptr to enum_list if enum==1 */ + } + const_val; + struct structdef *v_struct; /* structure pointer */ +} +specifier; + +/* types of declarators */ +typedef enum +{ + UPOINTER = 0, /* unknown pointer used only when parsing */ + POINTER, /* pointer to near data */ + IPOINTER, /* pointer to upper 128 bytes */ + PPOINTER, /* paged area pointer */ + FPOINTER, /* pointer to far data */ + CPOINTER, /* pointer to code space */ + GPOINTER, /* generic pointer */ + EEPPOINTER, /* pointer to eeprom */ + ARRAY, + FUNCTION +} +DECLARATOR_TYPE; + +typedef struct declarator +{ + DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */ + size_t num_elem; /* # of elems if type==array, */ + /* always 0 for flexible arrays */ + unsigned ptr_const:1; /* pointer is constant */ + unsigned ptr_volatile:1; /* pointer is volatile */ + unsigned ptr_restrict:1; /* pointer is resticted */ + struct symbol *ptr_addrspace; /* pointer is in named address space */ + + struct sym_link *tspec; /* pointer type specifier */ +} +declarator; + +typedef enum +{ + DECLARATOR = 1, + SPECIFIER +} SYM_LINK_CLASS; +#define DECLSPEC2TXT(select) (select==DECLARATOR?"DECLARATOR":select==SPECIFIER?"SPECIFIER":"UNKNOWN") + +typedef struct sym_link +{ + SYM_LINK_CLASS xclass; /* DECLARATOR or SPECIFIER */ + unsigned tdef:1; /* current link created by */ + /* typedef if this flag is set */ + union + { + specifier s; /* if CLASS == SPECIFIER */ + declarator d; /* if CLASS == DECLARATOR */ + } select; + + /* function attributes */ + struct + { + struct value *args; /* the defined arguments */ + unsigned hasVargs:1; /* functions has varargs */ + unsigned calleeSaves:1; /* functions uses callee save */ + unsigned hasbody:1; /* function body defined */ + unsigned hasFcall:1; /* does it call other functions */ + unsigned reent:1; /* function is reentrant */ + unsigned naked:1; /* naked function */ + + unsigned shadowregs:1; /* function uses shadow registers (pic16 port) */ + unsigned wparam:1; /* first byte of arguments is passed via WREG (pic16 port) */ + unsigned nonbanked:1; /* function has the nonbanked attribute */ + unsigned banked:1; /* function has the banked attribute */ + unsigned critical:1; /* critical function */ + unsigned intrtn:1; /* this is an interrupt routine */ + unsigned rbank:1; /* seperate register bank */ + unsigned inlinereq:1; /* inlining requested */ + unsigned noreturn:1; /* promised not to return */ + unsigned smallc:1; /* Parameters on stack are passed in reverse order */ + unsigned z88dk_fastcall:1; /* For the z80-related ports: Function has a single paramter of at most 32 bits that is passed in dehl */ + unsigned z88dk_callee:1; /* Stack pointer adjustment for parameters passed on the stack is done by the callee */ + unsigned z88dk_shortcall:1; /* Short call available via rst (see values later) (Z80 only) */ + unsigned z88dk_has_params_offset:1; /* Has a parameter offset (Z80 only) */ + unsigned intno; /* Number of interrupt for interrupt service routine */ + short regbank; /* register bank 2b used */ + unsigned builtin; /* is a builtin function */ + unsigned javaNative; /* is a JavaNative Function (TININative ONLY) */ + unsigned overlay; /* force parameters & locals into overlay segment */ + unsigned hasStackParms; /* function has parameters on stack */ + bool preserved_regs[9]; /* Registers preserved by the function - may be an underestimate */ + unsigned char z88dk_shortcall_rst; /* Rst for a short call */ + unsigned short z88dk_shortcall_val; /* Value for a short call */ + unsigned short z88dk_params_offset; /* Additional offset from for arguments */ + } funcAttrs; + + struct sym_link *next; /* next element on the chain */ +} +sym_link; + +typedef struct symbol +{ + char name[SDCC_SYMNAME_MAX + 1]; /* Input Variable Name */ + char rname[SDCC_NAME_MAX + 1]; /* internal name */ + + long level; /* declaration lev,fld offset */ + short block; /* sequential block # of definition */ + int seqPoint; /* sequence point defined or, if unbound, used */ + int key; + unsigned flexArrayLength; /* if the symbol specifies a struct + with a "flexible array member", then the additional length in bytes for + the "fam" is stored here. Because the length can be different from symbol + to symbol AND v_struct isn't copied in copyLinkChain(), it's located here + in the symbol and not in v_struct or the declarator */ + unsigned implicit:1; /* implicit flag */ + unsigned undefined:1; /* undefined variable */ + unsigned infertype:1; /* type should be inferred from first assign */ + unsigned _isparm:1; /* is a parameter */ + unsigned ismyparm:1; /* is parameter of the function being generated */ + unsigned isitmp:1; /* is an intermediate temp */ + unsigned islbl:1; /* is a temporary label */ + unsigned isref:1; /* has been referenced */ + unsigned isind:1; /* is an induction variable */ + unsigned isinvariant:1; /* is a loop invariant */ + unsigned cdef:1; /* compiler defined symbol */ + unsigned addrtaken:1; /* address of the symbol was taken */ + unsigned isreqv:1; /* is the register equivalent of a symbol */ + unsigned udChked:1; /* use def checking has been already done */ + unsigned generated:1; /* code generated (function symbols only) */ + unsigned isinscope:1; /* is in scope */ + + /* following flags are used by the backend + for code generation and can be changed + if a better scheme for backend is thought of */ + unsigned isLiveFcall:1; /* is live at or across a function call */ + unsigned isspilt:1; /* has to be spilt */ + unsigned spillA:1; /* spilt be register allocator */ + unsigned remat:1; /* can be remateriazed */ + unsigned isptr:1; /* is a pointer */ + unsigned uptr:1; /* used as a pointer */ + unsigned isFree:1; /* used by register allocator */ + unsigned islocal:1; /* is a local variable */ + unsigned blockSpil:1; /* spilt at block level */ + unsigned remainSpil:1; /* spilt because not used in remainder */ + unsigned stackSpil:1; /* has been spilt on temp stack location */ + unsigned onStack:1; /* this symbol allocated on the stack */ + unsigned iaccess:1; /* indirect access */ + unsigned ruonly:1; /* used in return statement only */ + unsigned spildir:1; /* spilt in direct space */ + unsigned ptrreg:1; /* this symbol assigned to a ptr reg */ + unsigned noSpilLoc:1; /* cannot be assigned a spil location */ + bool funcDivFlagSafe:1; /* we know this function is safe to call with undocumented stm8 flag bit 6 set*/ + bool funcUsesVolatile:1; /* The function accesses a volatile variable */ + unsigned isstrlit; /* is a string literal and it's usage count */ + unsigned accuse; /* can be left in the accumulator + On the Z80 accuse is divided into + ACCUSE_A and ACCUSE_HL as the idea + is quite similar. + */ + unsigned dptr; /* 8051 variants with multiple DPTRS + currently implemented in DS390 only + */ + int allocreq; /* allocation is required for this variable */ + int stack; /* offset on stack */ + int xstack; /* offset on xternal stack */ + short nRegs; /* number of registers required */ + short regType; /* type of register required */ + + struct reg_info *regs[8]; /* can have at the most 8 registers */ + struct asmop *aop; /* asmoperand for this symbol */ + struct iCode *fuse; /* furthest use */ + struct iCode *rematiCode; /* rematerialise with which instruction */ + struct operand *reqv; /* register equivalent of a local variable */ + struct symbol *prereqv; /* symbol before register equiv. substitution */ + struct symbol *psbase; /* if pseudo symbol, the symbol it is based on */ + union + { + struct symbol *spillLoc; /* register spil location */ + struct set *itmpStack; /* symbols spilt @ this stack location */ + } + usl; + int bitVar; /* if bitVar != 0: this is a bit variable, bitVar is the size in bits */ + unsigned bitUnnamed:1; /* unnamed bit variable */ + unsigned offset; /* offset from top if struct */ + + int lineDef; /* defined line number */ + char *fileDef; /* defined filename */ + int lastLine; /* for functions the last line */ + struct sym_link *type; /* 1st link to declarator chain */ + struct sym_link *etype; /* last link to declarator chain */ + struct symbol *next; /* crosslink to next symbol */ + struct symbol *localof; /* local variable of which function */ + struct initList *ival; /* ptr to initializer if any */ + struct bitVect *defs; /* bit vector for definitions */ + struct bitVect *uses; /* bit vector for uses */ + struct bitVect *regsUsed; /* for functions registers used */ + int liveFrom; /* live from iCode sequence number */ + int liveTo; /* live to sequence number */ + int used; /* no. of times this was used */ + int recvSize; /* size of first argument */ + struct bitVect *clashes; /* overlaps with what other symbols */ + struct ast *funcTree; /* function body ast if inlined */ + struct symbol *addressmod[2]; /* access functions for named address spaces */ + + bool for_newralloc; +} +symbol; + +extern sym_link *validateLink (sym_link * l, + const char *macro, const char *args, const char select, const char *file, unsigned line); +/* Easy Access Macros */ +#define IS_OP_RUONLY(x) (IS_SYMOP(x) && OP_SYMBOL(x) && OP_SYMBOL(x)->ruonly) +#define IS_OP_ACCUSE(x) (IS_SYMOP(x) && OP_SYMBOL(x) && OP_SYMBOL(x)->accuse) + +#define DCL_TYPE(l) validateLink(l, "DCL_TYPE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.dcl_type +#define DCL_ELEM(l) validateLink(l, "DCL_ELEM", #l, DECLARATOR, __FILE__, __LINE__)->select.d.num_elem +#define DCL_PTR_CONST(l) validateLink(l, "DCL_PTR_CONST", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_const +#define DCL_PTR_VOLATILE(l) validateLink(l, "DCL_PTR_VOLATILE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_volatile +#define DCL_PTR_RESTRICT(l) validateLink(l, "DCL_PTR_RESTRICT", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_restrict +#define DCL_PTR_ADDRSPACE(l) validateLink(l, "DCL_PTR_ADDRSPACE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_addrspace +#define DCL_TSPEC(l) validateLink(l, "DCL_TSPEC", #l, DECLARATOR, __FILE__, __LINE__)->select.d.tspec + +#define FUNC_DEBUG //assert(IS_FUNC(x)); +#define FUNC_HASVARARGS(x) (x->funcAttrs.hasVargs) +#define IFFUNC_HASVARARGS(x) (IS_FUNC(x) && FUNC_HASVARARGS(x)) +#define FUNC_ARGS(x) (x->funcAttrs.args) +#define IFFUNC_ARGS(x) (IS_FUNC(x) && FUNC_ARGS(x)) +#define FUNC_HASFCALL(x) (x->funcAttrs.hasFcall) +#define IFFUNC_HASFCALL(x) (IS_FUNC(x) && FUNC_HASFCALL(x)) +#define FUNC_HASBODY(x) (x->funcAttrs.hasbody) +#define IFFUNC_HASBODY(x) (IS_FUNC(x) && FUNC_HASBODY(x)) +#define FUNC_CALLEESAVES(x) (x->funcAttrs.calleeSaves) +#define IFFUNC_CALLEESAVES(x) (IS_FUNC(x) && FUNC_CALLEESAVES(x)) +#define FUNC_ISISR(x) (x->funcAttrs.intrtn) +#define IFFUNC_ISISR(x) (IS_FUNC(x) && FUNC_ISISR(x)) +#define FUNC_INTNO(x) (x->funcAttrs.intno) +#define FUNC_REGBANK(x) (x->funcAttrs.regbank) +#define FUNC_HASSTACKPARM(x) (x->funcAttrs.hasStackParms) +#define FUNC_ISINLINE(x) (x->funcAttrs.inlinereq) +#define IFFUNC_ISINLINE(x) (IS_FUNC(x) && FUNC_ISINLINE(x)) +#define FUNC_ISNORETURN(x) (x->funcAttrs.noreturn) +#define IFFUNC_ISNORETURN(x) (IS_FUNC(x) && FUNC_ISNORETURN(x)) + +#define FUNC_ISREENT(x) (x->funcAttrs.reent) +#define IFFUNC_ISREENT(x) (IS_FUNC(x) && FUNC_ISREENT(x)) +#define FUNC_ISSHADOWREGS(x) (x->funcAttrs.shadowregs) +#define IFFUNC_ISSHADOWREGS(x) (IS_FUNC(x) && FUNC_ISSHADOWREGS(x)) +#define FUNC_ISWPARAM(x) (x->funcAttrs.wparam) +#define IFFUNC_ISWPARAM(x) (IS_FUNC(x) && FUNC_ISWPARAM(x)) +#define FUNC_ISNAKED(x) (x->funcAttrs.naked) +#define IFFUNC_ISNAKED(x) (IS_FUNC(x) && FUNC_ISNAKED(x)) +#define FUNC_NONBANKED(x) (x->funcAttrs.nonbanked) +#define IFFUNC_NONBANKED(x) (IS_FUNC(x) && FUNC_NONBANKED(x)) +#define FUNC_BANKED(x) (x->funcAttrs.banked) +#define IFFUNC_BANKED(x) (IS_FUNC(x) && FUNC_BANKED(x)) +#define FUNC_ISCRITICAL(x) (x->funcAttrs.critical) +#define IFFUNC_ISCRITICAL(x) (IS_FUNC(x) && FUNC_ISCRITICAL(x)) +#define FUNC_ISBUILTIN(x) (x->funcAttrs.builtin) +#define IFFUNC_ISBUILTIN(x) (IS_FUNC(x) && FUNC_ISBUILTIN(x)) +#define FUNC_ISJAVANATIVE(x) (x->funcAttrs.javaNative) +#define IFFUNC_ISJAVANATIVE(x) (IS_FUNC(x) && FUNC_ISJAVANATIVE(x)) +#define FUNC_ISOVERLAY(x) (x->funcAttrs.overlay) +#define IFFUNC_ISOVERLAY(x) (IS_FUNC(x) && FUNC_ISOVERLAY(x)) +#define FUNC_ISSMALLC(x) (x->funcAttrs.smallc) +#define IFFUNC_ISSMALLC(x) (IS_FUNC(x) && FUNC_ISSMALLC(x)) +#define FUNC_ISZ88DK_FASTCALL(x) (x->funcAttrs.z88dk_fastcall) +#define IFFUNC_ISZ88DK_FASTCALL(x) (IS_FUNC(x) && FUNC_ISZ88DK_FASTCALL(x)) +#define FUNC_ISZ88DK_CALLEE(x) (x->funcAttrs.z88dk_callee) +#define IFFUNC_ISZ88DK_CALLEE(x) (IS_FUNC(x) && FUNC_ISZ88DK_CALLEE(x)) +#define FUNC_ISZ88DK_SHORTCALL(x) (x->funcAttrs.z88dk_shortcall) +#define IFFUNC_ISZ88DK_SHORTCALL(x) (IS_FUNC(x) && FUNC_ISZ88DK_SHORTCALL(x)) + +#define BANKED_FUNCTIONS ( options.model == MODEL_HUGE || \ + ( (options.model == MODEL_LARGE || options.model == MODEL_MEDIUM) && \ + TARGET_Z80_LIKE ) ) +#define IFFUNC_ISBANKEDCALL(x) ( IS_FUNC(x) && \ + ( FUNC_BANKED(x) || ( BANKED_FUNCTIONS && !FUNC_NONBANKED(x) ) ) ) + +#define SPEC_NOUN(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.noun +#define SPEC_LONG(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_long +#define SPEC_LONGLONG(x) validateLink(x, "SPEC_LONGLONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_longlong +#define SPEC_SHORT(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_short +#define SPEC_USIGN(x) validateLink(x, "SPEC_USIGN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_unsigned +#define SPEC_SIGN(x) validateLink(x, "SPEC_USIGN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_signed +#define SPEC_SCLS(x) validateLink(x, "SPEC_SCLS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.sclass +#define SPEC_ENUM(x) validateLink(x, "SPEC_ENUM", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_isenum +#define SPEC_OCLS(x) validateLink(x, "SPEC_OCLS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.oclass +#define SPEC_STAT(x) validateLink(x, "SPEC_STAT", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_static +#define SPEC_EXTR(x) validateLink(x, "SPEC_EXTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_extern +#define SPEC_CODE(x) validateLink(x, "SPEC_CODE", #x, SPECIFIER, __FILE__, __LINE__)->select.s._codesg +#define SPEC_ABSA(x) validateLink(x, "SPEC_ABSA", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_absadr +#define SPEC_BANK(x) validateLink(x, "SPEC_BANK", #x, SPECIFIER, __FILE__, __LINE__)->select.s._regbank +#define SPEC_ADDR(x) validateLink(x, "SPEC_ADDR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._addr +#define SPEC_STAK(x) validateLink(x, "SPEC_STAK", #x, SPECIFIER, __FILE__, __LINE__)->select.s._stack +#define SPEC_CVAL(x) validateLink(x, "SPEC_CVAL", #x, SPECIFIER, __FILE__, __LINE__)->select.s.const_val +#define SPEC_BSTR(x) validateLink(x, "SPEC_BSTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitStart +#define SPEC_BLEN(x) validateLink(x, "SPEC_BLEN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitLength +#define SPEC_BUNNAMED(x) validateLink(x, "SPEC_BUNNAMED", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_bitUnnamed +#define SPEC_NEEDSPAR(x) validateLink(x, "SPEC_NEEDSPAR", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_needspar + +/* Sleaze: SPEC_ISR_SAVED_BANKS is only used on + * function type symbols, which obviously cannot + * be of BIT type. Therefore, we recycle the + * _bitStart field instead of defining a new field. + */ +#define SPEC_ISR_SAVED_BANKS(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitStart +#define SPEC_VOLATILE(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_volatile +#define SPEC_CONST(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_const +#define SPEC_RESTRICT(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_restrict +#define SPEC_ADDRSPACE(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.addrspace +#define SPEC_STRUCT(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.v_struct +#define SPEC_TYPEDEF(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_typedef +#define SPEC_REGPARM(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_isregparm +#define SPEC_ARGREG(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.argreg +#define SPEC_INLINE(x) validateLink(x, "SPEC_INLINE", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_inline +#define SPEC_NORETURN(x) validateLink(x, "SPEC_NORETURN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_noreturn +#define SPEC_ALIGNAS(x) validateLink(x, "SPEC_ALIGNAS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_alignas + +/* type check macros */ +#define IS_DECL(x) ( x && x->xclass == DECLARATOR ) +#define IS_SPEC(x) ( x && x->xclass == SPECIFIER ) + +#define IS_ARRAY(x) (IS_DECL(x) && DCL_TYPE(x) == ARRAY) +#define IS_DATA_PTR(x) (IS_DECL(x) && DCL_TYPE(x) == POINTER) +#define IS_SMALL_PTR(x) (IS_DECL(x) && (DCL_TYPE(x) == POINTER || \ + DCL_TYPE(x) == IPOINTER || \ + DCL_TYPE(x) == PPOINTER )) +#define IS_PTR(x) (IS_DECL(x) && (DCL_TYPE(x) == POINTER || \ + DCL_TYPE(x) == FPOINTER || \ + DCL_TYPE(x) == GPOINTER || \ + DCL_TYPE(x) == IPOINTER || \ + DCL_TYPE(x) == PPOINTER || \ + DCL_TYPE(x) == EEPPOINTER || \ + DCL_TYPE(x) == CPOINTER || \ + DCL_TYPE(x) == UPOINTER )) +#define IS_PTR_CONST(x) (IS_PTR(x) && DCL_PTR_CONST(x)) +#define IS_PTR_RESTRICT(x) (IS_PTR(x) && DCL_PTR_RESTRICT(x)) +#define IS_FARPTR(x) (IS_DECL(x) && DCL_TYPE(x) == FPOINTER) +#define IS_CODEPTR(x) (IS_DECL(x) && DCL_TYPE(x) == CPOINTER) +#define IS_GENPTR(x) (IS_DECL(x) && DCL_TYPE(x) == GPOINTER) +#define IS_FUNCPTR(x) (IS_DECL(x) && (DCL_TYPE(x) == CPOINTER || DCL_TYPE(x) == GPOINTER) && IS_FUNC(x->next)) +#define IS_FUNC(x) (IS_DECL(x) && DCL_TYPE(x) == FUNCTION) +#define IS_LONG(x) (IS_SPEC(x) && x->select.s.b_long) +#define IS_LONGLONG(x) (IS_SPEC(x) && x->select.s.b_longlong) +#define IS_UNSIGNED(x) (IS_SPEC(x) && x->select.s.b_unsigned) +#define IS_TYPEDEF(x) (IS_SPEC(x) && x->select.s.b_typedef) +#define IS_CONSTANT(x) (isConstant (x)) +#define IS_RESTRICT(x) (isRestrict (x)) +#define IS_STRUCT(x) (IS_SPEC(x) && x->select.s.noun == V_STRUCT) +#define IS_ABSOLUTE(x) (IS_SPEC(x) && x->select.s.b_absadr ) +#define IS_REGISTER(x) (IS_SPEC(x) && SPEC_SCLS(x) == S_REGISTER) +#define IS_RENT(x) (IS_SPEC(x) && x->select.s._reent ) +#define IS_STATIC(x) (IS_SPEC(x) && SPEC_STAT(x)) +#define IS_INLINE(x) (IS_SPEC(x) && SPEC_INLINE(x)) +#define IS_NORETURN(x) (IS_SPEC(x) && SPEC_NORETURN(x)) +#define IS_INT(x) (IS_SPEC(x) && x->select.s.noun == V_INT) +#define IS_VOID(x) (IS_SPEC(x) && x->select.s.noun == V_VOID) +#define IS_BOOL(x) (IS_SPEC(x) && x->select.s.noun == V_BOOL) +#define IS_CHAR(x) (IS_SPEC(x) && x->select.s.noun == V_CHAR) +#define IS_EXTERN(x) (IS_SPEC(x) && x->select.s.b_extern) +#define IS_VOLATILE(x) (isVolatile (x)) +#define IS_INTEGRAL(x) (IS_SPEC(x) && (x->select.s.noun == V_INT || \ + x->select.s.noun == V_BOOL || \ + x->select.s.noun == V_CHAR || \ + x->select.s.noun == V_BITFIELD || \ + x->select.s.noun == V_BBITFIELD || \ + x->select.s.noun == V_BIT || \ + x->select.s.noun == V_SBIT )) +#define IS_BITFIELD(x) (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD || \ + x->select.s.noun == V_BBITFIELD )) +#define IS_BITVAR(x) (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD || \ + x->select.s.noun == V_BBITFIELD || \ + x->select.s.noun == V_BIT || \ + x->select.s.noun == V_SBIT )) +#define IS_BIT(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT || \ + x->select.s.noun == V_SBIT )) +#define IS_BOOLEAN(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT || \ + x->select.s.noun == V_SBIT || \ + x->select.s.noun == V_BBITFIELD || \ + x->select.s.noun == V_BOOL )) +#define IS_FLOAT(x) (IS_SPEC(x) && x->select.s.noun == V_FLOAT) +#define IS_FIXED16X16(x) (IS_SPEC(x) && x->select.s.noun == V_FIXED16X16) +#define IS_FIXED(x) (IS_FIXED16X16(x)) +#define IS_ARITHMETIC(x) (IS_INTEGRAL(x) || IS_FLOAT(x) || IS_FIXED(x)) +#define IS_AGGREGATE(x) (IS_ARRAY(x) || IS_STRUCT(x)) +#define IS_LITERAL(x) (IS_SPEC(x) && x->select.s.sclass == S_LITERAL) +#define IS_CODE(x) (IS_SPEC(x) && SPEC_SCLS(x) == S_CODE) +#define IS_REGPARM(x) (IS_SPEC(x) && SPEC_REGPARM(x)) + +#define IS_VALID_PARAMETER_STORAGE_CLASS_SPEC(x) (!SPEC_TYPEDEF(x) && !SPEC_EXTR(x) && !SPEC_STAT(x) && SPEC_SCLS(x) != S_AUTO) + +/* symbol check macros */ +#define IS_AUTO(x) (x->level && !IS_STATIC(x->etype) && !IS_EXTERN(x->etype)) + +/* forward declaration for the global vars */ +extern bucket *SymbolTab[]; +extern bucket *StructTab[]; +extern bucket *TypedefTab[]; +extern bucket *LabelTab[]; +extern bucket *enumTab[]; +extern bucket *AddrspaceTab[]; +extern symbol *fsadd; +extern symbol *fssub; +extern symbol *fsmul; +extern symbol *fsdiv; +extern symbol *fseq; +extern symbol *fsneq; +extern symbol *fslt; + +extern symbol *fps16x16_add; +extern symbol *fps16x16_sub; +extern symbol *fps16x16_mul; +extern symbol *fps16x16_div; +extern symbol *fps16x16_eq; +extern symbol *fps16x16_neq; +extern symbol *fps16x16_lt; +extern symbol *fps16x16_lteq; +extern symbol *fps16x16_gt; +extern symbol *fps16x16_gteq; + +/* Dims: mul/div/mod, BYTE/WORD/DWORD/QWORD, SIGNED/UNSIGNED/BOTH */ +extern symbol *muldiv[3][4][4]; +/* 16 x 16 -> 32 multiplication SIGNED/UNSIGNED */ +extern symbol *muls16tos32[2]; +/* Dims: BYTE/WORD/DWORD/QWORD SIGNED/UNSIGNED */ +extern sym_link *multypes[4][2]; +/* Dims: to/from float, BYTE/WORD/DWORD/QWORD, SIGNED/USIGNED */ +extern symbol *conv[2][4][2]; +/* Dims: to/from fixed16x16, BYTE/WORD/DWORD/QWORD/FLOAT, SIGNED/USIGNED */ +extern symbol *fp16x16conv[2][5][2]; +/* Dims: shift left/shift right, BYTE/WORD/DWORD/QWORD, SIGNED/UNSIGNED */ +extern symbol *rlrr[2][4][2]; + +extern symbol *memcpy_builtin; + +#define SCHARTYPE multypes[0][0] +#define UCHARTYPE multypes[0][1] +#define INTTYPE multypes[1][0] +#define UINTTYPE multypes[1][1] +#define LONGTYPE multypes[2][0] +#define ULONGTYPE multypes[2][1] +#define LONGLONGTYPE multypes[3][0] +#define ULONGLONGTYPE multypes[3][1] + +extern sym_link *floatType; +extern sym_link *fixed16x16Type; + +#include "SDCCval.h" + +typedef enum +{ + RESULT_TYPE_NONE = 0, /* operands will be promoted to int */ + RESULT_TYPE_BOOL, + RESULT_TYPE_CHAR, + RESULT_TYPE_INT, + RESULT_TYPE_OTHER, /* operands will be promoted to int */ + RESULT_TYPE_IFX, + RESULT_TYPE_GPTR /* operands will be promoted to generic ptr */ +} RESULT_TYPE; + +/* forward definitions for the symbol table related functions */ +void initSymt (); +symbol *newSymbol (const char *, long); +sym_link *newLink (SYM_LINK_CLASS); +sym_link *newFloatLink (); +structdef *newStruct (const char *); +void addDecl (symbol *, int, sym_link *); +sym_link *finalizeSpec (sym_link *); +sym_link *mergeSpec (sym_link *, sym_link *, const char *name); +sym_link *mergeDeclSpec (sym_link *, sym_link *, const char *name); +symbol *reverseSyms (symbol *); +sym_link *reverseLink (sym_link *); +symbol *copySymbol (const symbol *); +symbol *copySymbolChain (const symbol *); +void printSymChain (symbol *, int); +void printStruct (structdef *, int); +char *genSymName (long); +sym_link *getSpec (sym_link *); +int compStructSize (int, structdef *); +sym_link *copyLinkChain (const sym_link *); +int checkDecl (symbol *, int); +void checkBasic (sym_link *, sym_link *); +value *checkPointerIval (sym_link *, value *); +value *checkStructIval (symbol *, value *); +value *checkArrayIval (sym_link *, value *); +value *checkIval (sym_link *, value *); +unsigned int getSize (sym_link *); +unsigned int bitsForType (sym_link *); +sym_link *newIntLink (); +sym_link *newCharLink (); +sym_link *newLongLink (); +sym_link *newBoolLink (); +sym_link *newVoidLink (); +int compareType (sym_link *, sym_link *); +int compareTypeExact (sym_link *, sym_link *, long); +int compareTypeInexact (sym_link *, sym_link *); +int checkFunction (symbol *, symbol *); +void cleanUpLevel (bucket **, long); +void cleanUpBlock (bucket **, int); +symbol *getAddrspace (sym_link *type); +int funcInChain (sym_link *); +void addSymChain (symbol **); +sym_link *structElemType (sym_link *, value *); +symbol *getStructElement (structdef *, symbol *); +sym_link *computeType (sym_link *, sym_link *, RESULT_TYPE, int); +void processFuncPtrArgs (sym_link *); +void processFuncArgs (symbol *); +int isSymbolEqual (const symbol *, const symbol *); +int powof2 (TYPE_TARGET_ULONG); +void dbuf_printTypeChain (sym_link *, struct dbuf_s *); +void printTypeChain (sym_link *, FILE *); +void printTypeChainRaw (sym_link *, FILE *); +void initCSupport (); +void initBuiltIns (); +void pointerTypes (sym_link *, sym_link *); +void cdbStructBlock (int); +void initHashT (); +bucket *newBucket (); +void addSym (bucket **, void *, char *, long, int, int checkType); +void deleteSym (bucket **, void *, const char *); +void *findSym (bucket **, void *, const char *); +void *findSymWithLevel (bucket **, struct symbol *); +void *findSymWithBlock (bucket **, struct symbol *, int, long); +void changePointer (sym_link * p); +void checkTypeSanity (sym_link * etype, const char *name); +sym_link *typeFromStr (const char *); +STORAGE_CLASS sclsFromPtr (sym_link * ptr); +sym_link *newEnumType (symbol *); +void promoteAnonStructs (int, structdef *); +int isConstant (sym_link * type); +int isVolatile (sym_link * type); +int isRestrict (sym_link * type); +value *aggregateToPointer (value *); + + +extern char *nounName (sym_link *); /* noun strings */ +extern void printFromToType (sym_link *, sym_link *); + +#endif |
