1 /*-------------------------------------------------------------------------
2 SDCCsymt.c - Code 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 -------------------------------------------------------------------------*/
26 bucket *SymbolTab [256] ; /* the symbol table */
27 bucket *StructTab [256] ; /* the structure table */
28 bucket *TypedefTab[256] ; /* the typedef table */
29 bucket *LabelTab [256] ; /* the Label table */
30 bucket *enumTab [256] ; /* enumerated table */
32 extern struct set *publics;
34 /*------------------------------------------------------------------*/
35 /* initSymt () - initialises symbol table related stuff */
36 /*------------------------------------------------------------------*/
41 for ( i = 0 ; i < 256 ; i++ )
42 SymbolTab[i] = StructTab[i] = (void *) NULL ;
46 /*-----------------------------------------------------------------*/
47 /* newBucket - allocates & returns a new bucket */
48 /*-----------------------------------------------------------------*/
53 ALLOC(bp,sizeof(bucket));
58 /*-----------------------------------------------------------------*/
59 /* hashKey - computes the hashkey given a symbol name */
60 /*-----------------------------------------------------------------*/
63 unsigned long key = 0;
70 /*-----------------------------------------------------------------*/
71 /* addSym - adds a symbol to the hash Table */
72 /*-----------------------------------------------------------------*/
73 void addSym ( bucket **stab ,
79 int i ; /* index into the hash Table */
80 bucket *bp ; /* temp bucket * */
82 /* the symbols are always added at the head of the list */
84 /* get a free entry */
85 ALLOC(bp,sizeof(bucket));
87 bp->sym = sym ; /* update the symbol pointer */
88 bp->level = level; /* update the nest level */
90 strcpy(bp->name,sname); /* copy the name into place */
92 /* if this is the first entry */
93 if (stab[i] == NULL) {
94 bp->prev = bp->next = (void *) NULL ; /* point to nothing */
97 /* not first entry then add @ head of list */
106 /*-----------------------------------------------------------------*/
107 /* deleteSym - deletes a symbol from the hash Table entry */
108 /*-----------------------------------------------------------------*/
109 void deleteSym ( bucket **stab, void *sym, char *sname)
117 /* find the symbol */
119 if (bp->sym == sym) /* found it then break out */
120 break ; /* of the loop */
124 if (!bp) /* did not find it */
126 /* if this is the first one in the chain */
129 if ( stab[i] ) /* if chain ! empty */
130 stab[i]->prev = (void *) NULL ;
132 /* middle || end of chain */
134 if ( bp->next ) /* if not end of chain */
135 bp->next->prev = bp->prev ;
137 bp->prev->next = bp->next ;
142 /*-----------------------------------------------------------------*/
143 /* findSym - finds a symbol in a table */
144 /*-----------------------------------------------------------------*/
145 void *findSym ( bucket **stab, void *sym, char *sname)
149 bp = stab[hashKey(sname)] ;
152 if ( bp->sym == sym || strcmp (bp->name,sname) == 0 )
157 return ( bp ? bp->sym : (void *) NULL ) ;
160 /*-----------------------------------------------------------------*/
161 /* findSymWithLevel - finds a symbol with a name & level */
162 /*-----------------------------------------------------------------*/
163 void *findSymWithLevel ( bucket **stab, symbol *sym)
167 bp = stab[hashKey(sym->name)];
170 ** do the search from the head of the list since the
171 ** elements are added at the head it is ensured that
172 ** we will find the deeper definitions before we find
173 ** the global ones. we need to check for symbols with
174 ** level <= to the level given, if levels match then block
175 ** numbers need to match as well
179 if ( strcmp(bp->name,sym->name) == 0 && bp->level <= sym->level) {
180 /* if this is parameter then nothing else need to be checked */
181 if (((symbol *)(bp->sym))->_isparm)
183 /* if levels match then block numbers hsould also match */
184 if (bp->level && bp->level == sym->level && bp->block == sym->block )
186 /* if levels don't match then we are okay */
187 if (bp->level && bp->level != sym->level)
189 /* if this is a global variable then we are ok too */
197 return (void *) NULL ;
200 /*-----------------------------------------------------------------*/
201 /* findSymWithBlock - finds a symbol with name in with a block */
202 /*-----------------------------------------------------------------*/
203 void *findSymWithBlock ( bucket **stab, symbol *sym, int block)
207 bp = stab[hashKey(sym->name)] ;
210 if ( strcmp (bp->name,sym->name) == 0 &&
216 return ( bp ? bp->sym : (void *) NULL ) ;
219 /*------------------------------------------------------------------*/
220 /* newSymbol () - returns a new pointer to a symbol */
221 /*------------------------------------------------------------------*/
222 symbol *newSymbol (char *name, int scope )
226 ALLOC(sym,sizeof(symbol));
228 strcpy(sym->name,name); /* copy the name */
229 sym->level = scope ; /* set the level */
230 sym->block = currBlockno ;
231 sym->lineDef = yylineno ; /* set the line number */
235 /*------------------------------------------------------------------*/
236 /* newLink - creates a new link (declarator,specifier) */
237 /*------------------------------------------------------------------*/
242 ALLOC(p,sizeof(link));
247 /*------------------------------------------------------------------*/
248 /* newStruct - creats a new structdef from the free list */
249 /*------------------------------------------------------------------*/
250 structdef *newStruct ( char *tag )
254 ALLOC(s,sizeof(structdef));
256 strcpy(s->tag,tag) ; /* copy the tag */
260 /*------------------------------------------------------------------*/
261 /* pointerTypes - do the computation for the pointer types */
262 /*------------------------------------------------------------------*/
263 void pointerTypes (link *ptr, link *type)
268 /* find the first pointer type */
269 while (ptr && !IS_PTR(ptr))
272 /* could not find it */
273 if (!ptr || IS_SPEC(ptr) ||
274 DCL_TYPE(ptr) != UPOINTER)
277 /* change the pointer type depending on the
278 storage class of the type */
280 DCL_PTR_CONST(ptr) = SPEC_CONST(type);
281 DCL_PTR_VOLATILE(ptr) = SPEC_VOLATILE(type);
282 switch (SPEC_SCLS(type)) {
284 DCL_TYPE(ptr) = FPOINTER;
287 DCL_TYPE(ptr) = IPOINTER ;
290 DCL_TYPE(ptr) = PPOINTER ;
293 DCL_TYPE(ptr) = POINTER ;
296 DCL_PTR_CONST(ptr) = 1;
297 DCL_TYPE(ptr) = CPOINTER ;
300 DCL_TYPE(ptr) = GPOINTER;
303 /* the storage class of type ends here */
306 SPEC_VOLATILE(type) = 0;
309 /* now change all the remaining unknown pointers
310 to generic pointers */
312 if (!IS_SPEC(ptr) && DCL_TYPE(ptr) == UPOINTER)
313 DCL_TYPE(ptr) = GPOINTER;
317 /* same for the type although it is highly unlikely that
318 type will have a pointer */
320 if (!IS_SPEC(type) && DCL_TYPE(type) == UPOINTER)
321 DCL_TYPE(type) = GPOINTER;
327 /*------------------------------------------------------------------*/
328 /* addDecl - adds a declarator @ the end of a chain */
329 /*------------------------------------------------------------------*/
330 void addDecl ( symbol *sym, int type , link *p )
336 /* if we are passed a link then set head & tail */
343 head = tail = newLink() ;
344 DCL_TYPE(head) = type ;
347 /* if this is the first entry */
353 if ( IS_SPEC(sym->etype) && IS_SPEC(head) && head == tail ) {
354 sym->etype = mergeSpec(sym->etype,head);
357 if ( IS_SPEC(sym->etype) && !IS_SPEC(head) && head == tail ) {
359 while (t->next != sym->etype) t = t->next ;
361 tail->next = sym->etype;
363 sym->etype->next = head;
369 /* if the type is a unknown pointer and has
370 a tspec then take the storage class const & volatile
371 attribute from the tspec & make it those of this
375 DCL_TYPE(p) == UPOINTER &&
377 if (!IS_SPEC(sym->etype)) {
378 sym->etype = sym->etype->next = newLink();
379 sym->etype->class = SPECIFIER;
381 SPEC_SCLS(sym->etype) = SPEC_SCLS(DCL_TSPEC(p));
382 SPEC_CONST(sym->etype) = SPEC_CONST(DCL_TSPEC(p));
383 SPEC_VOLATILE(sym->etype) = SPEC_VOLATILE(DCL_TSPEC(p));
389 /*------------------------------------------------------------------*/
390 /* mergeSpec - merges two specifiers and returns the new one */
391 /*------------------------------------------------------------------*/
392 link *mergeSpec ( link *dest, link *src )
394 /* if noun different then src overrides */
395 if ( SPEC_NOUN(dest) != SPEC_NOUN(src) && !SPEC_NOUN(dest))
396 SPEC_NOUN(dest) = SPEC_NOUN(src) ;
398 if (! SPEC_SCLS(dest)) /* if destination has no storage class */
399 SPEC_SCLS(dest) = SPEC_SCLS(src) ;
401 /* copy all the specifications */
402 SPEC_LONG(dest) |= SPEC_LONG(src);
403 SPEC_SHORT(dest) |= SPEC_SHORT(src);
404 SPEC_USIGN(dest) |= SPEC_USIGN(src);
405 SPEC_STAT(dest) |= SPEC_STAT(src);
406 SPEC_EXTR(dest) |= SPEC_EXTR(src);
407 SPEC_ABSA(dest) |= SPEC_ABSA(src);
408 SPEC_RENT(dest) |= SPEC_RENT(src);
409 SPEC_INTN(dest) |= SPEC_INTN(src);
410 SPEC_BANK(dest) |= SPEC_BANK(src);
411 SPEC_VOLATILE(dest) |= SPEC_VOLATILE(src);
412 SPEC_CRTCL(dest) |= SPEC_CRTCL(src);
413 SPEC_ADDR(dest) |= SPEC_ADDR(src);
414 SPEC_OCLS(dest) = SPEC_OCLS(src);
415 SPEC_BLEN(dest) |= SPEC_BLEN(src);
416 SPEC_BSTR(dest) |= SPEC_BSTR(src);
417 SPEC_TYPEDEF(dest) |= SPEC_TYPEDEF(src);
419 if ( IS_STRUCT(dest) && SPEC_STRUCT(dest) == NULL )
420 SPEC_STRUCT(dest) = SPEC_STRUCT(src);
425 /*------------------------------------------------------------------*/
426 /* cloneSpec - copies the entire spec and returns a new spec */
427 /*------------------------------------------------------------------*/
428 link *cloneSpec ( link *src )
432 /* go thru chain till we find the specifier */
433 while ( src && src->class != SPECIFIER )
437 memcpy (spec,src,sizeof(link));
441 /*------------------------------------------------------------------*/
442 /* genSymName - generates and returns a name used for anonymous vars*/
443 /*------------------------------------------------------------------*/
444 char *genSymName ( int level )
446 static int gCount = 0 ;
447 static char gname[SDCC_NAME_MAX+1] ;
449 sprintf (gname,"__%04d%04d",level,gCount++);
453 /*------------------------------------------------------------------*/
454 /* getSpec - returns the specifier part from a declaration chain */
455 /*------------------------------------------------------------------*/
456 link *getSpec ( link *p )
461 while ( p && ! (IS_SPEC(p)))
467 /*------------------------------------------------------------------*/
468 /* newCharLink() - creates an int type */
469 /*------------------------------------------------------------------*/
475 p->class = SPECIFIER ;
476 SPEC_NOUN(p) = V_CHAR ;
481 /*------------------------------------------------------------------*/
482 /* newFloatLink - a new Float type */
483 /*------------------------------------------------------------------*/
489 p->class = SPECIFIER ;
490 SPEC_NOUN(p) = V_FLOAT ;
495 /*------------------------------------------------------------------*/
496 /* newLongLink() - new long type */
497 /*------------------------------------------------------------------*/
503 p->class = SPECIFIER ;
504 SPEC_NOUN(p) = V_INT ;
510 /*------------------------------------------------------------------*/
511 /* newIntLink() - creates an int type */
512 /*------------------------------------------------------------------*/
518 p->class = SPECIFIER ;
519 SPEC_NOUN(p) = V_INT ;
524 /*------------------------------------------------------------------*/
525 /* getSize - returns size of a type chain in bits */
526 /*------------------------------------------------------------------*/
527 unsigned int getSize ( link *p )
529 /* if nothing return 0 */
533 if ( IS_SPEC(p) ) { /* if this is the specifier then */
535 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
537 return (IS_LONG(p) ? LONGSIZE : ( IS_SHORT(p) ? SHORTSIZE: INTSIZE)) ;
545 return SPEC_STRUCT(p)->size ;
551 return ((SPEC_BLEN(p) / 8) + (SPEC_BLEN(p) % 8 ? 1 : 0)) ;
557 /* this is a specifier */
558 switch (DCL_TYPE(p)) {
562 return DCL_ELEM(p) * getSize (p->next) ;
578 /*------------------------------------------------------------------*/
579 /* bitsForType - returns # of bits required to store this type */
580 /*------------------------------------------------------------------*/
581 unsigned int bitsForType ( link *p )
583 /* if nothing return 0 */
587 if ( IS_SPEC(p) ) { /* if this is the specifier then */
589 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
591 return (IS_LONG(p) ? LONGSIZE*8 : ( IS_SHORT(p) ? SHORTSIZE*8: INTSIZE*8)) ;
599 return SPEC_STRUCT(p)->size*8 ;
611 /* this is a specifier */
612 switch (DCL_TYPE(p)) {
616 return DCL_ELEM(p) * getSize (p->next) *8 ;
620 return ( PTRSIZE * 8) ;
623 return ( FPTRSIZE * 8);
625 return ( GPTRSIZE * 8);
632 /*------------------------------------------------------------------*/
633 /* copySymbolChain - copies a symbol chain */
634 /*------------------------------------------------------------------*/
635 symbol *copySymbolChain (symbol *src)
642 dest = copySymbol(src);
643 dest->next = copySymbolChain(src->next);
647 /*------------------------------------------------------------------*/
648 /* copySymbol - makes a copy of a symbol */
649 /*------------------------------------------------------------------*/
650 symbol *copySymbol (symbol *src)
657 dest = newSymbol( src->name, src->level );
658 memcpy(dest,src,sizeof(symbol));
659 dest->level = src->level ;
660 dest->block = src->block ;
661 dest->ival = copyIlist(src->ival);
662 dest->type = copyLinkChain(src->type);
663 dest->etype= getSpec(dest->type);
665 dest->args = copyValueChain (src->args);
666 dest->key = src->key;
667 dest->calleeSave = src->calleeSave;
668 dest->allocreq = src->allocreq;
672 /*------------------------------------------------------------------*/
673 /* reverseSyms - reverses the links for a symbol chain */
674 /*------------------------------------------------------------------*/
675 symbol *reverseSyms ( symbol *sym)
677 symbol *prev , *curr, *next ;
692 sym->next = (void *) NULL ;
696 /*------------------------------------------------------------------*/
697 /* reverseLink - reverses the links for a type chain */
698 /*------------------------------------------------------------------*/
699 link *reverseLink ( link *type)
701 link *prev , *curr, *next ;
716 type->next = (void *) NULL ;
720 /*------------------------------------------------------------------*/
721 /* addSymChain - adds a symbol chain to the symboltable */
722 /*------------------------------------------------------------------*/
723 void addSymChain ( symbol *symHead )
725 symbol *sym = symHead ;
726 symbol *csym = NULL ;
728 for (;sym != NULL ; sym = sym->next ) {
730 /* if already exists in the symbol table then check if
731 the previous was an extern definition if yes then
732 then check if the type match, if the types match then
733 delete the current entry and add the new entry */
734 if ((csym = findSymWithLevel (SymbolTab,sym)) &&
735 csym->level == sym->level) {
737 /* previous definition extern ? */
738 if ( IS_EXTERN(csym->etype) ) {
739 /* do types match ? */
740 if (checkType ( csym->type,sym->type) != 1)
742 werror (E_DUPLICATE,csym->name);
744 /* delete current entry */
745 deleteSym (SymbolTab, csym, csym->name );
747 addSym (SymbolTab, sym, sym->name, sym->level,sym->block);
748 } else /* not extern */
749 werror(E_DUPLICATE,sym->name) ;
753 /* check if previously defined */
754 if (csym && csym->level == sym->level ) {
755 /* if the previous one was declared as extern */
756 /* then check the type with the current one */
757 if ( IS_EXTERN(csym->etype) ) {
758 if ( checkType (csym->type, sym->type ) <= 0 )
759 werror (W_EXTERN_MISMATCH,csym->name);
763 addSym (SymbolTab,sym,sym->name,sym->level,sym->block) ;
768 /*------------------------------------------------------------------*/
769 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
770 /*------------------------------------------------------------------*/
771 int funcInChain (link *lnk)
781 /*------------------------------------------------------------------*/
782 /* structElemType - returns the type info of a sturct member */
783 /*------------------------------------------------------------------*/
784 link *structElemType (link *stype, value *id ,value **argsp)
786 symbol *fields = (SPEC_STRUCT(stype) ? SPEC_STRUCT(stype)->fields : NULL);
788 if ( ! fields || ! id)
791 /* look for the id */
793 if (strcmp(fields->rname,id->name) == 0) {
795 *argsp = fields->args;
797 return copyLinkChain (fields->type) ;
799 fields = fields->next ;
801 werror(E_NOT_MEMBER,id->name);
806 /*------------------------------------------------------------------*/
807 /* getStructElement - returns element of a tructure definition */
808 /*------------------------------------------------------------------*/
809 symbol *getStructElement ( structdef *sdef, symbol *sym)
813 for ( field = sdef->fields ; field ; field = field->next )
814 if ( strcmp(field->name,sym->name) == 0)
817 werror(E_NOT_MEMBER,sym->name);
819 return sdef->fields ;
822 /*------------------------------------------------------------------*/
823 /* compStructSize - computes the size of a structure */
824 /*------------------------------------------------------------------*/
825 int compStructSize (int su, structdef *sdef )
827 int sum = 0 , usum =0;
831 /* for the identifiers */
832 loop = sdef->fields ;
835 /* create the internal name for this variable */
836 sprintf (loop->rname,"_%s",loop->name);
837 loop->offset = ( su == UNION ? sum = 0 : sum ) ;
838 SPEC_VOLATILE(loop->etype) |= (su == UNION ? 1 : 0);
840 /* if this is a bit field */
843 /* change it to a unsigned bit */
844 SPEC_NOUN(loop->etype) = V_BIT ;
845 SPEC_USIGN(loop->etype) = 1 ;
846 /* check if this fit into the remaining */
847 /* bits of this byte else align it to the */
848 /* next byte boundary */
849 if ((SPEC_BLEN(loop->etype)=loop->bitVar) <= (8 - bitOffset)) {
850 SPEC_BSTR(loop->etype) = bitOffset ;
851 sum += (loop->bitVar / 8) ;
852 bitOffset += (loop->bitVar % 8);
854 else /* does not fit */
857 loop->offset++; /* go to the next byte */
859 SPEC_BSTR(loop->etype) = bitOffset ;
860 sum += (loop->bitVar / 8) ;
861 bitOffset += (loop->bitVar % 8);
863 /* if this is the last field then pad */
864 if (!loop->next && bitOffset) {
871 sum += getSize (loop->type) ;
874 /* if function then do the arguments for it */
875 if (funcInChain(loop->type)) {
876 processFuncArgs (loop, 1);
881 /* if this is not a bitfield but the */
882 /* previous one was and did not take */
883 /* the whole byte then pad the rest */
884 if ((loop && !loop->bitVar) && bitOffset) {
889 /* if union then size = sizeof larget field */
891 usum = max(usum,sum);
895 return (su == UNION ? usum : sum);
898 /*------------------------------------------------------------------*/
899 /* checkSClass - check the storage class specification */
900 /*------------------------------------------------------------------*/
901 static void checkSClass ( symbol *sym )
903 /* type is literal can happen foe enums change
905 if (SPEC_SCLS(sym->etype) == S_LITERAL && !SPEC_ENUM(sym->etype))
906 SPEC_SCLS(sym->etype) = S_AUTO;
908 /* if sfr or sbit then must also be */
909 /* volatile the initial value will be xlated */
910 /* to an absolute address */
911 if (SPEC_SCLS(sym->etype) == S_SBIT ||
912 SPEC_SCLS(sym->etype) == S_SFR ) {
913 SPEC_VOLATILE(sym->etype) = 1;
914 /* if initial value given */
916 SPEC_ABSA(sym->etype) = 1;
917 SPEC_ADDR(sym->etype) =
918 (int) list2int(sym->ival);
923 /* if absolute address given then it mark it as
925 if (IS_ABSOLUTE(sym->etype))
926 SPEC_VOLATILE(sym->etype) = 1;
928 /* global variables declared const put into code */
929 if (sym->level == 0 &&
930 SPEC_SCLS(sym->etype) == S_CONSTANT)
931 SPEC_SCLS(sym->etype) = S_CODE ;
934 /* global variable in code space is a constant */
935 if (sym->level == 0 &&
936 SPEC_SCLS(sym->etype) == S_CODE)
937 SPEC_CONST(sym->etype) = 1;
940 /* if bit variable then no storage class can be */
941 /* specified since bit is already a storage */
942 if ( IS_BITVAR(sym->etype) &&
943 ( SPEC_SCLS(sym->etype) != S_FIXED &&
944 SPEC_SCLS(sym->etype) != S_SBIT &&
945 SPEC_SCLS(sym->etype) != S_BIT )
947 werror (E_BITVAR_STORAGE,sym->name);
948 SPEC_SCLS(sym->etype) = S_FIXED ;
951 /* extern variables cannot be initialized */
952 if (IS_EXTERN(sym->etype) && sym->ival) {
953 werror(E_EXTERN_INIT,sym->name);
957 /* if this is an automatic symbol then */
958 /* storage class will be ignored and */
959 /* symbol will be allocated on stack/ */
960 /* data depending on flag */
962 (options.stackAuto || reentrant ) &&
963 ( SPEC_SCLS(sym->etype) != S_AUTO &&
964 SPEC_SCLS(sym->etype) != S_FIXED &&
965 SPEC_SCLS(sym->etype) != S_REGISTER &&
966 SPEC_SCLS(sym->etype) != S_CONSTANT )) {
968 werror(E_AUTO_ASSUMED,sym->name) ;
969 SPEC_SCLS(sym->etype) = S_AUTO ;
972 /* automatic symbols cannot be given */
973 /* an absolute address ignore it */
975 SPEC_ABSA(sym->etype) &&
976 (options.stackAuto || reentrant) ) {
977 werror(E_AUTO_ABSA,sym->name);
978 SPEC_ABSA(sym->etype) = 0 ;
981 /* arrays & pointers cannot be defined for bits */
982 /* SBITS or SFRs or BIT */
983 if ((IS_ARRAY(sym->type) || IS_PTR(sym->type)) &&
984 ( SPEC_NOUN(sym->etype) == V_BIT ||
985 SPEC_NOUN(sym->etype) == V_SBIT ||
986 SPEC_SCLS(sym->etype) == S_SFR ))
987 werror(E_BIT_ARRAY,sym->name);
989 /* if this is a bit|sbit then set length & start */
990 if (SPEC_NOUN(sym->etype) == V_BIT ||
991 SPEC_NOUN(sym->etype) == V_SBIT ) {
992 SPEC_BLEN(sym->etype) = 1 ;
993 SPEC_BSTR(sym->etype) = 0 ;
996 /* variables declared in CODE space must have */
997 /* initializers if not an extern */
998 if (SPEC_SCLS(sym->etype) == S_CODE &&
1001 !IS_EXTERN(sym->etype))
1002 werror(E_CODE_NO_INIT,sym->name);
1004 /* if parameter or local variable then change */
1005 /* the storage class to reflect where the var will go */
1006 if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) {
1007 if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype)))
1008 SPEC_SCLS(sym->etype) = (options.model ?
1009 S_XSTACK : S_STACK ) ;
1011 SPEC_SCLS(sym->etype) = (options.model ?
1016 /*------------------------------------------------------------------*/
1017 /* changePointer - change pointer to functions */
1018 /*------------------------------------------------------------------*/
1019 void changePointer (symbol *sym)
1023 /* go thru the chain of declarations */
1024 /* if we find a pointer to a function */
1025 /* unconditionally change it to a ptr */
1027 for ( p = sym->type ; p ; p = p->next) {
1028 if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER)
1029 DCL_TYPE(p) = GPOINTER ;
1030 if ( IS_PTR(p) && IS_FUNC(p->next))
1031 DCL_TYPE(p) = CPOINTER ;
1035 /*------------------------------------------------------------------*/
1036 /* checkDecl - does semantic validation of a declaration */
1037 /*------------------------------------------------------------------*/
1038 int checkDecl ( symbol *sym )
1041 checkSClass (sym); /* check the storage class */
1042 changePointer(sym); /* change pointers if required */
1044 /* if this is an array without any dimension
1045 then update the dimension from the initial value */
1046 if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type))
1047 DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival);
1052 /*------------------------------------------------------------------*/
1053 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1054 /*------------------------------------------------------------------*/
1055 link *copyLinkChain ( link *p)
1057 link *head, *curr , *loop;
1060 head = loop = ( curr ? newLink() : (void *) NULL) ;
1062 memcpy(loop,curr,sizeof(link)) ; /* copy it */
1063 loop->next = (curr->next ? newLink() : (void *) NULL) ;
1072 /*------------------------------------------------------------------*/
1073 /* cleanUpBlock - cleansup the symbol table specified for all the */
1074 /* symbols in the given block */
1075 /*------------------------------------------------------------------*/
1076 void cleanUpBlock ( bucket **table, int block)
1081 /* go thru the entire table */
1082 for ( i = 0 ; i < 256; i++ ) {
1083 for ( chain = table[i]; chain ; chain = chain->next ) {
1084 if (chain->block >= block) {
1085 deleteSym (table,chain->sym,chain->name);
1091 /*------------------------------------------------------------------*/
1092 /* cleanUpLevel - cleansup the symbol table specified for all the */
1093 /* symbols in the given level */
1094 /*------------------------------------------------------------------*/
1095 void cleanUpLevel (bucket **table, int level )
1100 /* go thru the entire table */
1101 for ( i = 0 ; i < 256; i++ ) {
1102 for ( chain = table[i]; chain ; chain = chain->next ) {
1103 if (chain->level >= level) {
1104 deleteSym (table,chain->sym,chain->name);
1110 /*------------------------------------------------------------------*/
1111 /* computeType - computes the resultant type from two types */
1112 /*------------------------------------------------------------------*/
1113 link *computeType ( link *type1, link *type2)
1117 link *etype1 = getSpec(type1);
1118 link *etype2 = getSpec(type2);
1120 /* if one of them is a float then result is a float */
1121 /* here we assume that the types passed are okay */
1122 /* and can be cast to one another */
1123 /* which ever is greater in size */
1124 if (IS_FLOAT(etype1) || IS_FLOAT(etype2))
1125 rType = newFloatLink();
1127 /* if only one of them is a bit variable
1128 then the other one prevails */
1129 if (IS_BITVAR(etype1) && !IS_BITVAR(etype2))
1130 rType = copyLinkChain(type2);
1132 if (IS_BITVAR(etype2) && !IS_BITVAR(etype1))
1133 rType = copyLinkChain(type1);
1135 /* if one of them is a pointer then that
1138 rType = copyLinkChain(type1);
1141 rType = copyLinkChain(type2);
1143 if (getSize (type1) > getSize(type2) )
1144 rType = copyLinkChain(type1);
1146 rType = copyLinkChain(type2);
1148 reType = getSpec(rType);
1150 /* if either of them unsigned then make this unsigned */
1151 if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType))
1152 SPEC_USIGN(reType) = 1;
1154 /* if result is a literal then make not so */
1155 if (IS_LITERAL(reType))
1156 SPEC_SCLS(reType) = S_REGISTER ;
1161 /*------------------------------------------------------------------*/
1162 /* checkType - will do type check return 1 if match */
1163 /*------------------------------------------------------------------*/
1164 int checkType ( link *dest, link *src )
1175 /* if dest is a declarator then */
1176 if (IS_DECL(dest)) {
1178 if (DCL_TYPE(src) == DCL_TYPE(dest))
1179 return checkType(dest->next,src->next);
1181 if (IS_PTR(src) && IS_PTR(dest))
1184 if (IS_PTR(dest) && IS_ARRAY(src))
1187 if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src))
1188 return -1 * checkType (dest->next,src) ;
1193 if (IS_PTR(dest) && IS_INTEGRAL(src))
1199 /* if one of them is a void then ok */
1200 if (SPEC_NOUN(dest) == V_VOID &&
1201 SPEC_NOUN(src) != V_VOID )
1204 if (SPEC_NOUN(dest) != V_VOID &&
1205 SPEC_NOUN(src) == V_VOID )
1208 /* char === to short */
1209 if (SPEC_NOUN(dest) == V_CHAR &&
1210 SPEC_NOUN(src) == V_INT &&
1212 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1214 if (SPEC_NOUN(src) == V_CHAR &&
1215 SPEC_NOUN(dest) == V_INT &&
1217 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1219 /* if they are both bitfields then if the lengths
1220 and starts don't match */
1221 if (IS_BITFIELD(dest) && IS_BITFIELD(src) &&
1222 (SPEC_BLEN(dest) != SPEC_BLEN(src) ||
1223 SPEC_BSTR(dest) != SPEC_BSTR(src)))
1226 /* it is a specifier */
1227 if (SPEC_NOUN(dest) != SPEC_NOUN(src)) {
1228 if (SPEC_USIGN(dest) == SPEC_USIGN(src) &&
1229 IS_INTEGRAL(dest) && IS_INTEGRAL(src) &&
1230 getSize(dest) == getSize(src))
1233 if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src))
1239 if (IS_STRUCT(dest)) {
1240 if (SPEC_STRUCT(dest) != SPEC_STRUCT(src))
1245 if (SPEC_LONG(dest) != SPEC_LONG(src))
1248 if (SPEC_SHORT(dest) != SPEC_SHORT(src))
1251 if (SPEC_USIGN(dest) != SPEC_USIGN(src))
1257 /*------------------------------------------------------------------*/
1258 /* inCalleeSaveList - return 1 if found in calle save list */
1259 /*------------------------------------------------------------------*/
1260 bool inCalleeSaveList ( char *s)
1264 for (i = 0 ; options.calleeSaves[i] ; i++ )
1265 if (strcmp(options.calleeSaves[i],s) == 0)
1271 /*------------------------------------------------------------------*/
1272 /* checkFunction - does all kinds of check on a function */
1273 /*------------------------------------------------------------------*/
1274 int checkFunction (symbol *sym)
1277 value *exargs, *acargs ;
1280 /* if not type then some kind of error */
1284 /* if the function has no type then make it return int */
1285 if ( !sym->type->next )
1286 sym->type->next = sym->etype = newIntLink();
1288 /* function cannot return aggregate */
1289 if (IS_AGGREGATE(sym->type->next)) {
1290 werror(E_FUNC_AGGR,sym->name);
1294 /* function cannot return bit */
1295 if (IS_BITVAR(sym->type->next)) {
1296 werror(E_FUNC_BIT,sym->name);
1300 /* check if this function is defined as calleeSaves
1301 then mark it as such */
1302 sym->calleeSave = inCalleeSaveList(sym->name);
1304 /* if interrupt service routine */
1305 /* then it cannot have arguments */
1306 if ( sym->args && IS_ISR(sym->etype) && !IS_VOID(sym->args->type)) {
1307 werror(E_INT_ARGS,sym->name);
1311 if (!(csym = findSym (SymbolTab, sym, sym->name )))
1312 return 1 ; /* not defined nothing more to check */
1314 /* check if body already present */
1315 if ( csym && csym->fbody ) {
1316 werror(E_FUNC_BODY,sym->name);
1320 /* check the return value type */
1321 if (checkType (csym->type,sym->type) <= 0) {
1322 werror(E_PREV_DEF_CONFLICT,csym->name,"type") ;
1323 werror (E_CONTINUE,"previous defintion type ");
1324 printTypeChain(csym->type,stderr);fprintf(stderr,"\n");
1325 werror (E_CONTINUE,"current definition type ");
1326 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1330 if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) {
1331 werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt");
1335 if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) {
1336 werror (E_PREV_DEF_CONFLICT,csym->name,"using");
1340 /* compare expected agrs with actual args */
1341 exargs = csym->args ;
1342 acargs = sym->args ;
1344 /* for all the expected args do */
1347 exargs = exargs->next, acargs = acargs->next, argCnt++ ) {
1348 if ( checkType(exargs->type,acargs->type) <= 0) {
1349 werror(E_ARG_TYPE,argCnt);
1354 /* if one them ended we have a problem */
1355 if ((exargs && !acargs && !IS_VOID(exargs->type)) ||
1356 (!exargs && acargs && !IS_VOID(acargs->type)))
1357 werror(E_ARG_COUNT);
1359 /* replace with this defition */
1360 sym->cdef = csym->cdef;
1361 deleteSym (SymbolTab,csym,csym->name);
1362 addSym (SymbolTab,sym,sym->name,sym->level,sym->block);
1363 if (IS_EXTERN(csym->etype) && !
1364 IS_EXTERN(sym->etype))
1365 addSet(&publics,sym);
1369 /*-----------------------------------------------------------------*/
1370 /* processFuncArgs - does some processing with function args */
1371 /*-----------------------------------------------------------------*/
1372 void processFuncArgs (symbol *func, int ignoreName)
1377 /* if this function has variable argument list */
1378 /* then make the function a reentrant one */
1380 SPEC_RENT(func->etype) = 1;
1382 /* check if this function is defined as calleeSaves
1383 then mark it as such */
1384 func->calleeSave = inCalleeSaveList(func->name);
1386 val = func->args; /* loop thru all the arguments */
1388 /* if it is void then remove parameters */
1389 if (val && IS_VOID(val->type)) {
1394 /* if any of the arguments is an aggregate */
1395 /* change it to pointer to the same type */
1398 /* mark it as a register parameter if
1399 the function does nit have VA_ARG
1400 and MAX_REG_PARMS not exceeded &&
1401 not inhibited by command line option or #pragma */
1402 if (pNum <= MAX_REG_PARMS &&
1403 !options.noregparms &&
1405 SPEC_REGPARM(val->etype) = 1;
1407 if ( IS_AGGREGATE(val->type)) {
1408 /* if this is a structure */
1409 /* then we need to add a new link */
1410 if (IS_STRUCT(val->type)) {
1411 /* first lets add DECLARATOR type */
1412 link *p = val->type ;
1414 werror(W_STRUCT_AS_ARG,val->name);
1415 val->type = newLink();
1416 val->type->next = p ;
1419 /* change to a pointer depending on the */
1420 /* storage class specified */
1421 switch (SPEC_SCLS(val->etype)) {
1423 DCL_TYPE(val->type) = IPOINTER;
1426 DCL_TYPE(val->type) = PPOINTER;
1432 DCL_TYPE(val->type) = POINTER ;
1435 DCL_TYPE(val->type) = CPOINTER;
1438 DCL_TYPE(val->type) = FPOINTER;
1441 DCL_TYPE(val->type) = GPOINTER;
1444 /* is there is a symbol associated then */
1445 /* change the type of the symbol as well*/
1447 val->sym->type = copyLinkChain(val->type);
1448 val->sym->etype = getSpec(val->sym->type);
1456 /* if this function is reentrant or */
1457 /* automatics r 2b stacked then nothing */
1458 if (IS_RENT(func->etype) || options.stackAuto )
1465 /* if a symbolname is not given */
1466 /* synthesize a variable name */
1469 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1470 val->sym = newSymbol(val->name,1);
1471 SPEC_OCLS(val->etype) = (options.model ? xdata : data);
1472 val->sym->type = copyLinkChain (val->type);
1473 val->sym->etype = getSpec (val->sym->type);
1474 val->sym->_isparm = 1;
1475 strcpy (val->sym->rname,val->name);
1476 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1477 SPEC_STAT(func->etype);
1478 addSymChain(val->sym);
1481 else /* symbol name given create synth name */ {
1483 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1484 strcpy (val->sym->rname,val->name);
1485 val->sym->_isparm = 1;
1486 SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) =
1487 (options.model ? xdata : data);
1488 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1489 SPEC_STAT(func->etype);
1495 /*-----------------------------------------------------------------*/
1496 /* isSymbolEqual - compares two symbols return 1 if they match */
1497 /*-----------------------------------------------------------------*/
1498 int isSymbolEqual (symbol *dest, symbol *src)
1500 /* if pointers match then equal */
1504 /* if one of them is null then don't match */
1508 /* if both of them have rname match on rname */
1509 if (dest->rname[0] && src->rname[0])
1510 return (!strcmp(dest->rname,src->rname));
1512 /* otherwise match on name */
1513 return (!strcmp(dest->name,src->name));
1516 /*-----------------------------------------------------------------*/
1517 /* printTypeChain - prints the type chain in human readable form */
1518 /*-----------------------------------------------------------------*/
1519 void printTypeChain (link *type, FILE *of)
1529 if (IS_DECL(type)) {
1530 switch (DCL_TYPE(type)) {
1532 fprintf (of,"function ");
1535 fprintf (of,"_generic * ");
1536 if (DCL_PTR_CONST(type))
1537 fprintf(of,"const ");
1540 fprintf (of,"_code * ");
1541 if (DCL_PTR_CONST(type))
1542 fprintf(of,"const ");
1545 fprintf (of,"_far * ");
1546 if (DCL_PTR_CONST(type))
1547 fprintf(of,"const ");
1550 fprintf (of,"_near * ");
1551 if (DCL_PTR_CONST(type))
1552 fprintf(of,"const ");
1555 fprintf (of,"_idata *");
1556 if (DCL_PTR_CONST(type))
1557 fprintf(of,"const ");
1560 fprintf (of,"_pdata *");
1561 if (DCL_PTR_CONST(type))
1562 fprintf(of,"const ");
1565 fprintf (of," _unkown *");
1566 if (DCL_PTR_CONST(type))
1567 fprintf(of,"const ");
1571 fprintf (of,"array of ");
1575 if (SPEC_VOLATILE(type))
1576 fprintf (of,"volatile ");
1577 if (SPEC_USIGN(type))
1578 fprintf (of,"unsigned ");
1580 switch (SPEC_NOUN(type)) {
1583 fprintf (of,"long ");
1586 fprintf (of,"short ");
1588 fprintf (of,"int ");
1592 fprintf(of,"char ");
1596 fprintf(of,"void ");
1600 fprintf(of,"float ");
1604 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1608 fprintf(of,"sbit ");
1612 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1622 /*-----------------------------------------------------------------*/
1623 /* cdbTypeInfo - print the type information for debugger */
1624 /*-----------------------------------------------------------------*/
1625 void cdbTypeInfo (link *type,FILE *of)
1627 fprintf(of,"{%d}",getSize(type));
1629 if (IS_DECL(type)) {
1630 switch (DCL_TYPE(type)) {
1653 fprintf (of,"DA%d,",DCL_ELEM(type));
1657 switch (SPEC_NOUN(type)) {
1681 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1689 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1693 if (SPEC_USIGN(type))
1701 /*-----------------------------------------------------------------*/
1702 /* cdbSymbol - prints a symbol & its type information for debugger */
1703 /*-----------------------------------------------------------------*/
1704 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1716 fprintf(of,"S:"); /* symbol record */
1717 /* if this is not a structure symbol then
1718 we need to figure out the scope information */
1722 if (IS_STATIC(sym->etype))
1723 fprintf(of,"F%s$",moduleName); /* scope is file */
1725 fprintf(of,"G$"); /* scope is global */
1728 /* symbol is local */
1729 fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1731 fprintf(of,"S$"); /* scope is structure */
1733 /* print the name, & mangled name */
1734 fprintf(of,"%s$%d$%d(",sym->name,
1735 sym->level,sym->block);
1737 cdbTypeInfo(sym->type,of);
1740 /* print the address space */
1741 map = SPEC_OCLS(sym->etype);
1742 fprintf(of,"%c,%d,%d",
1743 (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1745 /* if assigned to registers then output register names */
1746 /* if this is a function then print
1747 if is it an interrupt routine & interrupt number
1748 and the register bank it is using */
1750 fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1751 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1752 /* alternate location to find this symbol @ : eg registers
1759 /*-----------------------------------------------------------------*/
1760 /* cdbStruct - print a structure for debugger */
1761 /*-----------------------------------------------------------------*/
1762 void cdbStruct ( structdef *sdef,int block,FILE *of,
1763 int inStruct, char *tag)
1768 /* if block # then must have function scope */
1769 fprintf(of,"F%s$",moduleName);
1770 fprintf(of,"%s[",(tag ? tag : sdef->tag));
1771 for (sym=sdef->fields ; sym ; sym = sym->next) {
1772 fprintf(of,"({%d}",sym->offset);
1773 cdbSymbol(sym,of,TRUE,FALSE);
1781 /*------------------------------------------------------------------*/
1782 /* cdbStructBlock - calls struct printing for a blcks */
1783 /*------------------------------------------------------------------*/
1784 void cdbStructBlock (int block , FILE *of)
1787 bucket **table = StructTab;
1790 /* go thru the entire table */
1791 for ( i = 0 ; i < 256; i++ ) {
1792 for ( chain = table[i]; chain ; chain = chain->next ) {
1793 if (chain->block >= block) {
1794 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1800 /*-----------------------------------------------------------------*/
1801 /* powof2 - returns power of two for the number if number is pow 2 */
1802 /*-----------------------------------------------------------------*/
1803 int powof2 (unsigned long num)
1809 if (num & 1) n1s++ ;
1814 if (n1s > 1 || nshifts == 0) return 0;
1815 return nshifts - 1 ;
1861 /*-----------------------------------------------------------------*/
1862 /* initCSupport - create functions for C support routines */
1863 /*-----------------------------------------------------------------*/
1864 void initCSupport ()
1866 charType = newCharLink();
1867 intType = newIntLink();
1868 floatType= newFloatLink();
1869 longType = newLongLink();
1870 ucharType = copyLinkChain(charType);
1871 SPEC_USIGN(ucharType) = 1;
1872 ulongType = copyLinkChain(longType);
1873 SPEC_USIGN(ulongType) = 1;
1874 uintType = copyLinkChain(intType);
1875 SPEC_USIGN(uintType) = 1;
1878 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1879 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1880 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1881 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1882 __fseq = funcOfType ("__fseq", charType, floatType, 2, options.float_rent);
1883 __fsneq = funcOfType ("__fsneq", charType, floatType, 2, options.float_rent);
1884 __fslt = funcOfType ("__fslt", charType, floatType, 2, options.float_rent);
1885 __fslteq= funcOfType ("__fslteq", charType, floatType, 2, options.float_rent);
1886 __fsgt = funcOfType ("__fsgt", charType, floatType, 2, options.float_rent);
1887 __fsgteq= funcOfType ("__fsgteq", charType, floatType, 2, options.float_rent);
1889 __fs2uchar = funcOfType ("__fs2uchar",ucharType,floatType,1, options.float_rent);
1890 __fs2uint = funcOfType ("__fs2uint",uintType,floatType,1, options.float_rent);
1891 __fs2ulong = funcOfType ("__fs2ulong",ulongType,floatType,1, options.float_rent);
1892 __fs2char = funcOfType ("__fs2char",charType,floatType,1, options.float_rent);
1893 __fs2int = funcOfType ("__fs2int",intType,floatType,1, options.float_rent);
1894 __fs2long = funcOfType ("__fs2long",longType,floatType,1, options.float_rent);
1896 __long2fs = funcOfType ("__long2fs",floatType,longType,1, options.float_rent);
1897 __ulong2fs = funcOfType ("__ulong2fs",floatType,ulongType,1, options.float_rent);
1898 __int2fs = funcOfType ("__int2fs",floatType,intType,1, options.float_rent);
1899 __uint2fs = funcOfType ("__uint2fs",floatType,uintType,1, options.float_rent);
1900 __char2fs = funcOfType ("__char2fs",floatType,charType,1, options.float_rent);
1901 __uchar2fs = funcOfType ("__uchar2fs",floatType,ucharType,1, options.float_rent);
1903 __muluint = funcOfType ("_muluint",uintType,uintType,2,options.intlong_rent);
1904 __mulsint = funcOfType ("_mulsint",intType,intType,2,options.intlong_rent);
1905 __divuint = funcOfType ("_divuint",uintType,uintType,2,options.intlong_rent);
1906 __divsint = funcOfType ("_divsint",intType,intType,2,options.intlong_rent);
1907 __moduint = funcOfType ("_moduint",uintType,uintType,2,options.intlong_rent);
1908 __modsint = funcOfType ("_modsint",intType,intType,2,options.intlong_rent);
1910 __mululong = funcOfType ("_mululong",ulongType,ulongType,2,options.intlong_rent);
1911 __mulslong = funcOfType ("_mulslong",longType,longType,2,options.intlong_rent);
1912 __divulong = funcOfType ("_divulong",ulongType,ulongType,2,options.intlong_rent);
1913 __divslong = funcOfType ("_divslong",longType,longType,2,options.intlong_rent);
1914 __modulong = funcOfType ("_modulong",ulongType,ulongType,2,options.intlong_rent);
1915 __modslong = funcOfType ("_modslong",longType,longType,2,options.intlong_rent);