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 void checkSClass ( symbol *sym )
903 /* if sfr or sbit then must also be */
904 /* volatile the initial value will be xlated */
905 /* to an absolute address */
906 if (SPEC_SCLS(sym->etype) == S_SBIT ||
907 SPEC_SCLS(sym->etype) == S_SFR ) {
908 SPEC_VOLATILE(sym->etype) = 1;
909 /* if initial value given */
911 SPEC_ABSA(sym->etype) = 1;
912 SPEC_ADDR(sym->etype) =
913 (int) list2int(sym->ival);
918 /* if absolute address given then it mark it as
920 if (IS_ABSOLUTE(sym->etype))
921 SPEC_VOLATILE(sym->etype) = 1;
923 /* global variables declared const put into code */
924 if (sym->level == 0 &&
925 SPEC_SCLS(sym->etype) == S_CONSTANT)
926 SPEC_SCLS(sym->etype) = S_CODE ;
929 /* global variable in code space is a constant */
930 if (sym->level == 0 &&
931 SPEC_SCLS(sym->etype) == S_CODE)
932 SPEC_CONST(sym->etype) = 1;
935 /* if bit variable then no storage class can be */
936 /* specified since bit is already a storage */
937 if ( IS_BITVAR(sym->etype) &&
938 ( SPEC_SCLS(sym->etype) != S_FIXED &&
939 SPEC_SCLS(sym->etype) != S_SBIT &&
940 SPEC_SCLS(sym->etype) != S_BIT )
942 werror (E_BITVAR_STORAGE,sym->name);
943 SPEC_SCLS(sym->etype) = S_FIXED ;
946 /* extern variables cannot be initialized */
947 if (IS_EXTERN(sym->etype) && sym->ival) {
948 werror(E_EXTERN_INIT,sym->name);
952 /* if this is an automatic symbol then */
953 /* storage class will be ignored and */
954 /* symbol will be allocated on stack/ */
955 /* data depending on flag */
957 (options.stackAuto || reentrant ) &&
958 ( SPEC_SCLS(sym->etype) != S_AUTO &&
959 SPEC_SCLS(sym->etype) != S_FIXED &&
960 SPEC_SCLS(sym->etype) != S_REGISTER &&
961 SPEC_SCLS(sym->etype) != S_CONSTANT )) {
963 werror(E_AUTO_ASSUMED,sym->name) ;
964 SPEC_SCLS(sym->etype) = S_AUTO ;
967 /* automatic symbols cannot be given */
968 /* an absolute address ignore it */
970 SPEC_ABSA(sym->etype) &&
971 (options.stackAuto || reentrant) ) {
972 werror(E_AUTO_ABSA,sym->name);
973 SPEC_ABSA(sym->etype) = 0 ;
976 /* arrays & pointers cannot be defined for bits */
977 /* SBITS or SFRs or BIT */
978 if ((IS_ARRAY(sym->type) || IS_PTR(sym->type)) &&
979 ( SPEC_NOUN(sym->etype) == V_BIT ||
980 SPEC_NOUN(sym->etype) == V_SBIT ||
981 SPEC_SCLS(sym->etype) == S_SFR ))
982 werror(E_BIT_ARRAY,sym->name);
984 /* if this is a bit|sbit then set length & start */
985 if (SPEC_NOUN(sym->etype) == V_BIT ||
986 SPEC_NOUN(sym->etype) == V_SBIT ) {
987 SPEC_BLEN(sym->etype) = 1 ;
988 SPEC_BSTR(sym->etype) = 0 ;
991 /* variables declared in CODE space must have */
992 /* initializers if not an extern */
993 if (SPEC_SCLS(sym->etype) == S_CODE &&
996 !IS_EXTERN(sym->etype))
997 werror(E_CODE_NO_INIT,sym->name);
999 /* if parameter or local variable then change */
1000 /* the storage class to reflect where the var will go */
1001 if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) {
1002 if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype)))
1003 SPEC_SCLS(sym->etype) = (options.model ?
1004 S_XSTACK : S_STACK ) ;
1006 SPEC_SCLS(sym->etype) = (options.model ?
1011 /*------------------------------------------------------------------*/
1012 /* changePointer - change pointer to functions */
1013 /*------------------------------------------------------------------*/
1014 void changePointer (symbol *sym)
1018 /* go thru the chain of declarations */
1019 /* if we find a pointer to a function */
1020 /* unconditionally change it to a ptr */
1022 for ( p = sym->type ; p ; p = p->next) {
1023 if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER)
1024 DCL_TYPE(p) = GPOINTER ;
1025 if ( IS_PTR(p) && IS_FUNC(p->next))
1026 DCL_TYPE(p) = CPOINTER ;
1030 /*------------------------------------------------------------------*/
1031 /* checkDecl - does semantic validation of a declaration */
1032 /*------------------------------------------------------------------*/
1033 int checkDecl ( symbol *sym )
1036 checkSClass (sym); /* check the storage class */
1037 changePointer(sym); /* change pointers if required */
1039 /* if this is an array without any dimension
1040 then update the dimension from the initial value */
1041 if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type))
1042 DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival);
1047 /*------------------------------------------------------------------*/
1048 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1049 /*------------------------------------------------------------------*/
1050 link *copyLinkChain ( link *p)
1052 link *head, *curr , *loop;
1055 head = loop = ( curr ? newLink() : (void *) NULL) ;
1057 memcpy(loop,curr,sizeof(link)) ; /* copy it */
1058 loop->next = (curr->next ? newLink() : (void *) NULL) ;
1067 /*------------------------------------------------------------------*/
1068 /* cleanUpBlock - cleansup the symbol table specified for all the */
1069 /* symbols in the given block */
1070 /*------------------------------------------------------------------*/
1071 void cleanUpBlock ( bucket **table, int block)
1076 /* go thru the entire table */
1077 for ( i = 0 ; i < 256; i++ ) {
1078 for ( chain = table[i]; chain ; chain = chain->next ) {
1079 if (chain->block >= block) {
1080 deleteSym (table,chain->sym,chain->name);
1086 /*------------------------------------------------------------------*/
1087 /* cleanUpLevel - cleansup the symbol table specified for all the */
1088 /* symbols in the given level */
1089 /*------------------------------------------------------------------*/
1090 void cleanUpLevel (bucket **table, int level )
1095 /* go thru the entire table */
1096 for ( i = 0 ; i < 256; i++ ) {
1097 for ( chain = table[i]; chain ; chain = chain->next ) {
1098 if (chain->level >= level) {
1099 deleteSym (table,chain->sym,chain->name);
1105 /*------------------------------------------------------------------*/
1106 /* computeType - computes the resultant type from two types */
1107 /*------------------------------------------------------------------*/
1108 link *computeType ( link *type1, link *type2)
1112 link *etype1 = getSpec(type1);
1113 link *etype2 = getSpec(type2);
1115 /* if one of them is a float then result is a float */
1116 /* here we assume that the types passed are okay */
1117 /* and can be cast to one another */
1118 /* which ever is greater in size */
1119 if (IS_FLOAT(etype1) || IS_FLOAT(etype2))
1120 rType = newFloatLink();
1122 /* if only one of them is a bit variable
1123 then the other one prevails */
1124 if (IS_BITVAR(etype1) && !IS_BITVAR(etype2))
1125 rType = copyLinkChain(type2);
1127 if (IS_BITVAR(etype2) && !IS_BITVAR(etype1))
1128 rType = copyLinkChain(type1);
1130 /* if one of them is a pointer then that
1133 rType = copyLinkChain(type1);
1136 rType = copyLinkChain(type2);
1138 if (getSize (type1) > getSize(type2) )
1139 rType = copyLinkChain(type1);
1141 rType = copyLinkChain(type2);
1143 reType = getSpec(rType);
1145 /* if either of them unsigned then make this unsigned */
1146 if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType))
1147 SPEC_USIGN(reType) = 1;
1149 /* if result is a literal then make not so */
1150 if (IS_LITERAL(reType))
1151 SPEC_SCLS(reType) = S_REGISTER ;
1156 /*------------------------------------------------------------------*/
1157 /* checkType - will do type check return 1 if match */
1158 /*------------------------------------------------------------------*/
1159 int checkType ( link *dest, link *src )
1170 /* if dest is a declarator then */
1171 if (IS_DECL(dest)) {
1173 if (DCL_TYPE(src) == DCL_TYPE(dest))
1174 return checkType(dest->next,src->next);
1176 if (IS_PTR(src) && IS_PTR(dest))
1179 if (IS_PTR(dest) && IS_ARRAY(src))
1182 if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src))
1183 return -1 * checkType (dest->next,src) ;
1188 if (IS_PTR(dest) && IS_INTEGRAL(src))
1194 /* if one of them is a void then ok */
1195 if (SPEC_NOUN(dest) == V_VOID &&
1196 SPEC_NOUN(src) != V_VOID )
1199 if (SPEC_NOUN(dest) != V_VOID &&
1200 SPEC_NOUN(src) == V_VOID )
1203 /* char === to short */
1204 if (SPEC_NOUN(dest) == V_CHAR &&
1205 SPEC_NOUN(src) == V_INT &&
1207 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1209 if (SPEC_NOUN(src) == V_CHAR &&
1210 SPEC_NOUN(dest) == V_INT &&
1212 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1214 /* if they are both bitfields then if the lengths
1215 and starts don't match */
1216 if (IS_BITFIELD(dest) && IS_BITFIELD(src) &&
1217 (SPEC_BLEN(dest) != SPEC_BLEN(src) ||
1218 SPEC_BSTR(dest) != SPEC_BSTR(src)))
1221 /* it is a specifier */
1222 if (SPEC_NOUN(dest) != SPEC_NOUN(src)) {
1223 if (SPEC_USIGN(dest) == SPEC_USIGN(src) &&
1224 IS_INTEGRAL(dest) && IS_INTEGRAL(src) &&
1225 getSize(dest) == getSize(src))
1228 if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src))
1234 if (IS_STRUCT(dest)) {
1235 if (SPEC_STRUCT(dest) != SPEC_STRUCT(src))
1240 if (SPEC_LONG(dest) != SPEC_LONG(src))
1243 if (SPEC_SHORT(dest) != SPEC_SHORT(src))
1246 if (SPEC_USIGN(dest) != SPEC_USIGN(src))
1252 /*------------------------------------------------------------------*/
1253 /* inCalleeSaveList - return 1 if found in calle save list */
1254 /*------------------------------------------------------------------*/
1255 bool inCalleeSaveList ( char *s)
1259 for (i = 0 ; options.calleeSaves[i] ; i++ )
1260 if (strcmp(options.calleeSaves[i],s) == 0)
1266 /*------------------------------------------------------------------*/
1267 /* checkFunction - does all kinds of check on a function */
1268 /*------------------------------------------------------------------*/
1269 int checkFunction (symbol *sym)
1272 value *exargs, *acargs ;
1275 /* if not type then some kind of error */
1279 /* if the function has no type then make it return int */
1280 if ( !sym->type->next )
1281 sym->type->next = sym->etype = newIntLink();
1283 /* function cannot return aggregate */
1284 if (IS_AGGREGATE(sym->type->next)) {
1285 werror(E_FUNC_AGGR,sym->name);
1289 /* function cannot return bit */
1290 if (IS_BITVAR(sym->type->next)) {
1291 werror(E_FUNC_BIT,sym->name);
1295 /* check if this function is defined as calleeSaves
1296 then mark it as such */
1297 sym->calleeSave = inCalleeSaveList(sym->name);
1299 /* if interrupt service routine */
1300 /* then it cannot have arguments */
1301 if ( sym->args && IS_ISR(sym->etype) && !IS_VOID(sym->args->type)) {
1302 werror(E_INT_ARGS,sym->name);
1306 if (!(csym = findSym (SymbolTab, sym, sym->name )))
1307 return 1 ; /* not defined nothing more to check */
1309 /* check if body already present */
1310 if ( csym && csym->fbody ) {
1311 werror(E_FUNC_BODY,sym->name);
1315 /* check the return value type */
1316 if (checkType (csym->type,sym->type) <= 0) {
1317 werror(E_PREV_DEF_CONFLICT,csym->name,"type") ;
1318 werror (E_CONTINUE,"previous defintion type ");
1319 printTypeChain(csym->type,stderr);fprintf(stderr,"\n");
1320 werror (E_CONTINUE,"current definition type ");
1321 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1325 if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) {
1326 werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt");
1330 if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) {
1331 werror (E_PREV_DEF_CONFLICT,csym->name,"using");
1335 /* compare expected agrs with actual args */
1336 exargs = csym->args ;
1337 acargs = sym->args ;
1339 /* for all the expected args do */
1342 exargs = exargs->next, acargs = acargs->next, argCnt++ ) {
1343 if ( checkType(exargs->type,acargs->type) <= 0) {
1344 werror(E_ARG_TYPE,argCnt);
1349 /* if one them ended we have a problem */
1350 if ((exargs && !acargs && !IS_VOID(exargs->type)) ||
1351 (!exargs && acargs && !IS_VOID(acargs->type)))
1352 werror(E_ARG_COUNT);
1354 /* replace with this defition */
1355 sym->cdef = csym->cdef;
1356 deleteSym (SymbolTab,csym,csym->name);
1357 addSym (SymbolTab,sym,sym->name,sym->level,sym->block);
1358 if (IS_EXTERN(csym->etype) && !
1359 IS_EXTERN(sym->etype))
1360 addSet(&publics,sym);
1364 /*-----------------------------------------------------------------*/
1365 /* processFuncArgs - does some processing with function args */
1366 /*-----------------------------------------------------------------*/
1367 void processFuncArgs (symbol *func, int ignoreName)
1372 /* if this function has variable argument list */
1373 /* then make the function a reentrant one */
1375 SPEC_RENT(func->etype) = 1;
1377 /* check if this function is defined as calleeSaves
1378 then mark it as such */
1379 func->calleeSave = inCalleeSaveList(func->name);
1381 val = func->args; /* loop thru all the arguments */
1383 /* if it is void then remove parameters */
1384 if (val && IS_VOID(val->type)) {
1389 /* if any of the arguments is an aggregate */
1390 /* change it to pointer to the same type */
1393 /* mark it as a register parameter if
1394 the function does nit have VA_ARG
1395 and MAX_REG_PARMS not exceeded &&
1396 not inhibited by command line option or #pragma */
1397 if (pNum <= MAX_REG_PARMS &&
1398 !options.noregparms &&
1400 SPEC_REGPARM(val->etype) = 1;
1402 if ( IS_AGGREGATE(val->type)) {
1403 /* if this is a structure */
1404 /* then we need to add a new link */
1405 if (IS_STRUCT(val->type)) {
1406 /* first lets add DECLARATOR type */
1407 link *p = val->type ;
1409 werror(W_STRUCT_AS_ARG,val->name);
1410 val->type = newLink();
1411 val->type->next = p ;
1414 /* change to a pointer depending on the */
1415 /* storage class specified */
1416 switch (SPEC_SCLS(val->etype)) {
1418 DCL_TYPE(val->type) = IPOINTER;
1421 DCL_TYPE(val->type) = PPOINTER;
1427 DCL_TYPE(val->type) = POINTER ;
1430 DCL_TYPE(val->type) = CPOINTER;
1433 DCL_TYPE(val->type) = FPOINTER;
1436 DCL_TYPE(val->type) = GPOINTER;
1439 /* is there is a symbol associated then */
1440 /* change the type of the symbol as well*/
1442 val->sym->type = copyLinkChain(val->type);
1443 val->sym->etype = getSpec(val->sym->type);
1451 /* if this function is reentrant or */
1452 /* automatics r 2b stacked then nothing */
1453 if (IS_RENT(func->etype) || options.stackAuto )
1460 /* if a symbolname is not given */
1461 /* synthesize a variable name */
1464 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1465 val->sym = newSymbol(val->name,1);
1466 SPEC_OCLS(val->etype) = (options.model ? xdata : data);
1467 val->sym->type = copyLinkChain (val->type);
1468 val->sym->etype = getSpec (val->sym->type);
1469 val->sym->_isparm = 1;
1470 strcpy (val->sym->rname,val->name);
1471 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1472 SPEC_STAT(func->etype);
1473 addSymChain(val->sym);
1476 else /* symbol name given create synth name */ {
1478 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1479 strcpy (val->sym->rname,val->name);
1480 val->sym->_isparm = 1;
1481 SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) =
1482 (options.model ? xdata : data);
1483 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1484 SPEC_STAT(func->etype);
1490 /*-----------------------------------------------------------------*/
1491 /* isSymbolEqual - compares two symbols return 1 if they match */
1492 /*-----------------------------------------------------------------*/
1493 int isSymbolEqual (symbol *dest, symbol *src)
1495 /* if pointers match then equal */
1499 /* if one of them is null then don't match */
1503 /* if both of them have rname match on rname */
1504 if (dest->rname[0] && src->rname[0])
1505 return (!strcmp(dest->rname,src->rname));
1507 /* otherwise match on name */
1508 return (!strcmp(dest->name,src->name));
1511 /*-----------------------------------------------------------------*/
1512 /* printTypeChain - prints the type chain in human readable form */
1513 /*-----------------------------------------------------------------*/
1514 void printTypeChain (link *type, FILE *of)
1524 if (IS_DECL(type)) {
1525 switch (DCL_TYPE(type)) {
1527 fprintf (of,"function ");
1530 fprintf (of,"_generic * ");
1531 if (DCL_PTR_CONST(type))
1532 fprintf(of,"const ");
1535 fprintf (of,"_code * ");
1536 if (DCL_PTR_CONST(type))
1537 fprintf(of,"const ");
1540 fprintf (of,"_far * ");
1541 if (DCL_PTR_CONST(type))
1542 fprintf(of,"const ");
1545 fprintf (of,"_near * ");
1546 if (DCL_PTR_CONST(type))
1547 fprintf(of,"const ");
1550 fprintf (of,"_idata *");
1551 if (DCL_PTR_CONST(type))
1552 fprintf(of,"const ");
1555 fprintf (of,"_pdata *");
1556 if (DCL_PTR_CONST(type))
1557 fprintf(of,"const ");
1560 fprintf (of," _unkown *");
1561 if (DCL_PTR_CONST(type))
1562 fprintf(of,"const ");
1566 fprintf (of,"array of ");
1570 if (SPEC_VOLATILE(type))
1571 fprintf (of,"volatile ");
1572 if (SPEC_USIGN(type))
1573 fprintf (of,"unsigned ");
1575 switch (SPEC_NOUN(type)) {
1578 fprintf (of,"long ");
1581 fprintf (of,"short ");
1583 fprintf (of,"int ");
1587 fprintf(of,"char ");
1591 fprintf(of,"void ");
1595 fprintf(of,"float ");
1599 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1603 fprintf(of,"sbit ");
1607 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1617 /*-----------------------------------------------------------------*/
1618 /* cdbTypeInfo - print the type information for debugger */
1619 /*-----------------------------------------------------------------*/
1620 void cdbTypeInfo (link *type,FILE *of)
1622 fprintf(of,"{%d}",getSize(type));
1624 if (IS_DECL(type)) {
1625 switch (DCL_TYPE(type)) {
1648 fprintf (of,"DA%d,",DCL_ELEM(type));
1652 switch (SPEC_NOUN(type)) {
1676 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1684 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1688 if (SPEC_USIGN(type))
1696 /*-----------------------------------------------------------------*/
1697 /* cdbSymbol - prints a symbol & its type information for debugger */
1698 /*-----------------------------------------------------------------*/
1699 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1711 fprintf(of,"S:"); /* symbol record */
1712 /* if this is not a structure symbol then
1713 we need to figure out the scope information */
1717 if (IS_STATIC(sym->etype))
1718 fprintf(of,"F%s$",moduleName); /* scope is file */
1720 fprintf(of,"G$"); /* scope is global */
1723 /* symbol is local */
1724 fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1726 fprintf(of,"S$"); /* scope is structure */
1728 /* print the name, & mangled name */
1729 fprintf(of,"%s$%d$%d(",sym->name,
1730 sym->level,sym->block);
1732 cdbTypeInfo(sym->type,of);
1735 /* print the address space */
1736 map = SPEC_OCLS(sym->etype);
1737 fprintf(of,"%c,%d,%d",
1738 (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1740 /* if assigned to registers then output register names */
1741 /* if this is a function then print
1742 if is it an interrupt routine & interrupt number
1743 and the register bank it is using */
1745 fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1746 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1747 /* alternate location to find this symbol @ : eg registers
1754 /*-----------------------------------------------------------------*/
1755 /* cdbStruct - print a structure for debugger */
1756 /*-----------------------------------------------------------------*/
1757 void cdbStruct ( structdef *sdef,int block,FILE *of,
1758 int inStruct, char *tag)
1763 /* if block # then must have function scope */
1764 fprintf(of,"F%s$",moduleName);
1765 fprintf(of,"%s[",(tag ? tag : sdef->tag));
1766 for (sym=sdef->fields ; sym ; sym = sym->next) {
1767 fprintf(of,"({%d}",sym->offset);
1768 cdbSymbol(sym,of,TRUE,FALSE);
1776 /*------------------------------------------------------------------*/
1777 /* cdbStructBlock - calls struct printing for a blcks */
1778 /*------------------------------------------------------------------*/
1779 void cdbStructBlock (int block , FILE *of)
1782 bucket **table = StructTab;
1785 /* go thru the entire table */
1786 for ( i = 0 ; i < 256; i++ ) {
1787 for ( chain = table[i]; chain ; chain = chain->next ) {
1788 if (chain->block >= block) {
1789 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1795 /*-----------------------------------------------------------------*/
1796 /* powof2 - returns power of two for the number if number is pow 2 */
1797 /*-----------------------------------------------------------------*/
1798 int powof2 (unsigned long num)
1804 if (num & 1) n1s++ ;
1809 if (n1s > 1 || nshifts == 0) return 0;
1810 return nshifts - 1 ;
1856 /*-----------------------------------------------------------------*/
1857 /* initCSupport - create functions for C support routines */
1858 /*-----------------------------------------------------------------*/
1859 void initCSupport ()
1861 charType = newCharLink();
1862 intType = newIntLink();
1863 floatType= newFloatLink();
1864 longType = newLongLink();
1865 ucharType = copyLinkChain(charType);
1866 SPEC_USIGN(ucharType) = 1;
1867 ulongType = copyLinkChain(longType);
1868 SPEC_USIGN(ulongType) = 1;
1869 uintType = copyLinkChain(intType);
1870 SPEC_USIGN(uintType) = 1;
1873 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1874 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1875 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1876 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1877 __fseq = funcOfType ("__fseq", charType, floatType, 2, options.float_rent);
1878 __fsneq = funcOfType ("__fsneq", charType, floatType, 2, options.float_rent);
1879 __fslt = funcOfType ("__fslt", charType, floatType, 2, options.float_rent);
1880 __fslteq= funcOfType ("__fslteq", charType, floatType, 2, options.float_rent);
1881 __fsgt = funcOfType ("__fsgt", charType, floatType, 2, options.float_rent);
1882 __fsgteq= funcOfType ("__fsgteq", charType, floatType, 2, options.float_rent);
1884 __fs2uchar = funcOfType ("__fs2uchar",ucharType,floatType,1, options.float_rent);
1885 __fs2uint = funcOfType ("__fs2uint",uintType,floatType,1, options.float_rent);
1886 __fs2ulong = funcOfType ("__fs2ulong",ulongType,floatType,1, options.float_rent);
1887 __fs2char = funcOfType ("__fs2char",charType,floatType,1, options.float_rent);
1888 __fs2int = funcOfType ("__fs2int",intType,floatType,1, options.float_rent);
1889 __fs2long = funcOfType ("__fs2long",longType,floatType,1, options.float_rent);
1891 __long2fs = funcOfType ("__long2fs",floatType,longType,1, options.float_rent);
1892 __ulong2fs = funcOfType ("__ulong2fs",floatType,ulongType,1, options.float_rent);
1893 __int2fs = funcOfType ("__int2fs",floatType,intType,1, options.float_rent);
1894 __uint2fs = funcOfType ("__uint2fs",floatType,uintType,1, options.float_rent);
1895 __char2fs = funcOfType ("__char2fs",floatType,charType,1, options.float_rent);
1896 __uchar2fs = funcOfType ("__uchar2fs",floatType,ucharType,1, options.float_rent);
1898 __muluint = funcOfType ("_muluint",uintType,uintType,2,options.intlong_rent);
1899 __mulsint = funcOfType ("_mulsint",intType,intType,2,options.intlong_rent);
1900 __divuint = funcOfType ("_divuint",uintType,uintType,2,options.intlong_rent);
1901 __divsint = funcOfType ("_divsint",intType,intType,2,options.intlong_rent);
1902 __moduint = funcOfType ("_moduint",uintType,uintType,2,options.intlong_rent);
1903 __modsint = funcOfType ("_modsint",intType,intType,2,options.intlong_rent);
1905 __mululong = funcOfType ("_mululong",ulongType,ulongType,2,options.intlong_rent);
1906 __mulslong = funcOfType ("_mulslong",longType,longType,2,options.intlong_rent);
1907 __divulong = funcOfType ("_divulong",ulongType,ulongType,2,options.intlong_rent);
1908 __divslong = funcOfType ("_divslong",longType,longType,2,options.intlong_rent);
1909 __modulong = funcOfType ("_modulong",ulongType,ulongType,2,options.intlong_rent);
1910 __modslong = funcOfType ("_modslong",longType,longType,2,options.intlong_rent);