1 /*-------------------------------------------------------------------------
2   SDCCsymt.h - Header file for Symbols table related structures and MACRO's.
3 
4   Copyright (C) 1998 Sandeep Dutta . sandeep.dutta@usa.net
5 
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10 
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15 
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 -------------------------------------------------------------------------*/
20 
21 #ifndef  SDCCSYMT_H
22 #define  SDCCSYMT_H
23 
24 #define MAX_NEST_LEVEL  256
25 #define SDCC_SYMNAME_MAX 64
26 #define SDCC_NAME_MAX  3*SDCC_SYMNAME_MAX       // big enough for _<func>_<var>_etc
27 #include "SDCChasht.h"
28 #include "SDCCglobl.h"
29 #include "dbuf.h"
30 
31 #define INTNO_MAX 255           /* maximum allowed interrupt number */
32 #define INTNO_TRAP INTNO_MAX
33 #define INTNO_UNSPEC (INTNO_MAX+1)      /* interrupt number unspecified */
34 
35 
36 #define BITVAR_PAD -1
37 
38 enum
39 {
40   TYPEOF_INT = 1,
41   TYPEOF_SHORT,
42   TYPEOF_BOOL,
43   TYPEOF_CHAR,
44   TYPEOF_LONG,
45   TYPEOF_LONGLONG,
46   TYPEOF_FLOAT,
47   TYPEOF_FIXED16X16,
48   TYPEOF_BIT,
49   TYPEOF_BITFIELD,
50   TYPEOF_SBIT,
51   TYPEOF_SFR,
52   TYPEOF_VOID,
53   TYPEOF_STRUCT,
54   TYPEOF_ARRAY,
55   TYPEOF_FUNCTION,
56   TYPEOF_POINTER,
57   TYPEOF_FPOINTER,
58   TYPEOF_CPOINTER,
59   TYPEOF_GPOINTER,
60   TYPEOF_PPOINTER,
61   TYPEOF_IPOINTER,
62   TYPEOF_EEPPOINTER
63 };
64 
65 // values for first byte (or 3 most significant bits) of generic pointer.
66 #if 0
67 #define GPTYPE_FAR       0x00
68 #define GPTYPE_NEAR      0x40
69 #define GPTYPE_XSTACK    0x60
70 #define GPTYPE_CODE      0x80
71 #else
72 #define GPTYPE_FAR      (port->gp_tags.tag_far)
73 #define GPTYPE_NEAR     (port->gp_tags.tag_near)
74 #define GPTYPE_XSTACK   (port->gp_tags.tag_xstack)
75 #define GPTYPE_CODE     (port->gp_tags.tag_code)
76 #endif
77 
78 #define HASHTAB_SIZE 256
79 
80 /* hash table bucket */
81 typedef struct bucket
82 {
83   void *sym;                    /* pointer to the object      */
84   char name[SDCC_NAME_MAX + 1]; /* name of this symbol        */
85   long level;                   /* nest level for this symbol */
86   int block;                    /* belongs to which block     */
87   struct bucket *prev;          /* ptr 2 previous bucket      */
88   struct bucket *next;          /* ptr 2 next bucket          */
89 }
90 bucket;
91 
92 typedef struct structdef
93 {
94   char tag[SDCC_NAME_MAX + 1];  /* tag part of structure      */
95   long level;                   /* Nesting level              */
96   int block;                    /* belongs to which block     */
97   struct symbol *fields;        /* pointer to fields          */
98   unsigned size;                /* sizeof the table in bytes  */
99   int type;                     /* STRUCT or UNION            */
100   bool b_flexArrayMember;       /* has got a flexible array member,
101                                    only needed for syntax checks */
102   struct symbol *tagsym;        /* tag symbol (NULL if no tag) */
103 }
104 structdef;
105 
106 /* noun definitions */
107 typedef enum
108 {
109   V_INT = 1,
110   V_FLOAT,
111   V_FIXED16X16,
112   V_BOOL,
113   V_CHAR,
114   V_VOID,
115   V_STRUCT,
116   V_LABEL,
117   V_BIT,
118   V_BITFIELD,
119   V_BBITFIELD,
120   V_SBIT,
121   V_DOUBLE
122 }
123 NOUN;
124 
125 /* storage class    */
126 typedef enum
127 {
128   S_FIXED = 0,
129   S_AUTO,
130   S_REGISTER,
131   S_SFR,
132   S_SBIT,
133   S_CODE,
134   S_XDATA,
135   S_DATA,
136   S_IDATA,
137   S_PDATA,
138   S_LITERAL,
139   S_STACK,
140   S_XSTACK,
141   S_BIT,
142   S_EEPROM
143 }
144 STORAGE_CLASS;
145 
146 #define TYPE_TARGET_CHAR  TYPE_BYTE
147 #define TYPE_TARGET_INT   TYPE_WORD
148 #define TYPE_TARGET_LONG  TYPE_DWORD
149 #define TYPE_TARGET_UCHAR TYPE_UBYTE
150 #define TYPE_TARGET_UINT  TYPE_UWORD
151 #define TYPE_TARGET_ULONG TYPE_UDWORD
152 #define TYPE_TARGET_LONGLONG TYPE_QWORD
153 #define TYPE_TARGET_ULONGLONG TYPE_UQWORD
154 
155 /* specifier is the last in the type-chain */
156 typedef struct specifier
157 {
158   NOUN noun;                        /* CHAR INT STRUCTURE LABEL   */
159   STORAGE_CLASS sclass;             /* REGISTER,AUTO,FIX,CONSTANT */
160   struct memmap *oclass;            /* output storage class       */
161   unsigned b_long:1;                /* 1=long                     */
162   unsigned b_longlong:1;            /* 1=long long                */
163   unsigned b_short:1;               /* 1=short int                */
164   unsigned b_unsigned:1;            /* 1=unsigned, 0=signed       */
165   unsigned b_signed:1;              /* just for sanity checks only*/
166   bool     b_implicit_sign:1;       /* signedness not explicitly specified - needed to keep char a separate type from signed char and unsigned char. */
167   unsigned b_static:1;              /* 1=static keyword found     */
168   unsigned b_extern:1;              /* 1=extern found             */
169   unsigned b_inline:1;              /* inline function requested  */
170   unsigned b_noreturn:1;            /* promised not to return     */
171   unsigned b_alignas:1;             /* alignment                  */
172   unsigned b_absadr:1;              /* absolute address specfied  */
173   unsigned b_volatile:1;            /* is marked as volatile      */
174   unsigned b_const:1;               /* is a constant              */
175   unsigned b_restrict:1;            /* is restricted              */
176   struct symbol *addrspace;         /* is in named address space  */
177   unsigned b_typedef:1;             /* is typedefed               */
178   unsigned b_isregparm:1;           /* is the first parameter     */
179   unsigned b_isenum:1;              /* is an enumerated type      */
180   unsigned b_bitUnnamed:1;          /* is an unnamed bit-field    */
181   unsigned b_needspar:1;            /* has to be a parameter      */
182   unsigned _bitStart;               /* bit start position         */
183   unsigned _bitLength;              /* bit length                 */
184   unsigned _addr;                   /* address of symbol          */
185   unsigned _stack;                  /* stack offset for stacked v */
186   int argreg;                       /* reg no for regparm         */
187   union
188   {                                   /* Values if constant or enum */
189     TYPE_TARGET_INT v_int;            /* 2 bytes: int and char values            */
190     const char *v_char;               /*          char character string          */
191     const TYPE_TARGET_UINT *v_char16; /*          char16_t character string      */
192     const TYPE_TARGET_ULONG *v_char32;/*          char32_t character string      */
193     TYPE_TARGET_UINT v_uint;          /* 2 bytes: unsigned int const value       */
194     TYPE_TARGET_LONG v_long;          /* 4 bytes: long constant value            */
195     TYPE_TARGET_ULONG v_ulong;        /* 4 bytes: unsigned long constant value   */
196     TYPE_TARGET_LONGLONG v_longlong;  /* 8 bytes: long long constant value       */
197     TYPE_TARGET_ULONGLONG v_ulonglong;/* 8 bytes: unsigned long long const value */
198     double v_float;                   /*          floating point constant value  */
199     TYPE_TARGET_ULONG v_fixed16x16;   /* 4 bytes: fixed point constant value     */
200     struct symbol *v_enum;            /* ptr to enum_list if enum==1             */
201   }
202   const_val;
203   struct structdef *v_struct;       /* structure pointer      */
204 }
205 specifier;
206 
207 /* types of declarators */
208 typedef enum
209 {
210   UPOINTER = 0,                     /* unknown pointer used only when parsing */
211   POINTER,                          /* pointer to near data  */
212   IPOINTER,                         /* pointer to upper 128 bytes */
213   PPOINTER,                         /* paged area pointer    */
214   FPOINTER,                         /* pointer to far data   */
215   CPOINTER,                         /* pointer to code space */
216   GPOINTER,                         /* generic pointer       */
217   EEPPOINTER,                       /* pointer to eeprom     */
218   ARRAY,
219   FUNCTION
220 }
221 DECLARATOR_TYPE;
222 
223 typedef struct declarator
224 {
225   DECLARATOR_TYPE dcl_type;         /* POINTER,ARRAY or FUNCTION  */
226   size_t num_elem;                  /* # of elems if type==array, */
227   /* always 0 for flexible arrays */
228   unsigned ptr_const:1;             /* pointer is constant        */
229   unsigned ptr_volatile:1;          /* pointer is volatile        */
230   unsigned ptr_restrict:1;          /* pointer is resticted       */
231   struct symbol *ptr_addrspace;     /* pointer is in named address space  */
232 
233   struct sym_link *tspec;           /* pointer type specifier     */
234 }
235 declarator;
236 
237 typedef enum
238 {
239   DECLARATOR = 1,
240   SPECIFIER
241 } SYM_LINK_CLASS;
242 #define DECLSPEC2TXT(select) (select==DECLARATOR?"DECLARATOR":select==SPECIFIER?"SPECIFIER":"UNKNOWN")
243 
244 typedef struct sym_link
245 {
246   SYM_LINK_CLASS xclass;            /* DECLARATOR or SPECIFIER     */
247   unsigned tdef:1;                  /* current link created by     */
248                                     /* typedef if this flag is set */
249   union
250   {
251     specifier s;                    /* if CLASS == SPECIFIER      */
252     declarator d;                   /* if CLASS == DECLARATOR     */
253   } select;
254 
255   /* function attributes */
256   struct
257   {
258     struct value *args;             /* the defined arguments                */
259     unsigned hasVargs:1;            /* functions has varargs                */
260     unsigned calleeSaves:1;         /* functions uses callee save           */
261     unsigned hasbody:1;             /* function body defined                */
262     unsigned hasFcall:1;            /* does it call other functions         */
263     unsigned reent:1;               /* function is reentrant                */
264     unsigned naked:1;               /* naked function                       */
265 
266     unsigned shadowregs:1;          /* function uses shadow registers (pic16 port) */
267     unsigned wparam:1;              /* first byte of arguments is passed via WREG (pic16 port) */
268     unsigned nonbanked:1;           /* function has the nonbanked attribute */
269     unsigned banked:1;              /* function has the banked attribute    */
270     unsigned critical:1;            /* critical function                    */
271     unsigned intrtn:1;              /* this is an interrupt routine         */
272     unsigned rbank:1;               /* seperate register bank               */
273     unsigned inlinereq:1;           /* inlining requested                   */
274     unsigned noreturn:1;            /* promised not to return               */
275     unsigned smallc:1;              /* Parameters on stack are passed in reverse order */
276     unsigned z88dk_fastcall:1;      /* For the z80-related ports: Function has a single paramter of at most 32 bits that is passed in dehl */
277     unsigned z88dk_callee:1;        /* Stack pointer adjustment for parameters passed on the stack is done by the callee */
278     unsigned z88dk_shortcall:1;     /* Short call available via rst (see values later) (Z80 only) */
279     unsigned z88dk_has_params_offset:1;     /* Has a parameter offset (Z80 only) */
280     unsigned intno;                 /* Number of interrupt for interrupt service routine */
281     short regbank;                  /* register bank 2b used                */
282     unsigned builtin;               /* is a builtin function                */
283     unsigned javaNative;            /* is a JavaNative Function (TININative ONLY) */
284     unsigned overlay;               /* force parameters & locals into overlay segment */
285     unsigned hasStackParms;         /* function has parameters on stack     */
286     bool preserved_regs[9];         /* Registers preserved by the function - may be an underestimate */
287     unsigned char z88dk_shortcall_rst;  /* Rst for a short call */
288     unsigned short z88dk_shortcall_val; /* Value for a short call */
289     unsigned short z88dk_params_offset;  /* Additional offset from for arguments */
290   } funcAttrs;
291 
292   struct sym_link *next;            /* next element on the chain  */
293 }
294 sym_link;
295 
296 typedef struct symbol
297 {
298   char name[SDCC_SYMNAME_MAX + 1];  /* Input Variable Name     */
299   char rname[SDCC_NAME_MAX + 1];    /* internal name           */
300 
301   long level;                       /* declaration lev,fld offset */
302   short block;                      /* sequential block # of definition */
303   int seqPoint;                     /* sequence point defined or, if unbound, used */
304   int key;
305   unsigned flexArrayLength;         /* if the symbol specifies a struct
306                                        with a "flexible array member", then the additional length in bytes for
307                                        the "fam" is stored here. Because the length can be different from symbol
308                                        to symbol AND v_struct isn't copied in copyLinkChain(), it's located here
309                                        in the symbol and not in v_struct or the declarator */
310   unsigned implicit:1;              /* implicit flag                     */
311   unsigned undefined:1;             /* undefined variable                */
312   unsigned infertype:1;             /* type should be inferred from first assign */
313   unsigned _isparm:1;               /* is a parameter          */
314   unsigned ismyparm:1;              /* is parameter of the function being generated */
315   unsigned isitmp:1;                /* is an intermediate temp */
316   unsigned islbl:1;                 /* is a temporary label */
317   unsigned isref:1;                 /* has been referenced  */
318   unsigned isind:1;                 /* is an induction variable */
319   unsigned isinvariant:1;           /* is a loop invariant  */
320   unsigned cdef:1;                  /* compiler defined symbol */
321   unsigned addrtaken:1;             /* address of the symbol was taken */
322   unsigned isreqv:1;                /* is the register equivalent of a symbol */
323   unsigned udChked:1;               /* use def checking has been already done */
324   unsigned generated:1;             /* code generated (function symbols only) */
325   unsigned isinscope:1;             /* is in scope */
326 
327   /* following flags are used by the backend
328      for code generation and can be changed
329      if a better scheme for backend is thought of */
330   unsigned isLiveFcall:1;           /* is live at or across a function call */
331   unsigned isspilt:1;               /* has to be spilt */
332   unsigned spillA:1;                /* spilt be register allocator */
333   unsigned remat:1;                 /* can be remateriazed */
334   unsigned isptr:1;                 /* is a pointer */
335   unsigned uptr:1;                  /* used as a pointer */
336   unsigned isFree:1;                /* used by register allocator */
337   unsigned islocal:1;               /* is a local variable        */
338   unsigned blockSpil:1;             /* spilt at block level       */
339   unsigned remainSpil:1;            /* spilt because not used in remainder */
340   unsigned stackSpil:1;             /* has been spilt on temp stack location */
341   unsigned onStack:1;               /* this symbol allocated on the stack */
342   unsigned iaccess:1;               /* indirect access      */
343   unsigned ruonly:1;                /* used in return statement only */
344   unsigned spildir:1;               /* spilt in direct space */
345   unsigned ptrreg:1;                /* this symbol assigned to a ptr reg */
346   unsigned noSpilLoc:1;             /* cannot be assigned a spil location */
347   bool funcDivFlagSafe:1;           /* we know this function is safe to call with undocumented stm8 flag bit 6 set*/
348   bool funcUsesVolatile:1;          /* The function accesses a volatile variable */
349   unsigned isstrlit;                /* is a string literal and it's usage count  */
350   unsigned accuse;                  /* can be left in the accumulator
351                                        On the Z80 accuse is divided into
352                                        ACCUSE_A and ACCUSE_HL as the idea
353                                        is quite similar.
354                                      */
355   unsigned dptr;                    /* 8051 variants with multiple DPTRS
356                                        currently implemented in DS390 only
357                                      */
358   int allocreq;                     /* allocation is required for this variable */
359   int stack;                        /* offset on stack      */
360   int xstack;                       /* offset on xternal stack */
361   short nRegs;                      /* number of registers required */
362   short regType;                    /* type of register required    */
363 
364   struct reg_info *regs[8];         /* can have at the most 8 registers */
365   struct asmop *aop;                /* asmoperand for this symbol */
366   struct iCode *fuse;               /* furthest use */
367   struct iCode *rematiCode;         /* rematerialise with which instruction */
368   struct operand *reqv;             /* register equivalent of a local variable */
369   struct symbol *prereqv;           /* symbol before register equiv. substitution */
370   struct symbol *psbase;            /* if pseudo symbol, the symbol it is based on */
371   union
372   {
373     struct symbol *spillLoc;        /* register spil location */
374     struct set *itmpStack;          /* symbols spilt @ this stack location */
375   }
376   usl;
377   int bitVar;                       /* if bitVar != 0: this is a bit variable, bitVar is the size in bits */
378   unsigned bitUnnamed:1;            /* unnamed bit variable */
379   unsigned offset;                  /* offset from top if struct */
380 
381   int lineDef;                      /* defined line number        */
382   char *fileDef;                    /* defined filename           */
383   int lastLine;                     /* for functions the last line */
384   struct sym_link *type;            /* 1st link to declarator chain */
385   struct sym_link *etype;           /* last link to declarator chain */
386   struct symbol *next;              /* crosslink to next symbol   */
387   struct symbol *localof;           /* local variable of which function */
388   struct initList *ival;            /* ptr to initializer if any  */
389   struct bitVect *defs;             /* bit vector for definitions */
390   struct bitVect *uses;             /* bit vector for uses        */
391   struct bitVect *regsUsed;         /* for functions registers used */
392   int liveFrom;                     /* live from iCode sequence number */
393   int liveTo;                       /* live to sequence number */
394   int used;                         /* no. of times this was used */
395   int recvSize;                     /* size of first argument  */
396   struct bitVect *clashes;          /* overlaps with what other symbols */
397   struct ast *funcTree;             /* function body ast if inlined */
398   struct symbol *addressmod[2];     /* access functions for named address spaces */
399 
400   bool for_newralloc;
401 }
402 symbol;
403 
404 extern sym_link *validateLink (sym_link * l,
405                                const char *macro, const char *args, const char select, const char *file, unsigned line);
406 /* Easy Access Macros */
407 #define IS_OP_RUONLY(x) (IS_SYMOP(x) && OP_SYMBOL(x) && OP_SYMBOL(x)->ruonly)
408 #define IS_OP_ACCUSE(x) (IS_SYMOP(x) && OP_SYMBOL(x) && OP_SYMBOL(x)->accuse)
409 
410 #define DCL_TYPE(l)  validateLink(l, "DCL_TYPE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.dcl_type
411 #define DCL_ELEM(l)  validateLink(l, "DCL_ELEM", #l, DECLARATOR, __FILE__, __LINE__)->select.d.num_elem
412 #define DCL_PTR_CONST(l) validateLink(l, "DCL_PTR_CONST", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_const
413 #define DCL_PTR_VOLATILE(l) validateLink(l, "DCL_PTR_VOLATILE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_volatile
414 #define DCL_PTR_RESTRICT(l) validateLink(l, "DCL_PTR_RESTRICT", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_restrict
415 #define DCL_PTR_ADDRSPACE(l) validateLink(l, "DCL_PTR_ADDRSPACE", #l, DECLARATOR, __FILE__, __LINE__)->select.d.ptr_addrspace
416 #define DCL_TSPEC(l) validateLink(l, "DCL_TSPEC", #l, DECLARATOR, __FILE__, __LINE__)->select.d.tspec
417 
418 #define FUNC_DEBUG              //assert(IS_FUNC(x));
419 #define FUNC_HASVARARGS(x) (x->funcAttrs.hasVargs)
420 #define IFFUNC_HASVARARGS(x) (IS_FUNC(x) && FUNC_HASVARARGS(x))
421 #define FUNC_ARGS(x) (x->funcAttrs.args)
422 #define IFFUNC_ARGS(x) (IS_FUNC(x) && FUNC_ARGS(x))
423 #define FUNC_HASFCALL(x) (x->funcAttrs.hasFcall)
424 #define IFFUNC_HASFCALL(x) (IS_FUNC(x) && FUNC_HASFCALL(x))
425 #define FUNC_HASBODY(x) (x->funcAttrs.hasbody)
426 #define IFFUNC_HASBODY(x) (IS_FUNC(x) && FUNC_HASBODY(x))
427 #define FUNC_CALLEESAVES(x) (x->funcAttrs.calleeSaves)
428 #define IFFUNC_CALLEESAVES(x) (IS_FUNC(x) && FUNC_CALLEESAVES(x))
429 #define FUNC_ISISR(x) (x->funcAttrs.intrtn)
430 #define IFFUNC_ISISR(x) (IS_FUNC(x) && FUNC_ISISR(x))
431 #define FUNC_INTNO(x) (x->funcAttrs.intno)
432 #define FUNC_REGBANK(x) (x->funcAttrs.regbank)
433 #define FUNC_HASSTACKPARM(x) (x->funcAttrs.hasStackParms)
434 #define FUNC_ISINLINE(x) (x->funcAttrs.inlinereq)
435 #define IFFUNC_ISINLINE(x) (IS_FUNC(x) && FUNC_ISINLINE(x))
436 #define FUNC_ISNORETURN(x) (x->funcAttrs.noreturn)
437 #define IFFUNC_ISNORETURN(x) (IS_FUNC(x) && FUNC_ISNORETURN(x))
438 
439 #define FUNC_ISREENT(x) (x->funcAttrs.reent)
440 #define IFFUNC_ISREENT(x) (IS_FUNC(x) && FUNC_ISREENT(x))
441 #define FUNC_ISSHADOWREGS(x) (x->funcAttrs.shadowregs)
442 #define IFFUNC_ISSHADOWREGS(x) (IS_FUNC(x) && FUNC_ISSHADOWREGS(x))
443 #define FUNC_ISWPARAM(x) (x->funcAttrs.wparam)
444 #define IFFUNC_ISWPARAM(x) (IS_FUNC(x) && FUNC_ISWPARAM(x))
445 #define FUNC_ISNAKED(x) (x->funcAttrs.naked)
446 #define IFFUNC_ISNAKED(x) (IS_FUNC(x) && FUNC_ISNAKED(x))
447 #define FUNC_NONBANKED(x) (x->funcAttrs.nonbanked)
448 #define IFFUNC_NONBANKED(x) (IS_FUNC(x) && FUNC_NONBANKED(x))
449 #define FUNC_BANKED(x) (x->funcAttrs.banked)
450 #define IFFUNC_BANKED(x) (IS_FUNC(x) && FUNC_BANKED(x))
451 #define FUNC_ISCRITICAL(x) (x->funcAttrs.critical)
452 #define IFFUNC_ISCRITICAL(x) (IS_FUNC(x) && FUNC_ISCRITICAL(x))
453 #define FUNC_ISBUILTIN(x) (x->funcAttrs.builtin)
454 #define IFFUNC_ISBUILTIN(x) (IS_FUNC(x) && FUNC_ISBUILTIN(x))
455 #define FUNC_ISJAVANATIVE(x) (x->funcAttrs.javaNative)
456 #define IFFUNC_ISJAVANATIVE(x) (IS_FUNC(x) && FUNC_ISJAVANATIVE(x))
457 #define FUNC_ISOVERLAY(x) (x->funcAttrs.overlay)
458 #define IFFUNC_ISOVERLAY(x) (IS_FUNC(x) && FUNC_ISOVERLAY(x))
459 #define FUNC_ISSMALLC(x) (x->funcAttrs.smallc)
460 #define IFFUNC_ISSMALLC(x) (IS_FUNC(x) && FUNC_ISSMALLC(x))
461 #define FUNC_ISZ88DK_FASTCALL(x) (x->funcAttrs.z88dk_fastcall)
462 #define IFFUNC_ISZ88DK_FASTCALL(x) (IS_FUNC(x) && FUNC_ISZ88DK_FASTCALL(x))
463 #define FUNC_ISZ88DK_CALLEE(x) (x->funcAttrs.z88dk_callee)
464 #define IFFUNC_ISZ88DK_CALLEE(x) (IS_FUNC(x) && FUNC_ISZ88DK_CALLEE(x))
465 #define FUNC_ISZ88DK_SHORTCALL(x) (x->funcAttrs.z88dk_shortcall)
466 #define IFFUNC_ISZ88DK_SHORTCALL(x) (IS_FUNC(x) && FUNC_ISZ88DK_SHORTCALL(x))
467 
468 #define BANKED_FUNCTIONS        ( options.model == MODEL_HUGE || \
469                                   ( (options.model == MODEL_LARGE || options.model == MODEL_MEDIUM) && \
470                                     TARGET_Z80_LIKE ) )
471 #define IFFUNC_ISBANKEDCALL(x)  ( IS_FUNC(x) && \
472                                   ( FUNC_BANKED(x) || ( BANKED_FUNCTIONS && !FUNC_NONBANKED(x) ) ) )
473 
474 #define SPEC_NOUN(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.noun
475 #define SPEC_LONG(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_long
476 #define SPEC_LONGLONG(x) validateLink(x, "SPEC_LONGLONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_longlong
477 #define SPEC_SHORT(x) validateLink(x, "SPEC_LONG", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_short
478 #define SPEC_USIGN(x) validateLink(x, "SPEC_USIGN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_unsigned
479 #define SPEC_SIGN(x) validateLink(x, "SPEC_SIGN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_signed
480 #define SPEC_SCLS(x) validateLink(x, "SPEC_SCLS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.sclass
481 #define SPEC_ENUM(x) validateLink(x, "SPEC_ENUM", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_isenum
482 #define SPEC_OCLS(x) validateLink(x, "SPEC_OCLS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.oclass
483 #define SPEC_STAT(x) validateLink(x, "SPEC_STAT", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_static
484 #define SPEC_EXTR(x) validateLink(x, "SPEC_EXTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_extern
485 #define SPEC_CODE(x) validateLink(x, "SPEC_CODE", #x, SPECIFIER, __FILE__, __LINE__)->select.s._codesg
486 #define SPEC_ABSA(x) validateLink(x, "SPEC_ABSA", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_absadr
487 #define SPEC_BANK(x) validateLink(x, "SPEC_BANK", #x, SPECIFIER, __FILE__, __LINE__)->select.s._regbank
488 #define SPEC_ADDR(x) validateLink(x, "SPEC_ADDR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._addr
489 #define SPEC_STAK(x) validateLink(x, "SPEC_STAK", #x, SPECIFIER, __FILE__, __LINE__)->select.s._stack
490 #define SPEC_CVAL(x) validateLink(x, "SPEC_CVAL", #x, SPECIFIER, __FILE__, __LINE__)->select.s.const_val
491 #define SPEC_BSTR(x) validateLink(x, "SPEC_BSTR", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitStart
492 #define SPEC_BLEN(x) validateLink(x, "SPEC_BLEN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitLength
493 #define SPEC_BUNNAMED(x) validateLink(x, "SPEC_BUNNAMED", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_bitUnnamed
494 #define SPEC_NEEDSPAR(x) validateLink(x, "SPEC_NEEDSPAR", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_needspar
495 
496 /* Sleaze: SPEC_ISR_SAVED_BANKS is only used on
497  * function type symbols, which obviously cannot
498  * be of BIT type. Therefore, we recycle the
499  * _bitStart field instead of defining a new field.
500  */
501 #define SPEC_ISR_SAVED_BANKS(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s._bitStart
502 #define SPEC_VOLATILE(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_volatile
503 #define SPEC_CONST(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_const
504 #define SPEC_RESTRICT(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_restrict
505 #define SPEC_ADDRSPACE(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.addrspace
506 #define SPEC_STRUCT(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.v_struct
507 #define SPEC_TYPEDEF(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_typedef
508 #define SPEC_REGPARM(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_isregparm
509 #define SPEC_ARGREG(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.argreg
510 #define SPEC_INLINE(x) validateLink(x, "SPEC_INLINE", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_inline
511 #define SPEC_NORETURN(x) validateLink(x, "SPEC_NORETURN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_noreturn
512 #define SPEC_ALIGNAS(x) validateLink(x, "SPEC_ALIGNAS", #x, SPECIFIER, __FILE__, __LINE__)->select.s.b_alignas
513 
514 /* type check macros */
515 #define IS_DECL(x)       ( x && x->xclass == DECLARATOR )
516 #define IS_SPEC(x)       ( x && x->xclass == SPECIFIER  )
517 
518 #define IS_ARRAY(x)      (IS_DECL(x) && DCL_TYPE(x) == ARRAY)
519 #define IS_DATA_PTR(x)   (IS_DECL(x) && DCL_TYPE(x) == POINTER)
520 #define IS_SMALL_PTR(x)  (IS_DECL(x) && (DCL_TYPE(x) == POINTER    ||    \
521                                          DCL_TYPE(x) == IPOINTER   ||    \
522                                          DCL_TYPE(x) == PPOINTER  ))
523 #define IS_PTR(x)        (IS_DECL(x) && (DCL_TYPE(x) == POINTER    ||    \
524                                          DCL_TYPE(x) == FPOINTER   ||    \
525                                          DCL_TYPE(x) == GPOINTER   ||    \
526                                          DCL_TYPE(x) == IPOINTER   ||    \
527                                          DCL_TYPE(x) == PPOINTER   ||    \
528                                          DCL_TYPE(x) == EEPPOINTER ||    \
529                                          DCL_TYPE(x) == CPOINTER   ||    \
530                                          DCL_TYPE(x) == UPOINTER  ))
531 #define IS_PTR_CONST(x)  (IS_PTR(x) && DCL_PTR_CONST(x))
532 #define IS_PTR_RESTRICT(x) (IS_PTR(x) && DCL_PTR_RESTRICT(x))
533 #define IS_FARPTR(x)     (IS_DECL(x) && DCL_TYPE(x) == FPOINTER)
534 #define IS_CODEPTR(x)    (IS_DECL(x) && DCL_TYPE(x) == CPOINTER)
535 #define IS_GENPTR(x)     (IS_DECL(x) && DCL_TYPE(x) == GPOINTER)
536 #define IS_FUNCPTR(x)    (IS_DECL(x) && (DCL_TYPE(x) == CPOINTER || DCL_TYPE(x) == GPOINTER) && IS_FUNC(x->next))
537 #define IS_FUNC(x)       (IS_DECL(x) && DCL_TYPE(x) == FUNCTION)
538 #define IS_LONG(x)       (IS_SPEC(x) && x->select.s.b_long)
539 #define IS_LONGLONG(x)   (IS_SPEC(x) && x->select.s.b_longlong)
540 #define IS_UNSIGNED(x)   (IS_SPEC(x) && x->select.s.b_unsigned)
541 #define IS_TYPEDEF(x)    (IS_SPEC(x) && x->select.s.b_typedef)
542 #define IS_CONSTANT(x)   (isConstant (x))
543 #define IS_RESTRICT(x)   (isRestrict (x))
544 #define IS_STRUCT(x)     (IS_SPEC(x) && x->select.s.noun == V_STRUCT)
545 #define IS_ABSOLUTE(x)   (IS_SPEC(x) && x->select.s.b_absadr )
546 #define IS_REGISTER(x)   (IS_SPEC(x) && SPEC_SCLS(x) == S_REGISTER)
547 #define IS_RENT(x)       (IS_SPEC(x) && x->select.s._reent )
548 #define IS_STATIC(x)     (IS_SPEC(x) && SPEC_STAT(x))
549 #define IS_INLINE(x)     (IS_SPEC(x) && SPEC_INLINE(x))
550 #define IS_NORETURN(x)   (IS_SPEC(x) && SPEC_NORETURN(x))
551 #define IS_INT(x)        (IS_SPEC(x) && x->select.s.noun == V_INT)
552 #define IS_VOID(x)       (IS_SPEC(x) && x->select.s.noun == V_VOID)
553 #define IS_BOOL(x)       (IS_SPEC(x) && x->select.s.noun == V_BOOL)
554 #define IS_CHAR(x)       (IS_SPEC(x) && x->select.s.noun == V_CHAR)
555 #define IS_EXTERN(x)     (IS_SPEC(x) && x->select.s.b_extern)
556 #define IS_VOLATILE(x)   (isVolatile (x))
557 #define IS_INTEGRAL(x)   (IS_SPEC(x) && (x->select.s.noun == V_INT       || \
558                                          x->select.s.noun == V_BOOL      || \
559                                          x->select.s.noun == V_CHAR      || \
560                                          x->select.s.noun == V_BITFIELD  || \
561                                          x->select.s.noun == V_BBITFIELD || \
562                                          x->select.s.noun == V_BIT       || \
563                                          x->select.s.noun == V_SBIT ))
564 #define IS_BITFIELD(x)   (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD  || \
565                                          x->select.s.noun == V_BBITFIELD ))
566 #define IS_BITVAR(x)     (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD  || \
567                                          x->select.s.noun == V_BBITFIELD || \
568                                          x->select.s.noun == V_BIT       || \
569                                          x->select.s.noun == V_SBIT ))
570 #define IS_BIT(x)        (IS_SPEC(x) && (x->select.s.noun == V_BIT       || \
571                                          x->select.s.noun == V_SBIT ))
572 #define IS_BOOLEAN(x)    (IS_SPEC(x) && (x->select.s.noun == V_BIT       || \
573                                          x->select.s.noun == V_SBIT      || \
574                                          x->select.s.noun == V_BBITFIELD || \
575                                          x->select.s.noun == V_BOOL ))
576 #define IS_FLOAT(x)      (IS_SPEC(x) && x->select.s.noun == V_FLOAT)
577 #define IS_FIXED16X16(x) (IS_SPEC(x) && x->select.s.noun == V_FIXED16X16)
578 #define IS_FIXED(x)      (IS_FIXED16X16(x))
579 #define IS_ARITHMETIC(x) (IS_INTEGRAL(x) || IS_FLOAT(x) || IS_FIXED(x))
580 #define IS_AGGREGATE(x)  (IS_ARRAY(x) || IS_STRUCT(x))
581 #define IS_LITERAL(x)    (IS_SPEC(x) && x->select.s.sclass == S_LITERAL)
582 #define IS_CODE(x)       (IS_SPEC(x) && SPEC_SCLS(x) == S_CODE)
583 #define IS_REGPARM(x)    (IS_SPEC(x) && SPEC_REGPARM(x))
584 
585 #define IS_VALID_PARAMETER_STORAGE_CLASS_SPEC(x)    (!SPEC_TYPEDEF(x) && !SPEC_EXTR(x) && !SPEC_STAT(x) && SPEC_SCLS(x) != S_AUTO)
586 
587 /* symbol check macros */
588 #define IS_AUTO(x)       (x->level && !IS_STATIC(x->etype) && !IS_EXTERN(x->etype))
589 
590 /* forward declaration for the global vars */
591 extern bucket *SymbolTab[];
592 extern bucket *StructTab[];
593 extern bucket *TypedefTab[];
594 extern bucket *LabelTab[];
595 extern bucket *enumTab[];
596 extern bucket *AddrspaceTab[];
597 extern symbol *fsadd;
598 extern symbol *fssub;
599 extern symbol *fsmul;
600 extern symbol *fsdiv;
601 extern symbol *fseq;
602 extern symbol *fsneq;
603 extern symbol *fslt;
604 
605 extern symbol *fps16x16_add;
606 extern symbol *fps16x16_sub;
607 extern symbol *fps16x16_mul;
608 extern symbol *fps16x16_div;
609 extern symbol *fps16x16_eq;
610 extern symbol *fps16x16_neq;
611 extern symbol *fps16x16_lt;
612 extern symbol *fps16x16_lteq;
613 extern symbol *fps16x16_gt;
614 extern symbol *fps16x16_gteq;
615 
616 /* Dims: mul/div/mod, BYTE/WORD/DWORD/QWORD, SIGNED/UNSIGNED/BOTH */
617 extern symbol *muldiv[3][4][4];
618 /* 16 x 16 -> 32 multiplication SIGNED/UNSIGNED */
619 extern symbol *muls16tos32[2];
620 /* Dims: BYTE/WORD/DWORD/QWORD SIGNED/UNSIGNED */
621 extern sym_link *multypes[4][2];
622 /* Dims: to/from float, BYTE/WORD/DWORD/QWORD, SIGNED/USIGNED */
623 extern symbol *conv[2][4][2];
624 /* Dims: to/from fixed16x16, BYTE/WORD/DWORD/QWORD/FLOAT, SIGNED/USIGNED */
625 extern symbol *fp16x16conv[2][5][2];
626 /* Dims: shift left/shift right, BYTE/WORD/DWORD/QWORD, SIGNED/UNSIGNED */
627 extern symbol *rlrr[2][4][2];
628 
629 extern symbol *memcpy_builtin;
630 
631 #define SCHARTYPE       multypes[0][0]
632 #define UCHARTYPE       multypes[0][1]
633 #define INTTYPE         multypes[1][0]
634 #define UINTTYPE        multypes[1][1]
635 #define LONGTYPE        multypes[2][0]
636 #define ULONGTYPE       multypes[2][1]
637 #define LONGLONGTYPE    multypes[3][0]
638 #define ULONGLONGTYPE   multypes[3][1]
639 
640 extern sym_link *floatType;
641 extern sym_link *fixed16x16Type;
642 
643 #include "SDCCval.h"
644 
645 typedef enum
646 {
647   RESULT_TYPE_NONE = 0,         /* operands will be promoted to int */
648   RESULT_TYPE_BOOL,
649   RESULT_TYPE_CHAR,
650   RESULT_TYPE_INT,
651   RESULT_TYPE_OTHER,            /* operands will be promoted to int */
652   RESULT_TYPE_IFX,
653   RESULT_TYPE_GPTR              /* operands will be promoted to generic ptr */
654 } RESULT_TYPE;
655 
656 /* forward definitions for the symbol table related functions */
657 void initSymt ();
658 symbol *newSymbol (const char *, long);
659 sym_link *newLink (SYM_LINK_CLASS);
660 sym_link *newFloatLink ();
661 structdef *newStruct (const char *);
662 void addDecl (symbol *, int, sym_link *);
663 sym_link *finalizeSpec (sym_link *);
664 sym_link *mergeSpec (sym_link *, sym_link *, const char *name);
665 sym_link *mergeDeclSpec (sym_link *, sym_link *, const char *name);
666 symbol *reverseSyms (symbol *);
667 sym_link *reverseLink (sym_link *);
668 symbol *copySymbol (const symbol *);
669 symbol *copySymbolChain (const symbol *);
670 void printSymChain (symbol *, int);
671 void printStruct (structdef *, int);
672 char *genSymName (long);
673 sym_link *getSpec (sym_link *);
674 int compStructSize (int, structdef *);
675 sym_link *copyLinkChain (const sym_link *);
676 int checkDecl (symbol *, int);
677 void checkBasic (sym_link *, sym_link *);
678 value *checkPointerIval (sym_link *, value *);
679 value *checkStructIval (symbol *, value *);
680 value *checkArrayIval (sym_link *, value *);
681 value *checkIval (sym_link *, value *);
682 unsigned int getSize (sym_link *);
683 unsigned int bitsForType (sym_link *);
684 sym_link *newIntLink ();
685 sym_link *newCharLink ();
686 sym_link *newLongLink ();
687 sym_link *newBoolLink ();
688 sym_link *newVoidLink ();
689 int compareType (sym_link *, sym_link *);
690 int compareTypeExact (sym_link *, sym_link *, long);
691 int compareTypeInexact (sym_link *, sym_link *);
692 int checkFunction (symbol *, symbol *);
693 void cleanUpLevel (bucket **, long);
694 void cleanUpBlock (bucket **, int);
695 symbol *getAddrspace (sym_link *type);
696 int funcInChain (sym_link *);
697 void addSymChain (symbol **);
698 sym_link *structElemType (sym_link *, value *);
699 symbol *getStructElement (structdef *, symbol *);
700 sym_link *computeType (sym_link *, sym_link *, RESULT_TYPE, int);
701 void processFuncPtrArgs (sym_link *);
702 void processFuncArgs (symbol *);
703 int isSymbolEqual (const symbol *, const symbol *);
704 int powof2 (TYPE_TARGET_ULONG);
705 void dbuf_printTypeChain (sym_link *, struct dbuf_s *);
706 void printTypeChain (sym_link *, FILE *);
707 void printTypeChainRaw (sym_link *, FILE *);
708 void initCSupport ();
709 void initBuiltIns ();
710 void pointerTypes (sym_link *, sym_link *);
711 void cdbStructBlock (int);
712 void initHashT ();
713 bucket *newBucket ();
714 void addSym (bucket **, void *, char *, long, int, int checkType);
715 void deleteSym (bucket **, void *, const char *);
716 void *findSym (bucket **, void *, const char *);
717 void *findSymWithLevel (bucket **, struct symbol *);
718 void *findSymWithBlock (bucket **, struct symbol *, int, long);
719 void changePointer (sym_link * p);
720 void checkTypeSanity (sym_link * etype, const char *name);
721 sym_link *typeFromStr (const char *);
722 STORAGE_CLASS sclsFromPtr (sym_link * ptr);
723 sym_link *newEnumType (symbol *);
724 void promoteAnonStructs (int, structdef *);
725 int isConstant (sym_link * type);
726 int isVolatile (sym_link * type);
727 int isRestrict (sym_link * type);
728 value *aggregateToPointer (value *);
729 
730 
731 extern char *nounName (sym_link *);     /* noun strings */
732 extern void printFromToType (sym_link *, sym_link *);
733 
734 #endif
735