1 /*-------------------------------------------------------------------------
2 SDCCsymt.h - Header file for Symbols table related structures and MACRO's.
3 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 In other words, you are welcome to use, share and improve this program.
20 You are forbidden to forbid anyone else to use, share and improve
21 what you give them. Help stamp out software-hoarding!
22 -------------------------------------------------------------------------*/
27 #define MAX_NEST_LEVEL 256
28 #define SDCC_SYMNAME_MAX 64
29 #define SDCC_NAME_MAX 3*SDCC_SYMNAME_MAX // big enough for _<func>_<var>_etc
30 #include "SDCChasht.h"
33 #define HASHTAB_SIZE 256
35 /* hash table bucket */
38 void *sym; /* pointer to the object */
39 char name[SDCC_NAME_MAX + 1]; /* name of this symbol */
40 int level; /* nest level for this symbol */
41 int block; /* belongs to which block */
42 struct bucket *prev; /* ptr 2 previous bucket */
43 struct bucket *next; /* ptr 2 next bucket */
47 typedef struct structdef
49 char tag[SDCC_NAME_MAX + 1]; /* tag part of structure */
50 unsigned char level; /* Nesting level */
51 struct symbol *fields; /* pointer to fields */
52 unsigned size; /* sizeof the table in bytes */
56 /* noun definitions */
92 /* specifier is the last in the type-chain */
93 typedef struct specifier
95 NOUN noun; /* CHAR INT STRUCTURE LABEL */
96 STORAGE_CLASS sclass; /* REGISTER,AUTO,FIX,CONSTANT */
97 struct memmap *oclass; /* output storage class */
98 unsigned _long:1; /* 1=long */
99 unsigned _short:1; /* 1=short int */
100 unsigned _unsigned:1; /* 1=unsigned, 0=signed */
101 unsigned _signed:1; /* just for sanity checks only*/
102 unsigned _static:1; /* 1=static keyword found */
103 unsigned _extern:1; /* 1=extern found */
104 unsigned _absadr:1; /* absolute address specfied */
105 unsigned _volatile:1; /* is marked as volatile */
106 unsigned _const:1; /* is a constant */
107 unsigned _typedef:1; /* is typedefed */
108 unsigned _isregparm:1; /* is the first parameter */
109 unsigned _isenum:1; /* is an enumerated type */
110 unsigned _addr; /* address of symbol */
111 unsigned _stack; /* stack offset for stacked v */
112 unsigned _bitStart; /* bit start position */
113 int _bitLength; /* bit length */
116 { /* Values if constant or enum */
117 short int v_int; /* int and char values */
118 char *v_char; /* character string */
119 unsigned short v_uint; /* unsigned int const value */
120 long v_long; /* long constant value */
121 unsigned long v_ulong; /* unsigned long constant val */
122 double v_float; /* floating point constant value */
123 struct symbol *v_enum; /* ptr 2 enum_list if enum==1 */
126 struct structdef *v_struct; /* structure pointer */
130 /* types of declarators */
133 POINTER = 0, /* pointer to near data */
134 FPOINTER, /* pointer to far data */
135 CPOINTER, /* pointer to code space */
136 GPOINTER, /* _generic pointer */
137 PPOINTER, /* paged area pointer */
138 IPOINTER, /* pointer to upper 128 bytes */
139 UPOINTER, /* unknown pointer used only when parsing */
140 EEPPOINTER, /* pointer to eeprom */
146 typedef struct declarator
148 DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */
149 unsigned int num_elem; /* # of elems if type==array */
150 short ptr_const:1; /* pointer is constant */
151 short ptr_volatile:1; /* pointer is volatile */
152 struct sym_link *tspec; /* pointer type specifier */
159 typedef struct sym_link
161 unsigned class:1; /* DECLARATOR or SPECIFIER */
162 unsigned tdef:1; /* current link created by */
163 /* typedef if this flag is set */
166 specifier s; /* if CLASS == SPECIFIER */
167 declarator d; /* if CLASS == DECLARATOR */
170 /* function attributes */
172 struct value *args; /* the defined arguments */
173 unsigned hasVargs:1; /* functions has varargs */
174 unsigned calleeSaves:1; /* functions uses callee save */
175 unsigned hasbody:1; /* function body defined */
176 //unsigned ret:1; /* return statement for a function */
177 unsigned hasFcall:1; /* does it call other functions */
178 unsigned reent:1; /* function is reentrant */
179 unsigned naked:1; /* naked function */
181 unsigned nonbanked:1; /* function has the nonbanked attribute */
182 unsigned banked:1; /* function has the banked attribute */
183 unsigned critical:1; /* critical function */
184 unsigned intrtn:1; /* this is an interrupt routin */
185 unsigned rbank:1; /* seperate register bank */
186 unsigned intno; /* 1=Interrupt svc routine */
187 unsigned regbank; /* register bank 2b used */
188 unsigned builtin; /* is a builtin function */
191 struct sym_link *next; /* next element on the chain */
195 typedef struct symbol
197 char name[SDCC_SYMNAME_MAX + 1]; /* Input Variable Name */
198 char rname[SDCC_NAME_MAX + 1]; /* internal name */
200 short level; /* declration lev,fld offset */
201 short block; /* sequential block # of defintion */
203 unsigned implicit:1; /* implicit flag */
204 unsigned undefined:1; /* undefined variable */
205 unsigned _isparm:1; /* is a parameter */
206 unsigned ismyparm:1; /* is parameter of the function being generated */
207 unsigned isitmp:1; /* is an intermediate temp */
208 unsigned islbl:1; /* is a temporary label */
209 unsigned isref:1; /* has been referenced */
210 unsigned isind:1; /* is a induction variable */
211 unsigned isinvariant:1; /* is a loop invariant */
212 unsigned isstrlit:1; /* is a string literal */
213 unsigned cdef:1; /* compiler defined symbol */
214 unsigned addrtaken:1; /* address of the symbol was taken */
215 unsigned isreqv:1; /* is the register quivalent of a symbol */
216 unsigned udChked:1; /* use def checking has been already done */
218 /* following flags are used by the backend
219 for code generation and can be changed
220 if a better scheme for backend is thought of */
221 unsigned isLiveFcall:1; /* is live at or across a function call */
222 unsigned isspilt:1; /* has to be spilt */
223 unsigned spillA:1; /* spilt be register allocator */
224 unsigned remat:1; /* can be remateriazed */
225 unsigned isptr:1; /* is a pointer */
226 unsigned uptr:1; /* used as a pointer */
227 unsigned isFree:1; /* used by register allocator */
228 unsigned islocal:1; /* is a local variable */
229 unsigned blockSpil:1; /* spilt at block level */
230 unsigned remainSpil:1; /* spilt because not used in remainder */
231 unsigned stackSpil:1; /* has been spilt on temp stack location */
232 unsigned onStack:1; /* this symbol allocated on the stack */
233 unsigned iaccess:1; /* indirect access */
234 unsigned ruonly:1; /* used in return statement only */
235 unsigned spildir:1; /* spilt in direct space */
236 unsigned ptrreg:1; /* this symbol assigned to a ptr reg */
237 unsigned noSpilLoc:1; /* cannot be assigned a spil location */
238 unsigned accuse; /* can be left in the accumulator
239 On the Z80 accuse is devided into
240 ACCUSE_A and ACCUSE_HL as the idea
244 int allocreq ; /* allocation is required for this variable */
245 int stack; /* offset on stack */
246 int xstack; /* offset on xternal stack */
247 short nRegs; /* number of registers required */
248 short regType; /* type of register required */
250 struct regs *regs[4]; /* can have at the most 4 registers */
251 struct asmop *aop; /* asmoperand for this symbol */
252 struct iCode *fuse; /* furthest use */
253 struct iCode *rematiCode; /* rematerialse with which instruction */
254 struct operand *reqv; /* register equivalent of a local variable */
257 struct symbol *spillLoc; /* register spil location */
258 struct set *itmpStack; /* symbols spilt @ this stack location */
261 short bitVar; /* this is a bit variable */
262 unsigned offset; /* offset from top if struct */
264 int lineDef; /* defined line number */
265 int lastLine; /* for functions the last line */
266 struct sym_link *type; /* 1st link to declator chain */
267 struct sym_link *etype; /* last link to declarator chn */
268 struct symbol *next; /* crosslink to next symbol */
269 struct symbol *localof; /* local variable of which function */
270 struct initList *ival; /* ptr to initializer if any */
271 struct bitVect *defs; /* bit vector for definitions */
272 struct bitVect *uses; /* bit vector for uses */
273 struct bitVect *regsUsed; /* for functions registers used */
274 int liveFrom; /* live from iCode sequence number */
275 int liveTo; /* live to sequence number */
276 int used; /* no. of times this was used */
277 int recvSize; /* size of first argument */
278 struct bitVect *clashes; /* overlaps with what other symbols */
282 /* Easy Access Macros */
283 #define DCL_TYPE(l) l->select.d.dcl_type
284 #define DCL_ELEM(l) l->select.d.num_elem
285 #define DCL_PTR_CONST(l) l->select.d.ptr_const
286 #define DCL_PTR_VOLATILE(l) l->select.d.ptr_volatile
287 #define DCL_TSPEC(l) l->select.d.tspec
289 #define FUNC_DEBUG //assert(IS_FUNC(x));
290 #define FUNC_HASVARARGS(x) (x->funcAttrs.hasVargs)
291 #define IFFUNC_HASVARARGS(x) (IS_FUNC(x) && FUNC_HASVARARGS(x))
292 #define FUNC_ARGS(x) (x->funcAttrs.args)
293 #define IFFUNC_ARGS(x) (IS_FUNC(x) && FUNC_ARGS(x))
294 #define FUNC_HASFCALL(x) (x->funcAttrs.hasFcall)
295 #define IFFUNC_HASFCALL(x) (IS_FUNC(x) && FUNC_HASFCALL(x))
296 #define FUNC_HASBODY(x) (x->funcAttrs.hasbody)
297 #define IFFUNC_HASBODY(x) (IS_FUNC(x) && FUNC_HASBODY(x))
298 #define FUNC_CALLEESAVES(x) (x->funcAttrs.calleeSaves)
299 #define IFFUNC_CALLEESAVES(x) (IS_FUNC(x) && FUNC_CALLEESAVES(x))
300 #define FUNC_ISISR(x) (x->funcAttrs.intrtn)
301 #define IFFUNC_ISISR(x) (IS_FUNC(x) && FUNC_ISISR(x))
302 //#define FUNC_RBANK(x) (x->funcAttrs.rbank)
303 #define IFFUNC_RBANK(x) (IS_FUNC(x) && FUNC_RBANK(x))
304 #define FUNC_INTNO(x) (x->funcAttrs.intno)
305 #define FUNC_REGBANK(x) (x->funcAttrs.regbank)
307 #define FUNC_ISREENT(x) (x->funcAttrs.reent)
308 #define IFFUNC_ISREENT(x) (IS_FUNC(x) && FUNC_ISREENT(x))
309 #define FUNC_ISNAKED(x) (x->funcAttrs.naked)
310 #define IFFUNC_ISNAKED(x) (IS_FUNC(x) && FUNC_ISNAKED(x))
311 #define FUNC_NONBANKED(x) (x->funcAttrs.nonbanked)
312 #define IFFUNC_NONBANKED(x) (IS_FUNC(x) && FUNC_NONBANKED(x))
313 #define FUNC_BANKED(x) (x->funcAttrs.banked)
314 #define IFFUNC_BANKED(x) (IS_FUNC(x) && FUNC_BANKED(x))
315 #define FUNC_ISCRITICAL(x) (x->funcAttrs.critical)
316 #define IFFUNC_ISCRITICAL(x) (IS_FUNC(x) && FUNC_ISCRITICAL(x))
317 #define FUNC_ISBUILTIN(x) (x->funcAttrs.builtin)
318 #define IFFUNC_ISBUILTIN(x) (IS_FUNC(x) && FUNC_ISBUILTIN(x))
320 // jwk: I am not sure about this
321 #define IFFUNC_ISBANKEDCALL(x) (!IFFUNC_NONBANKED(x) && \
322 (options.model == MODEL_LARGE || \
323 options.model == MODEL_MEDIUM || \
326 #define SPEC_NOUN(x) x->select.s.noun
327 #define SPEC_LONG(x) x->select.s._long
328 #define SPEC_USIGN(x) x->select.s._unsigned
329 #define SPEC_SCLS(x) x->select.s.sclass
330 #define SPEC_ENUM(x) x->select.s._isenum
331 #define SPEC_OCLS(x) x->select.s.oclass
332 #define SPEC_STAT(x) x->select.s._static
333 #define SPEC_EXTR(x) x->select.s._extern
334 #define SPEC_CODE(x) x->select.s._codesg
335 #define SPEC_ABSA(x) x->select.s._absadr
336 #define SPEC_BANK(x) x->select.s._regbank
337 #define SPEC_ADDR(x) x->select.s._addr
338 #define SPEC_STAK(x) x->select.s._stack
339 #define SPEC_CVAL(x) x->select.s.const_val
340 #define SPEC_BSTR(x) x->select.s._bitStart
341 #define SPEC_BLEN(x) x->select.s._bitLength
343 /* Sleaze: SPEC_ISR_SAVED_BANKS is only used on
344 * function type symbols, which obviously cannot
345 * be of BIT type. Therefore, we recycle the
346 * _bitStart field instead of defining a new field.
348 #define SPEC_ISR_SAVED_BANKS(x) x->select.s._bitStart
349 #define SPEC_VOLATILE(x) x->select.s._volatile
350 #define SPEC_CONST(x) x->select.s._const
351 #define SPEC_STRUCT(x) x->select.s.v_struct
352 #define SPEC_TYPEDEF(x) x->select.s._typedef
353 #define SPEC_REGPARM(x) x->select.s._isregparm
355 /* type check macros */
356 #define IS_DECL(x) ( x && x->class == DECLARATOR )
357 #define IS_SPEC(x) ( x && x->class == SPECIFIER )
358 #define IS_ARRAY(x) (IS_DECL(x) && DCL_TYPE(x) == ARRAY)
359 #define IS_DATA_PTR(x) (IS_DECL(x) && DCL_TYPE(x) == POINTER)
360 #define IS_PTR(x) (IS_DECL(x) && (DCL_TYPE(x) == POINTER || \
361 DCL_TYPE(x) == FPOINTER || \
362 DCL_TYPE(x) == GPOINTER || \
363 DCL_TYPE(x) == IPOINTER || \
364 DCL_TYPE(x) == PPOINTER || \
365 DCL_TYPE(x) == EEPPOINTER || \
366 DCL_TYPE(x) == CPOINTER || \
367 DCL_TYPE(x) == UPOINTER ))
368 #define IS_PTR_CONST(x) (IS_PTR(x) && DCL_PTR_CONST(x))
369 #define IS_FARPTR(x) (IS_DECL(x) && DCL_TYPE(x) == FPOINTER)
370 #define IS_CODEPTR(x) (IS_DECL(x) && DCL_TYPE(x) == CPOINTER)
371 #define IS_GENPTR(x) (IS_DECL(x) && DCL_TYPE(x) == GPOINTER)
372 #define IS_FUNC(x) (IS_DECL(x) && DCL_TYPE(x) == FUNCTION)
373 #define IS_LONG(x) (IS_SPEC(x) && x->select.s._long)
374 #define IS_TYPEDEF(x)(IS_SPEC(x) && x->select.s._typedef)
375 #define IS_CONSTANT(x) (IS_SPEC(x) && ( x->select.s._const == 1))
376 #define IS_STRUCT(x) (IS_SPEC(x) && x->select.s.noun == V_STRUCT)
377 #define IS_ABSOLUTE(x) (IS_SPEC(x) && x->select.s._absadr )
378 #define IS_REGISTER(x) (IS_SPEC(x) && SPEC_SCLS(x) == S_REGISTER)
379 #define IS_RENT(x) (IS_SPEC(x) && x->select.s._reent )
380 #define IS_STATIC(x) (IS_SPEC(x) && SPEC_STAT(x))
381 #define IS_INT(x) (IS_SPEC(x) && x->select.s.noun == V_INT)
382 #define IS_VOID(x) (IS_SPEC(x) && x->select.s.noun == V_VOID)
383 #define IS_CHAR(x) (IS_SPEC(x) && x->select.s.noun == V_CHAR)
384 #define IS_EXTERN(x) (IS_SPEC(x) && x->select.s._extern)
385 #define IS_VOLATILE(x) (IS_SPEC(x) && x->select.s._volatile )
386 #define IS_INTEGRAL(x) (IS_SPEC(x) && (x->select.s.noun == V_INT || \
387 x->select.s.noun == V_CHAR || \
388 x->select.s.noun == V_BIT || \
389 x->select.s.noun == V_SBIT ))
390 #define IS_BITFIELD(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT))
391 #define IS_BITVAR(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT || \
392 x->select.s.noun == V_SBIT ))
393 #define IS_FLOAT(x) (IS_SPEC(x) && x->select.s.noun == V_FLOAT)
394 #define IS_ARITHMETIC(x) (IS_INTEGRAL(x) || IS_FLOAT(x))
395 #define IS_AGGREGATE(x) (IS_ARRAY(x) || IS_STRUCT(x))
396 #define IS_LITERAL(x) (IS_SPEC(x) && x->select.s.sclass == S_LITERAL)
397 #define IS_REGPARM(x) (IS_SPEC(x) && SPEC_REGPARM(x))
399 /* forward declaration for the global vars */
400 extern bucket *SymbolTab[];
401 extern bucket *StructTab[];
402 extern bucket *TypedefTab[];
403 extern bucket *LabelTab[];
404 extern bucket *enumTab[];
405 extern symbol *__fsadd;
406 extern symbol *__fssub;
407 extern symbol *__fsmul;
408 extern symbol *__fsdiv;
409 extern symbol *__fseq;
410 extern symbol *__fsneq;
411 extern symbol *__fslt;
412 extern symbol *__fslteq;
413 extern symbol *__fsgt;
414 extern symbol *__fsgteq;
416 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
417 extern symbol *__muldiv[3][3][2];
418 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
419 extern sym_link *__multypes[3][2];
420 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
421 extern symbol *__conv[2][3][2];
422 /* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
423 extern symbol *__rlrr[2][3][2];
425 #define CHARTYPE __multypes[0][0]
426 #define UCHARTYPE __multypes[0][1]
427 #define INTTYPE __multypes[1][0]
428 #define UINTTYPE __multypes[1][1]
429 #define LONGTYPE __multypes[2][0]
430 #define ULONGTYPE __multypes[2][1]
433 extern sym_link *floatType;
437 /* forward definitions for the symbol table related functions */
439 symbol *newSymbol (char *, int);
440 sym_link *newLink ();
441 sym_link *newFloatLink ();
442 structdef *newStruct (char *);
443 void addDecl (symbol *, int, sym_link *);
444 sym_link *mergeSpec (sym_link *, sym_link *, char *name);
445 sym_link *cloneSpec (sym_link *);
446 symbol *reverseSyms (symbol *);
447 sym_link *reverseLink (sym_link *);
448 symbol *copySymbol (symbol *);
449 symbol *copySymbolChain (symbol *);
450 void printSymChain (symbol *, int);
451 void printStruct (structdef *, int);
452 char *genSymName (int);
453 sym_link *getSpec (sym_link *);
454 char *genSymName (int);
455 int compStructSize (int, structdef *);
456 sym_link *copyLinkChain (sym_link *);
457 int checkDecl (symbol *, int);
458 void checkBasic (sym_link *, sym_link *);
459 value *checkPointerIval (sym_link *, value *);
460 value *checkStructIval (symbol *, value *);
461 value *checkArrayIval (sym_link *, value *);
462 value *checkIval (sym_link *, value *);
463 unsigned int getSize (sym_link *);
464 unsigned int bitsForType (sym_link *);
465 sym_link *newIntLink ();
466 sym_link *newCharLink ();
467 sym_link *newLongLink ();
468 int compareType (sym_link *, sym_link *);
469 int checkFunction (symbol *, symbol *);
470 void cleanUpLevel (bucket **, int);
471 void cleanUpBlock (bucket **, int);
472 int funcInChain (sym_link *);
473 void addSymChain (symbol *);
474 sym_link *structElemType (sym_link *, value *);
475 symbol *getStructElement (structdef *, symbol *);
476 sym_link *computeType (sym_link *, sym_link *);
477 void processFuncArgs (symbol *);
478 int isSymbolEqual (symbol *, symbol *);
479 int powof2 (unsigned long);
480 void printTypeChain (sym_link *, FILE *);
481 void initCSupport ();
482 void initBuiltIns ();
483 void pointerTypes (sym_link *, sym_link *);
484 void cdbTypeInfo (sym_link *, FILE *);
485 void cdbSymbol (symbol *, FILE *, int, int);
486 void cdbStructBlock (int, FILE *);
488 bucket *newBucket ();
489 void addSym (bucket **, void *, char *, int, int, int checkType);
490 void deleteSym (bucket **, void *, char *);
491 void *findSym (bucket **, void *, const char *);
492 void *findSymWithLevel (bucket **, struct symbol *);
493 void *findSymWithBlock (bucket **, struct symbol *, int);
494 void changePointer (symbol * sym);
495 void checkTypeSanity(sym_link *etype, char *name);
496 sym_link *typeFromStr (char *) ;
499 extern char *nounName(sym_link *); /* noun strings */
500 extern void printFromToType (sym_link *, sym_link *);