- void *sym; /* pointer to the object */
- char name[SDCC_NAME_MAX + 1]; /* name of this symbol */
- int 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 */
+ void *sym; /* pointer to the object */
+ char name[SDCC_NAME_MAX + 1]; /* name of this symbol */
+ int 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 */
- char tag[SDCC_NAME_MAX + 1]; /* tag part of structure */
- unsigned char level; /* Nesting level */
- struct symbol *fields; /* pointer to fields */
- unsigned size; /* sizeof the table in bytes */
- int type; /* STRUCT or UNION */
+ char tag[SDCC_NAME_MAX + 1]; /* tag part of structure */
+ unsigned char level; /* Nesting level */
+ struct symbol *fields; /* pointer to fields */
+ unsigned size; /* sizeof the table in bytes */
+ int type; /* STRUCT or UNION */
+ bool b_flexArrayMember; /* has got an flexible array member,
+ only needed for syntax checks */
- NOUN noun; /* CHAR INT STRUCTURE LABEL */
- STORAGE_CLASS sclass; /* REGISTER,AUTO,FIX,CONSTANT */
- struct memmap *oclass; /* output storage class */
- unsigned _long:1; /* 1=long */
- unsigned _short:1; /* 1=short int */
- unsigned _unsigned:1; /* 1=unsigned, 0=signed */
- unsigned _signed:1; /* just for sanity checks only*/
- unsigned _static:1; /* 1=static keyword found */
- unsigned _extern:1; /* 1=extern found */
- unsigned _absadr:1; /* absolute address specfied */
- unsigned _volatile:1; /* is marked as volatile */
- unsigned _const:1; /* is a constant */
- unsigned _typedef:1; /* is typedefed */
- unsigned _isregparm:1; /* is the first parameter */
- unsigned _isenum:1; /* is an enumerated type */
- unsigned _addr; /* address of symbol */
- unsigned _stack; /* stack offset for stacked v */
- unsigned _bitStart; /* bit start position */
- int _bitLength; /* bit length */
- int argreg; /* reg no for regparm */
+ 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_short:1; /* 1=short int */
+ unsigned b_unsigned:1; /* 1=unsigned, 0=signed */
+ unsigned b_signed:1; /* just for sanity checks only*/
+ unsigned b_static:1; /* 1=static keyword found */
+ unsigned b_extern:1; /* 1=extern found */
+ unsigned b_absadr:1; /* absolute address specfied */
+ unsigned b_volatile:1; /* is marked as volatile */
+ unsigned b_const:1; /* is a constant */
+ unsigned b_typedef:1; /* is typedefed */
+ unsigned b_isregparm:1; /* is the first parameter */
+ unsigned b_isenum:1; /* is an enumerated type */
+ unsigned _addr; /* address of symbol */
+ unsigned _stack; /* stack offset for stacked v */
+ unsigned _bitStart; /* bit start position */
+ int _bitLength; /* bit length */
+ int argreg; /* reg no for regparm */
- { /* Values if constant or enum */
- TYPE_WORD v_int; /* 2 bytes: int and char values */
- char *v_char; /* character string */
- TYPE_UWORD v_uint; /* 2 bytes: unsigned int const value */
- TYPE_DWORD v_long; /* 4 bytes: long constant value */
- TYPE_UDWORD v_ulong; /* 4 bytes: unsigned long constant value */
- double v_float; /* floating point constant value */
- struct symbol *v_enum; /* ptr to enum_list if enum==1 */
+ { /* Values if constant or enum */
+ TYPE_TARGET_INT v_int; /* 2 bytes: int and char values */
+ TYPE_TARGET_CHAR *v_char; /* 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 */
+ double v_float; /* floating point constant value */
+ TYPE_TARGET_ULONG v_fixed16x16; /* 4 bytes: fixed floating point constant value */
+ struct symbol *v_enum; /* ptr to enum_list if enum==1 */
- POINTER = 0, /* pointer to near data */
- FPOINTER, /* pointer to far data */
- CPOINTER, /* pointer to code space */
- GPOINTER, /* _generic pointer */
- PPOINTER, /* paged area pointer */
- IPOINTER, /* pointer to upper 128 bytes */
- UPOINTER, /* unknown pointer used only when parsing */
- EEPPOINTER, /* pointer to eeprom */
+ POINTER = 0, /* pointer to near data */
+ FPOINTER, /* pointer to far data */
+ CPOINTER, /* pointer to code space */
+ GPOINTER, /* _generic pointer */
+ PPOINTER, /* paged area pointer */
+ IPOINTER, /* pointer to upper 128 bytes */
+ UPOINTER, /* unknown pointer used only when parsing */
+ EEPPOINTER, /* pointer to eeprom */
- DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */
- unsigned int num_elem; /* # of elems if type==array */
- unsigned ptr_const:1; /* pointer is constant */
- unsigned ptr_volatile:1; /* pointer is volatile */
- struct sym_link *tspec; /* pointer type specifier */
+ DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */
+ unsigned int 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 */
+ struct sym_link *tspec; /* pointer type specifier */
- 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 intno; /* 1=Interrupt svc 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 */
+ 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 intno; /* 1=Interrupt svc 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 */
- unsigned implicit:1; /* implicit flag */
- unsigned undefined:1; /* undefined variable */
- 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 a 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 quivalent of a symbol */
- unsigned udChked:1; /* use def checking has been already done */
+ 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 lenght 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 a 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 quivalent of a symbol */
+ unsigned udChked:1; /* use def checking has been already done */
- 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 */
- 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 regs *regs[4]; /* can have at the most 4 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. substituion */
- struct symbol *psbase; /* if pseudo symbol, the symbol it is based on */
+ 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 */
+ 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 regs *regs[4]; /* can have at the most 4 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. substituion */
+ struct symbol *psbase; /* if pseudo symbol, the symbol it is based on */
- short bitVar; /* this is a 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 */
+ short bitVar; /* this is a 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 */
/* Easy Access Macros */
#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
/* Easy Access Macros */
#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 SPEC_LONG(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s._long
-#define SPEC_SHORT(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s._short
-#define SPEC_USIGN(x) validateLink(x, "SPEC_USIGN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._unsigned
+#define SPEC_LONG(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_long
+#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_STAT(x) validateLink(x, "SPEC_STAT", #x, SPECIFIER, __FILE__, __LINE__)->select.s._static
-#define SPEC_EXTR(x) validateLink(x, "SPEC_EXTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._extern
+#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_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_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_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_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_VOLATILE(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._volatile
-#define SPEC_CONST(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._const
+#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_TYPEDEF(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._typedef
-#define SPEC_REGPARM(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._isregparm
+#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
DCL_TYPE(x) == CPOINTER || \
DCL_TYPE(x) == UPOINTER ))
#define IS_PTR_CONST(x) (IS_PTR(x) && DCL_PTR_CONST(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)
DCL_TYPE(x) == CPOINTER || \
DCL_TYPE(x) == UPOINTER ))
#define IS_PTR_CONST(x) (IS_PTR(x) && DCL_PTR_CONST(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_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_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_CHAR(x) (IS_SPEC(x) && x->select.s.noun == V_CHAR)
#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_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_CHAR(x) (IS_SPEC(x) && x->select.s.noun == V_CHAR)
/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
extern symbol *__muldiv[3][3][2];
/* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
extern sym_link *__multypes[3][2];
/* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
extern symbol *__conv[2][3][2];
/* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
extern symbol *__muldiv[3][3][2];
/* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
extern sym_link *__multypes[3][2];
/* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
extern symbol *__conv[2][3][2];
-#define CHARTYPE __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 CHARTYPE __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]