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 #include "SDCCglobl.h"
33 bucket *SymbolTab [256] ; /* the symbol table */
34 bucket *StructTab [256] ; /* the structure table */
35 bucket *TypedefTab[256] ; /* the typedef table */
36 bucket *LabelTab [256] ; /* the Label table */
37 bucket *enumTab [256] ; /* enumerated table */
39 extern struct set *publics;
41 /*------------------------------------------------------------------*/
42 /* initSymt () - initialises symbol table related stuff */
43 /*------------------------------------------------------------------*/
48 for ( i = 0 ; i < 256 ; i++ )
49 SymbolTab[i] = StructTab[i] = (void *) NULL ;
53 /*-----------------------------------------------------------------*/
54 /* newBucket - allocates & returns a new bucket */
55 /*-----------------------------------------------------------------*/
60 ALLOC(bp,sizeof(bucket));
65 /*-----------------------------------------------------------------*/
66 /* hashKey - computes the hashkey given a symbol name */
67 /*-----------------------------------------------------------------*/
70 unsigned long key = 0;
77 /*-----------------------------------------------------------------*/
78 /* addSym - adds a symbol to the hash Table */
79 /*-----------------------------------------------------------------*/
80 void addSym ( bucket **stab ,
86 int i ; /* index into the hash Table */
87 bucket *bp ; /* temp bucket * */
89 /* the symbols are always added at the head of the list */
91 /* get a free entry */
92 ALLOC(bp,sizeof(bucket));
94 bp->sym = sym ; /* update the symbol pointer */
95 bp->level = level; /* update the nest level */
97 strcpy(bp->name,sname); /* copy the name into place */
99 /* if this is the first entry */
100 if (stab[i] == NULL) {
101 bp->prev = bp->next = (void *) NULL ; /* point to nothing */
104 /* not first entry then add @ head of list */
113 /*-----------------------------------------------------------------*/
114 /* deleteSym - deletes a symbol from the hash Table entry */
115 /*-----------------------------------------------------------------*/
116 void deleteSym ( bucket **stab, void *sym, char *sname)
124 /* find the symbol */
126 if (bp->sym == sym) /* found it then break out */
127 break ; /* of the loop */
131 if (!bp) /* did not find it */
133 /* if this is the first one in the chain */
136 if ( stab[i] ) /* if chain ! empty */
137 stab[i]->prev = (void *) NULL ;
139 /* middle || end of chain */
141 if ( bp->next ) /* if not end of chain */
142 bp->next->prev = bp->prev ;
144 bp->prev->next = bp->next ;
149 /*-----------------------------------------------------------------*/
150 /* findSym - finds a symbol in a table */
151 /*-----------------------------------------------------------------*/
152 void *findSym ( bucket **stab, void *sym, char *sname)
156 bp = stab[hashKey(sname)] ;
159 if ( bp->sym == sym || strcmp (bp->name,sname) == 0 )
164 return ( bp ? bp->sym : (void *) NULL ) ;
167 /*-----------------------------------------------------------------*/
168 /* findSymWithLevel - finds a symbol with a name & level */
169 /*-----------------------------------------------------------------*/
170 void *findSymWithLevel ( bucket **stab, symbol *sym)
174 bp = stab[hashKey(sym->name)];
177 ** do the search from the head of the list since the
178 ** elements are added at the head it is ensured that
179 ** we will find the deeper definitions before we find
180 ** the global ones. we need to check for symbols with
181 ** level <= to the level given, if levels match then block
182 ** numbers need to match as well
186 if ( strcmp(bp->name,sym->name) == 0 && bp->level <= sym->level) {
187 /* if this is parameter then nothing else need to be checked */
188 if (((symbol *)(bp->sym))->_isparm)
190 /* if levels match then block numbers hsould also match */
191 if (bp->level && bp->level == sym->level && bp->block == sym->block )
193 /* if levels don't match then we are okay */
194 if (bp->level && bp->level != sym->level)
196 /* if this is a global variable then we are ok too */
204 return (void *) NULL ;
207 /*-----------------------------------------------------------------*/
208 /* findSymWithBlock - finds a symbol with name in with a block */
209 /*-----------------------------------------------------------------*/
210 void *findSymWithBlock ( bucket **stab, symbol *sym, int block)
214 bp = stab[hashKey(sym->name)] ;
217 if ( strcmp (bp->name,sym->name) == 0 &&
223 return ( bp ? bp->sym : (void *) NULL ) ;
226 /*------------------------------------------------------------------*/
227 /* newSymbol () - returns a new pointer to a symbol */
228 /*------------------------------------------------------------------*/
229 symbol *newSymbol (char *name, int scope )
233 ALLOC(sym,sizeof(symbol));
235 strcpy(sym->name,name); /* copy the name */
236 sym->level = scope ; /* set the level */
237 sym->block = currBlockno ;
238 sym->lineDef = yylineno ; /* set the line number */
242 /*------------------------------------------------------------------*/
243 /* newLink - creates a new link (declarator,specifier) */
244 /*------------------------------------------------------------------*/
249 ALLOC(p,sizeof(link));
254 /*------------------------------------------------------------------*/
255 /* newStruct - creats a new structdef from the free list */
256 /*------------------------------------------------------------------*/
257 structdef *newStruct ( char *tag )
261 ALLOC(s,sizeof(structdef));
263 strcpy(s->tag,tag) ; /* copy the tag */
267 /*------------------------------------------------------------------*/
268 /* pointerTypes - do the computation for the pointer types */
269 /*------------------------------------------------------------------*/
270 void pointerTypes (link *ptr, link *type)
275 /* find the first pointer type */
276 while (ptr && !IS_PTR(ptr))
279 /* could not find it */
280 if (!ptr || IS_SPEC(ptr) ||
281 DCL_TYPE(ptr) != UPOINTER)
284 /* change the pointer type depending on the
285 storage class of the type */
287 DCL_PTR_CONST(ptr) = SPEC_CONST(type);
288 DCL_PTR_VOLATILE(ptr) = SPEC_VOLATILE(type);
289 switch (SPEC_SCLS(type)) {
291 DCL_TYPE(ptr) = FPOINTER;
294 DCL_TYPE(ptr) = IPOINTER ;
297 DCL_TYPE(ptr) = PPOINTER ;
300 DCL_TYPE(ptr) = POINTER ;
303 DCL_PTR_CONST(ptr) = 1;
304 DCL_TYPE(ptr) = CPOINTER ;
307 DCL_TYPE(ptr) = GPOINTER;
310 /* the storage class of type ends here */
313 SPEC_VOLATILE(type) = 0;
316 /* now change all the remaining unknown pointers
317 to generic pointers */
319 if (!IS_SPEC(ptr) && DCL_TYPE(ptr) == UPOINTER)
320 DCL_TYPE(ptr) = GPOINTER;
324 /* same for the type although it is highly unlikely that
325 type will have a pointer */
327 if (!IS_SPEC(type) && DCL_TYPE(type) == UPOINTER)
328 DCL_TYPE(type) = GPOINTER;
334 /*------------------------------------------------------------------*/
335 /* addDecl - adds a declarator @ the end of a chain */
336 /*------------------------------------------------------------------*/
337 void addDecl ( symbol *sym, int type , link *p )
343 /* if we are passed a link then set head & tail */
350 head = tail = newLink() ;
351 DCL_TYPE(head) = type ;
354 /* if this is the first entry */
360 if ( IS_SPEC(sym->etype) && IS_SPEC(head) && head == tail ) {
361 sym->etype = mergeSpec(sym->etype,head);
364 if ( IS_SPEC(sym->etype) && !IS_SPEC(head) && head == tail ) {
366 while (t->next != sym->etype) t = t->next ;
368 tail->next = sym->etype;
370 sym->etype->next = head;
376 /* if the type is a unknown pointer and has
377 a tspec then take the storage class const & volatile
378 attribute from the tspec & make it those of this
382 DCL_TYPE(p) == UPOINTER &&
384 if (!IS_SPEC(sym->etype)) {
385 sym->etype = sym->etype->next = newLink();
386 sym->etype->class = SPECIFIER;
388 SPEC_SCLS(sym->etype) = SPEC_SCLS(DCL_TSPEC(p));
389 SPEC_CONST(sym->etype) = SPEC_CONST(DCL_TSPEC(p));
390 SPEC_VOLATILE(sym->etype) = SPEC_VOLATILE(DCL_TSPEC(p));
396 /*------------------------------------------------------------------*/
397 /* mergeSpec - merges two specifiers and returns the new one */
398 /*------------------------------------------------------------------*/
399 link *mergeSpec ( link *dest, link *src )
401 /* if noun different then src overrides */
402 if ( SPEC_NOUN(dest) != SPEC_NOUN(src) && !SPEC_NOUN(dest))
403 SPEC_NOUN(dest) = SPEC_NOUN(src) ;
405 if (! SPEC_SCLS(dest)) /* if destination has no storage class */
406 SPEC_SCLS(dest) = SPEC_SCLS(src) ;
408 /* copy all the specifications */
409 SPEC_LONG(dest) |= SPEC_LONG(src);
410 SPEC_SHORT(dest) |= SPEC_SHORT(src);
411 SPEC_USIGN(dest) |= SPEC_USIGN(src);
412 SPEC_STAT(dest) |= SPEC_STAT(src);
413 SPEC_EXTR(dest) |= SPEC_EXTR(src);
414 SPEC_ABSA(dest) |= SPEC_ABSA(src);
415 SPEC_RENT(dest) |= SPEC_RENT(src);
416 SPEC_INTN(dest) |= SPEC_INTN(src);
417 SPEC_BANK(dest) |= SPEC_BANK(src);
418 SPEC_VOLATILE(dest) |= SPEC_VOLATILE(src);
419 SPEC_CRTCL(dest) |= SPEC_CRTCL(src);
420 SPEC_ADDR(dest) |= SPEC_ADDR(src);
421 SPEC_OCLS(dest) = SPEC_OCLS(src);
422 SPEC_BLEN(dest) |= SPEC_BLEN(src);
423 SPEC_BSTR(dest) |= SPEC_BSTR(src);
424 SPEC_TYPEDEF(dest) |= SPEC_TYPEDEF(src);
426 if ( IS_STRUCT(dest) && SPEC_STRUCT(dest) == NULL )
427 SPEC_STRUCT(dest) = SPEC_STRUCT(src);
432 /*------------------------------------------------------------------*/
433 /* cloneSpec - copies the entire spec and returns a new spec */
434 /*------------------------------------------------------------------*/
435 link *cloneSpec ( link *src )
439 /* go thru chain till we find the specifier */
440 while ( src && src->class != SPECIFIER )
444 memcpy (spec,src,sizeof(link));
448 /*------------------------------------------------------------------*/
449 /* genSymName - generates and returns a name used for anonymous vars*/
450 /*------------------------------------------------------------------*/
451 char *genSymName ( int level )
453 static int gCount = 0 ;
454 static char gname[SDCC_NAME_MAX+1] ;
456 sprintf (gname,"__%04d%04d",level,gCount++);
460 /*------------------------------------------------------------------*/
461 /* getSpec - returns the specifier part from a declaration chain */
462 /*------------------------------------------------------------------*/
463 link *getSpec ( link *p )
468 while ( p && ! (IS_SPEC(p)))
474 /*------------------------------------------------------------------*/
475 /* newCharLink() - creates an int type */
476 /*------------------------------------------------------------------*/
482 p->class = SPECIFIER ;
483 SPEC_NOUN(p) = V_CHAR ;
488 /*------------------------------------------------------------------*/
489 /* newFloatLink - a new Float type */
490 /*------------------------------------------------------------------*/
496 p->class = SPECIFIER ;
497 SPEC_NOUN(p) = V_FLOAT ;
502 /*------------------------------------------------------------------*/
503 /* newLongLink() - new long type */
504 /*------------------------------------------------------------------*/
510 p->class = SPECIFIER ;
511 SPEC_NOUN(p) = V_INT ;
517 /*------------------------------------------------------------------*/
518 /* newIntLink() - creates an int type */
519 /*------------------------------------------------------------------*/
525 p->class = SPECIFIER ;
526 SPEC_NOUN(p) = V_INT ;
531 /*------------------------------------------------------------------*/
532 /* getSize - returns size of a type chain in bits */
533 /*------------------------------------------------------------------*/
534 unsigned int getSize ( link *p )
536 /* if nothing return 0 */
540 if ( IS_SPEC(p) ) { /* if this is the specifier then */
542 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
544 return (IS_LONG(p) ? LONGSIZE : ( IS_SHORT(p) ? SHORTSIZE: INTSIZE)) ;
552 return SPEC_STRUCT(p)->size ;
558 return ((SPEC_BLEN(p) / 8) + (SPEC_BLEN(p) % 8 ? 1 : 0)) ;
564 /* this is a specifier */
565 switch (DCL_TYPE(p)) {
569 return DCL_ELEM(p) * getSize (p->next) ;
585 /*------------------------------------------------------------------*/
586 /* bitsForType - returns # of bits required to store this type */
587 /*------------------------------------------------------------------*/
588 unsigned int bitsForType ( link *p )
590 /* if nothing return 0 */
594 if ( IS_SPEC(p) ) { /* if this is the specifier then */
596 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
598 return (IS_LONG(p) ? LONGSIZE*8 : ( IS_SHORT(p) ? SHORTSIZE*8: INTSIZE*8)) ;
606 return SPEC_STRUCT(p)->size*8 ;
618 /* this is a specifier */
619 switch (DCL_TYPE(p)) {
623 return DCL_ELEM(p) * getSize (p->next) *8 ;
627 return ( PTRSIZE * 8) ;
630 return ( FPTRSIZE * 8);
632 return ( GPTRSIZE * 8);
639 /*------------------------------------------------------------------*/
640 /* copySymbolChain - copies a symbol chain */
641 /*------------------------------------------------------------------*/
642 symbol *copySymbolChain (symbol *src)
649 dest = copySymbol(src);
650 dest->next = copySymbolChain(src->next);
654 /*------------------------------------------------------------------*/
655 /* copySymbol - makes a copy of a symbol */
656 /*------------------------------------------------------------------*/
657 symbol *copySymbol (symbol *src)
664 dest = newSymbol( src->name, src->level );
665 memcpy(dest,src,sizeof(symbol));
666 dest->level = src->level ;
667 dest->block = src->block ;
668 dest->ival = copyIlist(src->ival);
669 dest->type = copyLinkChain(src->type);
670 dest->etype= getSpec(dest->type);
672 dest->args = copyValueChain (src->args);
673 dest->key = src->key;
674 dest->calleeSave = src->calleeSave;
675 dest->allocreq = src->allocreq;
679 /*------------------------------------------------------------------*/
680 /* reverseSyms - reverses the links for a symbol chain */
681 /*------------------------------------------------------------------*/
682 symbol *reverseSyms ( symbol *sym)
684 symbol *prev , *curr, *next ;
699 sym->next = (void *) NULL ;
703 /*------------------------------------------------------------------*/
704 /* reverseLink - reverses the links for a type chain */
705 /*------------------------------------------------------------------*/
706 link *reverseLink ( link *type)
708 link *prev , *curr, *next ;
723 type->next = (void *) NULL ;
727 /*------------------------------------------------------------------*/
728 /* addSymChain - adds a symbol chain to the symboltable */
729 /*------------------------------------------------------------------*/
730 void addSymChain ( symbol *symHead )
732 symbol *sym = symHead ;
733 symbol *csym = NULL ;
735 for (;sym != NULL ; sym = sym->next ) {
737 /* if already exists in the symbol table then check if
738 the previous was an extern definition if yes then
739 then check if the type match, if the types match then
740 delete the current entry and add the new entry */
741 if ((csym = findSymWithLevel (SymbolTab,sym)) &&
742 csym->level == sym->level) {
744 /* previous definition extern ? */
745 if ( IS_EXTERN(csym->etype) ) {
746 /* do types match ? */
747 if (checkType ( csym->type,sym->type) != 1)
749 werror (E_DUPLICATE,csym->name);
751 /* delete current entry */
752 deleteSym (SymbolTab, csym, csym->name );
754 addSym (SymbolTab, sym, sym->name, sym->level,sym->block);
755 } else /* not extern */
756 werror(E_DUPLICATE,sym->name) ;
760 /* check if previously defined */
761 if (csym && csym->level == sym->level ) {
762 /* if the previous one was declared as extern */
763 /* then check the type with the current one */
764 if ( IS_EXTERN(csym->etype) ) {
765 if ( checkType (csym->type, sym->type ) <= 0 )
766 werror (W_EXTERN_MISMATCH,csym->name);
770 addSym (SymbolTab,sym,sym->name,sym->level,sym->block) ;
775 /*------------------------------------------------------------------*/
776 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
777 /*------------------------------------------------------------------*/
778 int funcInChain (link *lnk)
788 /*------------------------------------------------------------------*/
789 /* structElemType - returns the type info of a sturct member */
790 /*------------------------------------------------------------------*/
791 link *structElemType (link *stype, value *id ,value **argsp)
793 symbol *fields = (SPEC_STRUCT(stype) ? SPEC_STRUCT(stype)->fields : NULL);
795 if ( ! fields || ! id)
798 /* look for the id */
800 if (strcmp(fields->rname,id->name) == 0) {
802 *argsp = fields->args;
804 return copyLinkChain (fields->type) ;
806 fields = fields->next ;
808 werror(E_NOT_MEMBER,id->name);
813 /*------------------------------------------------------------------*/
814 /* getStructElement - returns element of a tructure definition */
815 /*------------------------------------------------------------------*/
816 symbol *getStructElement ( structdef *sdef, symbol *sym)
820 for ( field = sdef->fields ; field ; field = field->next )
821 if ( strcmp(field->name,sym->name) == 0)
824 werror(E_NOT_MEMBER,sym->name);
826 return sdef->fields ;
829 /*------------------------------------------------------------------*/
830 /* compStructSize - computes the size of a structure */
831 /*------------------------------------------------------------------*/
832 int compStructSize (int su, structdef *sdef )
834 int sum = 0 , usum =0;
838 /* for the identifiers */
839 loop = sdef->fields ;
842 /* create the internal name for this variable */
843 sprintf (loop->rname,"_%s",loop->name);
844 loop->offset = ( su == UNION ? sum = 0 : sum ) ;
845 SPEC_VOLATILE(loop->etype) |= (su == UNION ? 1 : 0);
847 /* if this is a bit field */
850 /* change it to a unsigned bit */
851 SPEC_NOUN(loop->etype) = V_BIT ;
852 SPEC_USIGN(loop->etype) = 1 ;
853 /* check if this fit into the remaining */
854 /* bits of this byte else align it to the */
855 /* next byte boundary */
856 if ((SPEC_BLEN(loop->etype)=loop->bitVar) <= (8 - bitOffset)) {
857 SPEC_BSTR(loop->etype) = bitOffset ;
858 sum += (loop->bitVar / 8) ;
859 bitOffset += (loop->bitVar % 8);
861 else /* does not fit */
864 loop->offset++; /* go to the next byte */
866 SPEC_BSTR(loop->etype) = bitOffset ;
867 sum += (loop->bitVar / 8) ;
868 bitOffset += (loop->bitVar % 8);
870 /* if this is the last field then pad */
871 if (!loop->next && bitOffset) {
878 sum += getSize (loop->type) ;
881 /* if function then do the arguments for it */
882 if (funcInChain(loop->type)) {
883 processFuncArgs (loop, 1);
888 /* if this is not a bitfield but the */
889 /* previous one was and did not take */
890 /* the whole byte then pad the rest */
891 if ((loop && !loop->bitVar) && bitOffset) {
896 /* if union then size = sizeof larget field */
898 usum = max(usum,sum);
902 return (su == UNION ? usum : sum);
905 /*------------------------------------------------------------------*/
906 /* checkSClass - check the storage class specification */
907 /*------------------------------------------------------------------*/
908 void checkSClass ( symbol *sym )
910 /* if sfr or sbit then must also be */
911 /* volatile the initial value will be xlated */
912 /* to an absolute address */
913 if (SPEC_SCLS(sym->etype) == S_SBIT ||
914 SPEC_SCLS(sym->etype) == S_SFR ) {
915 SPEC_VOLATILE(sym->etype) = 1;
916 /* if initial value given */
918 SPEC_ABSA(sym->etype) = 1;
919 SPEC_ADDR(sym->etype) =
920 (int) list2int(sym->ival);
925 /* if absolute address given then it mark it as
927 if (IS_ABSOLUTE(sym->etype))
928 SPEC_VOLATILE(sym->etype) = 1;
930 /* global variables declared const put into code */
931 if (sym->level == 0 &&
932 SPEC_SCLS(sym->etype) == S_CONSTANT)
933 SPEC_SCLS(sym->etype) = S_CODE ;
936 /* global variable in code space is a constant */
937 if (sym->level == 0 &&
938 SPEC_SCLS(sym->etype) == S_CODE)
939 SPEC_CONST(sym->etype) = 1;
942 /* if bit variable then no storage class can be */
943 /* specified since bit is already a storage */
944 if ( IS_BITVAR(sym->etype) &&
945 ( SPEC_SCLS(sym->etype) != S_FIXED &&
946 SPEC_SCLS(sym->etype) != S_SBIT &&
947 SPEC_SCLS(sym->etype) != S_BIT )
949 werror (E_BITVAR_STORAGE,sym->name);
950 SPEC_SCLS(sym->etype) = S_FIXED ;
953 /* extern variables cannot be initialized */
954 if (IS_EXTERN(sym->etype) && sym->ival) {
955 werror(E_EXTERN_INIT,sym->name);
959 /* if this is an automatic symbol then */
960 /* storage class will be ignored and */
961 /* symbol will be allocated on stack/ */
962 /* data depending on flag */
964 (options.stackAuto || reentrant ) &&
965 ( SPEC_SCLS(sym->etype) != S_AUTO &&
966 SPEC_SCLS(sym->etype) != S_FIXED &&
967 SPEC_SCLS(sym->etype) != S_REGISTER &&
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.model ?
1011 S_XSTACK : S_STACK ) ;
1013 SPEC_SCLS(sym->etype) = (options.model ?
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);