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_STACK &&
967 SPEC_SCLS(sym->etype) != S_XSTACK &&
968 SPEC_SCLS(sym->etype) != S_CONSTANT )) {
970 werror(E_AUTO_ASSUMED,sym->name) ;
971 SPEC_SCLS(sym->etype) = S_AUTO ;
974 /* automatic symbols cannot be given */
975 /* an absolute address ignore it */
977 SPEC_ABSA(sym->etype) &&
978 (options.stackAuto || reentrant) ) {
979 werror(E_AUTO_ABSA,sym->name);
980 SPEC_ABSA(sym->etype) = 0 ;
983 /* arrays & pointers cannot be defined for bits */
984 /* SBITS or SFRs or BIT */
985 if ((IS_ARRAY(sym->type) || IS_PTR(sym->type)) &&
986 ( SPEC_NOUN(sym->etype) == V_BIT ||
987 SPEC_NOUN(sym->etype) == V_SBIT ||
988 SPEC_SCLS(sym->etype) == S_SFR ))
989 werror(E_BIT_ARRAY,sym->name);
991 /* if this is a bit|sbit then set length & start */
992 if (SPEC_NOUN(sym->etype) == V_BIT ||
993 SPEC_NOUN(sym->etype) == V_SBIT ) {
994 SPEC_BLEN(sym->etype) = 1 ;
995 SPEC_BSTR(sym->etype) = 0 ;
998 /* variables declared in CODE space must have */
999 /* initializers if not an extern */
1000 if (SPEC_SCLS(sym->etype) == S_CODE &&
1001 sym->ival == NULL &&
1003 !IS_EXTERN(sym->etype))
1004 werror(E_CODE_NO_INIT,sym->name);
1006 /* if parameter or local variable then change */
1007 /* the storage class to reflect where the var will go */
1008 if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) {
1009 if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype)))
1010 SPEC_SCLS(sym->etype) = (options.useXstack ?
1011 S_XSTACK : S_STACK ) ;
1013 SPEC_SCLS(sym->etype) = (options.useXstack ?
1018 /*------------------------------------------------------------------*/
1019 /* changePointer - change pointer to functions */
1020 /*------------------------------------------------------------------*/
1021 void changePointer (symbol *sym)
1025 /* go thru the chain of declarations */
1026 /* if we find a pointer to a function */
1027 /* unconditionally change it to a ptr */
1029 for ( p = sym->type ; p ; p = p->next) {
1030 if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER)
1031 DCL_TYPE(p) = GPOINTER ;
1032 if ( IS_PTR(p) && IS_FUNC(p->next))
1033 DCL_TYPE(p) = CPOINTER ;
1037 /*------------------------------------------------------------------*/
1038 /* checkDecl - does semantic validation of a declaration */
1039 /*------------------------------------------------------------------*/
1040 int checkDecl ( symbol *sym )
1043 checkSClass (sym); /* check the storage class */
1044 changePointer(sym); /* change pointers if required */
1046 /* if this is an array without any dimension
1047 then update the dimension from the initial value */
1048 if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type))
1049 DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival);
1054 /*------------------------------------------------------------------*/
1055 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1056 /*------------------------------------------------------------------*/
1057 link *copyLinkChain ( link *p)
1059 link *head, *curr , *loop;
1062 head = loop = ( curr ? newLink() : (void *) NULL) ;
1064 memcpy(loop,curr,sizeof(link)) ; /* copy it */
1065 loop->next = (curr->next ? newLink() : (void *) NULL) ;
1074 /*------------------------------------------------------------------*/
1075 /* cleanUpBlock - cleansup the symbol table specified for all the */
1076 /* symbols in the given block */
1077 /*------------------------------------------------------------------*/
1078 void cleanUpBlock ( bucket **table, int block)
1083 /* go thru the entire table */
1084 for ( i = 0 ; i < 256; i++ ) {
1085 for ( chain = table[i]; chain ; chain = chain->next ) {
1086 if (chain->block >= block) {
1087 deleteSym (table,chain->sym,chain->name);
1093 /*------------------------------------------------------------------*/
1094 /* cleanUpLevel - cleansup the symbol table specified for all the */
1095 /* symbols in the given level */
1096 /*------------------------------------------------------------------*/
1097 void cleanUpLevel (bucket **table, int level )
1102 /* go thru the entire table */
1103 for ( i = 0 ; i < 256; i++ ) {
1104 for ( chain = table[i]; chain ; chain = chain->next ) {
1105 if (chain->level >= level) {
1106 deleteSym (table,chain->sym,chain->name);
1112 /*------------------------------------------------------------------*/
1113 /* computeType - computes the resultant type from two types */
1114 /*------------------------------------------------------------------*/
1115 link *computeType ( link *type1, link *type2)
1119 link *etype1 = getSpec(type1);
1120 link *etype2 = getSpec(type2);
1122 /* if one of them is a float then result is a float */
1123 /* here we assume that the types passed are okay */
1124 /* and can be cast to one another */
1125 /* which ever is greater in size */
1126 if (IS_FLOAT(etype1) || IS_FLOAT(etype2))
1127 rType = newFloatLink();
1129 /* if only one of them is a bit variable
1130 then the other one prevails */
1131 if (IS_BITVAR(etype1) && !IS_BITVAR(etype2))
1132 rType = copyLinkChain(type2);
1134 if (IS_BITVAR(etype2) && !IS_BITVAR(etype1))
1135 rType = copyLinkChain(type1);
1137 /* if one of them is a pointer then that
1140 rType = copyLinkChain(type1);
1143 rType = copyLinkChain(type2);
1145 if (getSize (type1) > getSize(type2) )
1146 rType = copyLinkChain(type1);
1148 rType = copyLinkChain(type2);
1150 reType = getSpec(rType);
1152 /* if either of them unsigned then make this unsigned */
1153 if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType))
1154 SPEC_USIGN(reType) = 1;
1156 /* if result is a literal then make not so */
1157 if (IS_LITERAL(reType))
1158 SPEC_SCLS(reType) = S_REGISTER ;
1163 /*------------------------------------------------------------------*/
1164 /* checkType - will do type check return 1 if match */
1165 /*------------------------------------------------------------------*/
1166 int checkType ( link *dest, link *src )
1177 /* if dest is a declarator then */
1178 if (IS_DECL(dest)) {
1180 if (DCL_TYPE(src) == DCL_TYPE(dest))
1181 return checkType(dest->next,src->next);
1183 if (IS_PTR(src) && IS_PTR(dest))
1186 if (IS_PTR(dest) && IS_ARRAY(src))
1189 if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src))
1190 return -1 * checkType (dest->next,src) ;
1195 if (IS_PTR(dest) && IS_INTEGRAL(src))
1201 /* if one of them is a void then ok */
1202 if (SPEC_NOUN(dest) == V_VOID &&
1203 SPEC_NOUN(src) != V_VOID )
1206 if (SPEC_NOUN(dest) != V_VOID &&
1207 SPEC_NOUN(src) == V_VOID )
1210 /* char === to short */
1211 if (SPEC_NOUN(dest) == V_CHAR &&
1212 SPEC_NOUN(src) == V_INT &&
1214 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1216 if (SPEC_NOUN(src) == V_CHAR &&
1217 SPEC_NOUN(dest) == V_INT &&
1219 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1221 /* if they are both bitfields then if the lengths
1222 and starts don't match */
1223 if (IS_BITFIELD(dest) && IS_BITFIELD(src) &&
1224 (SPEC_BLEN(dest) != SPEC_BLEN(src) ||
1225 SPEC_BSTR(dest) != SPEC_BSTR(src)))
1228 /* it is a specifier */
1229 if (SPEC_NOUN(dest) != SPEC_NOUN(src)) {
1230 if (SPEC_USIGN(dest) == SPEC_USIGN(src) &&
1231 IS_INTEGRAL(dest) && IS_INTEGRAL(src) &&
1232 getSize(dest) == getSize(src))
1235 if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src))
1241 if (IS_STRUCT(dest)) {
1242 if (SPEC_STRUCT(dest) != SPEC_STRUCT(src))
1247 if (SPEC_LONG(dest) != SPEC_LONG(src))
1250 if (SPEC_SHORT(dest) != SPEC_SHORT(src))
1253 if (SPEC_USIGN(dest) != SPEC_USIGN(src))
1259 /*------------------------------------------------------------------*/
1260 /* inCalleeSaveList - return 1 if found in calle save list */
1261 /*------------------------------------------------------------------*/
1262 bool inCalleeSaveList ( char *s)
1266 for (i = 0 ; options.calleeSaves[i] ; i++ )
1267 if (strcmp(options.calleeSaves[i],s) == 0)
1273 /*------------------------------------------------------------------*/
1274 /* checkFunction - does all kinds of check on a function */
1275 /*------------------------------------------------------------------*/
1276 int checkFunction (symbol *sym)
1279 value *exargs, *acargs ;
1282 /* if not type then some kind of error */
1286 /* if the function has no type then make it return int */
1287 if ( !sym->type->next )
1288 sym->type->next = sym->etype = newIntLink();
1290 /* function cannot return aggregate */
1291 if (IS_AGGREGATE(sym->type->next)) {
1292 werror(E_FUNC_AGGR,sym->name);
1296 /* function cannot return bit */
1297 if (IS_BITVAR(sym->type->next)) {
1298 werror(E_FUNC_BIT,sym->name);
1302 /* check if this function is defined as calleeSaves
1303 then mark it as such */
1304 sym->calleeSave = inCalleeSaveList(sym->name);
1306 /* if interrupt service routine */
1307 /* then it cannot have arguments */
1308 if ( sym->args && IS_ISR(sym->etype) && !IS_VOID(sym->args->type)) {
1309 werror(E_INT_ARGS,sym->name);
1313 if (!(csym = findSym (SymbolTab, sym, sym->name )))
1314 return 1 ; /* not defined nothing more to check */
1316 /* check if body already present */
1317 if ( csym && csym->fbody ) {
1318 werror(E_FUNC_BODY,sym->name);
1322 /* check the return value type */
1323 if (checkType (csym->type,sym->type) <= 0) {
1324 werror(E_PREV_DEF_CONFLICT,csym->name,"type") ;
1325 werror (E_CONTINUE,"previous defintion type ");
1326 printTypeChain(csym->type,stderr);fprintf(stderr,"\n");
1327 werror (E_CONTINUE,"current definition type ");
1328 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1332 if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) {
1333 werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt");
1337 if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) {
1338 werror (E_PREV_DEF_CONFLICT,csym->name,"using");
1342 /* compare expected agrs with actual args */
1343 exargs = csym->args ;
1344 acargs = sym->args ;
1346 /* for all the expected args do */
1349 exargs = exargs->next, acargs = acargs->next, argCnt++ ) {
1350 if ( checkType(exargs->type,acargs->type) <= 0) {
1351 werror(E_ARG_TYPE,argCnt);
1356 /* if one them ended we have a problem */
1357 if ((exargs && !acargs && !IS_VOID(exargs->type)) ||
1358 (!exargs && acargs && !IS_VOID(acargs->type)))
1359 werror(E_ARG_COUNT);
1361 /* replace with this defition */
1362 sym->cdef = csym->cdef;
1363 deleteSym (SymbolTab,csym,csym->name);
1364 addSym (SymbolTab,sym,sym->name,sym->level,sym->block);
1365 if (IS_EXTERN(csym->etype) && !
1366 IS_EXTERN(sym->etype))
1367 addSet(&publics,sym);
1371 /*-----------------------------------------------------------------*/
1372 /* processFuncArgs - does some processing with function args */
1373 /*-----------------------------------------------------------------*/
1374 void processFuncArgs (symbol *func, int ignoreName)
1379 /* if this function has variable argument list */
1380 /* then make the function a reentrant one */
1382 SPEC_RENT(func->etype) = 1;
1384 /* check if this function is defined as calleeSaves
1385 then mark it as such */
1386 func->calleeSave = inCalleeSaveList(func->name);
1388 val = func->args; /* loop thru all the arguments */
1390 /* if it is void then remove parameters */
1391 if (val && IS_VOID(val->type)) {
1396 /* if any of the arguments is an aggregate */
1397 /* change it to pointer to the same type */
1400 /* mark it as a register parameter if
1401 the function does nit have VA_ARG
1402 and MAX_REG_PARMS not exceeded &&
1403 not inhibited by command line option or #pragma */
1404 if (pNum <= MAX_REG_PARMS &&
1405 !options.noregparms &&
1407 SPEC_REGPARM(val->etype) = 1;
1409 if ( IS_AGGREGATE(val->type)) {
1410 /* if this is a structure */
1411 /* then we need to add a new link */
1412 if (IS_STRUCT(val->type)) {
1413 /* first lets add DECLARATOR type */
1414 link *p = val->type ;
1416 werror(W_STRUCT_AS_ARG,val->name);
1417 val->type = newLink();
1418 val->type->next = p ;
1421 /* change to a pointer depending on the */
1422 /* storage class specified */
1423 switch (SPEC_SCLS(val->etype)) {
1425 DCL_TYPE(val->type) = IPOINTER;
1428 DCL_TYPE(val->type) = PPOINTER;
1434 DCL_TYPE(val->type) = POINTER ;
1437 DCL_TYPE(val->type) = CPOINTER;
1440 DCL_TYPE(val->type) = FPOINTER;
1443 DCL_TYPE(val->type) = GPOINTER;
1446 /* is there is a symbol associated then */
1447 /* change the type of the symbol as well*/
1449 val->sym->type = copyLinkChain(val->type);
1450 val->sym->etype = getSpec(val->sym->type);
1458 /* if this function is reentrant or */
1459 /* automatics r 2b stacked then nothing */
1460 if (IS_RENT(func->etype) || options.stackAuto )
1467 /* if a symbolname is not given */
1468 /* synthesize a variable name */
1471 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1472 val->sym = newSymbol(val->name,1);
1473 SPEC_OCLS(val->etype) = (options.model ? xdata : data);
1474 val->sym->type = copyLinkChain (val->type);
1475 val->sym->etype = getSpec (val->sym->type);
1476 val->sym->_isparm = 1;
1477 strcpy (val->sym->rname,val->name);
1478 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1479 SPEC_STAT(func->etype);
1480 addSymChain(val->sym);
1483 else /* symbol name given create synth name */ {
1485 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1486 strcpy (val->sym->rname,val->name);
1487 val->sym->_isparm = 1;
1488 SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) =
1489 (options.model ? xdata : data);
1490 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1491 SPEC_STAT(func->etype);
1497 /*-----------------------------------------------------------------*/
1498 /* isSymbolEqual - compares two symbols return 1 if they match */
1499 /*-----------------------------------------------------------------*/
1500 int isSymbolEqual (symbol *dest, symbol *src)
1502 /* if pointers match then equal */
1506 /* if one of them is null then don't match */
1510 /* if both of them have rname match on rname */
1511 if (dest->rname[0] && src->rname[0])
1512 return (!strcmp(dest->rname,src->rname));
1514 /* otherwise match on name */
1515 return (!strcmp(dest->name,src->name));
1518 /*-----------------------------------------------------------------*/
1519 /* printTypeChain - prints the type chain in human readable form */
1520 /*-----------------------------------------------------------------*/
1521 void printTypeChain (link *type, FILE *of)
1531 if (IS_DECL(type)) {
1532 switch (DCL_TYPE(type)) {
1534 fprintf (of,"function ");
1537 fprintf (of,"_generic * ");
1538 if (DCL_PTR_CONST(type))
1539 fprintf(of,"const ");
1542 fprintf (of,"_code * ");
1543 if (DCL_PTR_CONST(type))
1544 fprintf(of,"const ");
1547 fprintf (of,"_far * ");
1548 if (DCL_PTR_CONST(type))
1549 fprintf(of,"const ");
1552 fprintf (of,"_near * ");
1553 if (DCL_PTR_CONST(type))
1554 fprintf(of,"const ");
1557 fprintf (of,"_idata *");
1558 if (DCL_PTR_CONST(type))
1559 fprintf(of,"const ");
1562 fprintf (of,"_pdata *");
1563 if (DCL_PTR_CONST(type))
1564 fprintf(of,"const ");
1567 fprintf (of," _unkown *");
1568 if (DCL_PTR_CONST(type))
1569 fprintf(of,"const ");
1573 fprintf (of,"array of ");
1577 if (SPEC_VOLATILE(type))
1578 fprintf (of,"volatile ");
1579 if (SPEC_USIGN(type))
1580 fprintf (of,"unsigned ");
1582 switch (SPEC_NOUN(type)) {
1585 fprintf (of,"long ");
1588 fprintf (of,"short ");
1590 fprintf (of,"int ");
1594 fprintf(of,"char ");
1598 fprintf(of,"void ");
1602 fprintf(of,"float ");
1606 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1610 fprintf(of,"sbit ");
1614 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1624 /*-----------------------------------------------------------------*/
1625 /* cdbTypeInfo - print the type information for debugger */
1626 /*-----------------------------------------------------------------*/
1627 void cdbTypeInfo (link *type,FILE *of)
1629 fprintf(of,"{%d}",getSize(type));
1631 if (IS_DECL(type)) {
1632 switch (DCL_TYPE(type)) {
1655 fprintf (of,"DA%d,",DCL_ELEM(type));
1659 switch (SPEC_NOUN(type)) {
1683 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1691 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1695 if (SPEC_USIGN(type))
1703 /*-----------------------------------------------------------------*/
1704 /* cdbSymbol - prints a symbol & its type information for debugger */
1705 /*-----------------------------------------------------------------*/
1706 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1718 fprintf(of,"S:"); /* symbol record */
1719 /* if this is not a structure symbol then
1720 we need to figure out the scope information */
1724 if (IS_STATIC(sym->etype))
1725 fprintf(of,"F%s$",moduleName); /* scope is file */
1727 fprintf(of,"G$"); /* scope is global */
1730 /* symbol is local */
1731 fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1733 fprintf(of,"S$"); /* scope is structure */
1735 /* print the name, & mangled name */
1736 fprintf(of,"%s$%d$%d(",sym->name,
1737 sym->level,sym->block);
1739 cdbTypeInfo(sym->type,of);
1742 /* print the address space */
1743 map = SPEC_OCLS(sym->etype);
1744 fprintf(of,"%c,%d,%d",
1745 (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1747 /* if assigned to registers then output register names */
1748 /* if this is a function then print
1749 if is it an interrupt routine & interrupt number
1750 and the register bank it is using */
1752 fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1753 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1754 /* alternate location to find this symbol @ : eg registers
1761 /*-----------------------------------------------------------------*/
1762 /* cdbStruct - print a structure for debugger */
1763 /*-----------------------------------------------------------------*/
1764 void cdbStruct ( structdef *sdef,int block,FILE *of,
1765 int inStruct, char *tag)
1770 /* if block # then must have function scope */
1771 fprintf(of,"F%s$",moduleName);
1772 fprintf(of,"%s[",(tag ? tag : sdef->tag));
1773 for (sym=sdef->fields ; sym ; sym = sym->next) {
1774 fprintf(of,"({%d}",sym->offset);
1775 cdbSymbol(sym,of,TRUE,FALSE);
1783 /*------------------------------------------------------------------*/
1784 /* cdbStructBlock - calls struct printing for a blcks */
1785 /*------------------------------------------------------------------*/
1786 void cdbStructBlock (int block , FILE *of)
1789 bucket **table = StructTab;
1792 /* go thru the entire table */
1793 for ( i = 0 ; i < 256; i++ ) {
1794 for ( chain = table[i]; chain ; chain = chain->next ) {
1795 if (chain->block >= block) {
1796 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1802 /*-----------------------------------------------------------------*/
1803 /* powof2 - returns power of two for the number if number is pow 2 */
1804 /*-----------------------------------------------------------------*/
1805 int powof2 (unsigned long num)
1811 if (num & 1) n1s++ ;
1816 if (n1s > 1 || nshifts == 0) return 0;
1817 return nshifts - 1 ;
1863 /*-----------------------------------------------------------------*/
1864 /* initCSupport - create functions for C support routines */
1865 /*-----------------------------------------------------------------*/
1866 void initCSupport ()
1868 charType = newCharLink();
1869 intType = newIntLink();
1870 floatType= newFloatLink();
1871 longType = newLongLink();
1872 ucharType = copyLinkChain(charType);
1873 SPEC_USIGN(ucharType) = 1;
1874 ulongType = copyLinkChain(longType);
1875 SPEC_USIGN(ulongType) = 1;
1876 uintType = copyLinkChain(intType);
1877 SPEC_USIGN(uintType) = 1;
1880 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1881 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1882 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1883 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1884 __fseq = funcOfType ("__fseq", charType, floatType, 2, options.float_rent);
1885 __fsneq = funcOfType ("__fsneq", charType, floatType, 2, options.float_rent);
1886 __fslt = funcOfType ("__fslt", charType, floatType, 2, options.float_rent);
1887 __fslteq= funcOfType ("__fslteq", charType, floatType, 2, options.float_rent);
1888 __fsgt = funcOfType ("__fsgt", charType, floatType, 2, options.float_rent);
1889 __fsgteq= funcOfType ("__fsgteq", charType, floatType, 2, options.float_rent);
1891 __fs2uchar = funcOfType ("__fs2uchar",ucharType,floatType,1, options.float_rent);
1892 __fs2uint = funcOfType ("__fs2uint",uintType,floatType,1, options.float_rent);
1893 __fs2ulong = funcOfType ("__fs2ulong",ulongType,floatType,1, options.float_rent);
1894 __fs2char = funcOfType ("__fs2char",charType,floatType,1, options.float_rent);
1895 __fs2int = funcOfType ("__fs2int",intType,floatType,1, options.float_rent);
1896 __fs2long = funcOfType ("__fs2long",longType,floatType,1, options.float_rent);
1898 __long2fs = funcOfType ("__long2fs",floatType,longType,1, options.float_rent);
1899 __ulong2fs = funcOfType ("__ulong2fs",floatType,ulongType,1, options.float_rent);
1900 __int2fs = funcOfType ("__int2fs",floatType,intType,1, options.float_rent);
1901 __uint2fs = funcOfType ("__uint2fs",floatType,uintType,1, options.float_rent);
1902 __char2fs = funcOfType ("__char2fs",floatType,charType,1, options.float_rent);
1903 __uchar2fs = funcOfType ("__uchar2fs",floatType,ucharType,1, options.float_rent);
1905 __muluint = funcOfType ("_muluint",uintType,uintType,2,options.intlong_rent);
1906 __mulsint = funcOfType ("_mulsint",intType,intType,2,options.intlong_rent);
1907 __divuint = funcOfType ("_divuint",uintType,uintType,2,options.intlong_rent);
1908 __divsint = funcOfType ("_divsint",intType,intType,2,options.intlong_rent);
1909 __moduint = funcOfType ("_moduint",uintType,uintType,2,options.intlong_rent);
1910 __modsint = funcOfType ("_modsint",intType,intType,2,options.intlong_rent);
1912 __mululong = funcOfType ("_mululong",ulongType,ulongType,2,options.intlong_rent);
1913 __mulslong = funcOfType ("_mulslong",longType,longType,2,options.intlong_rent);
1914 __divulong = funcOfType ("_divulong",ulongType,ulongType,2,options.intlong_rent);
1915 __divslong = funcOfType ("_divslong",longType,longType,2,options.intlong_rent);
1916 __modulong = funcOfType ("_modulong",ulongType,ulongType,2,options.intlong_rent);
1917 __modslong = funcOfType ("_modslong",longType,longType,2,options.intlong_rent);