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) = EEPPOINTER;
303 DCL_TYPE(ptr) = GPOINTER;
306 /* the storage class of type ends here */
309 SPEC_VOLATILE(type) = 0;
312 /* now change all the remaining unknown pointers
313 to generic pointers */
315 if (!IS_SPEC(ptr) && DCL_TYPE(ptr) == UPOINTER)
316 DCL_TYPE(ptr) = GPOINTER;
320 /* same for the type although it is highly unlikely that
321 type will have a pointer */
323 if (!IS_SPEC(type) && DCL_TYPE(type) == UPOINTER)
324 DCL_TYPE(type) = GPOINTER;
330 /*------------------------------------------------------------------*/
331 /* addDecl - adds a declarator @ the end of a chain */
332 /*------------------------------------------------------------------*/
333 void addDecl ( symbol *sym, int type , link *p )
339 /* if we are passed a link then set head & tail */
346 head = tail = newLink() ;
347 DCL_TYPE(head) = type ;
350 /* if this is the first entry */
356 if ( IS_SPEC(sym->etype) && IS_SPEC(head) && head == tail ) {
357 sym->etype = mergeSpec(sym->etype,head);
360 if ( IS_SPEC(sym->etype) && !IS_SPEC(head) && head == tail ) {
362 while (t->next != sym->etype) t = t->next ;
364 tail->next = sym->etype;
366 sym->etype->next = head;
372 /* if the type is a unknown pointer and has
373 a tspec then take the storage class const & volatile
374 attribute from the tspec & make it those of this
378 DCL_TYPE(p) == UPOINTER &&
380 if (!IS_SPEC(sym->etype)) {
381 sym->etype = sym->etype->next = newLink();
382 sym->etype->class = SPECIFIER;
384 SPEC_SCLS(sym->etype) = SPEC_SCLS(DCL_TSPEC(p));
385 SPEC_CONST(sym->etype) = SPEC_CONST(DCL_TSPEC(p));
386 SPEC_VOLATILE(sym->etype) = SPEC_VOLATILE(DCL_TSPEC(p));
392 /*------------------------------------------------------------------*/
393 /* mergeSpec - merges two specifiers and returns the new one */
394 /*------------------------------------------------------------------*/
395 link *mergeSpec ( link *dest, link *src )
397 /* if noun different then src overrides */
398 if ( SPEC_NOUN(dest) != SPEC_NOUN(src) && !SPEC_NOUN(dest))
399 SPEC_NOUN(dest) = SPEC_NOUN(src) ;
401 if (! SPEC_SCLS(dest)) /* if destination has no storage class */
402 SPEC_SCLS(dest) = SPEC_SCLS(src) ;
404 /* copy all the specifications */
405 SPEC_LONG(dest) |= SPEC_LONG(src);
406 SPEC_SHORT(dest) |= SPEC_SHORT(src);
407 SPEC_USIGN(dest) |= SPEC_USIGN(src);
408 SPEC_STAT(dest) |= SPEC_STAT(src);
409 SPEC_EXTR(dest) |= SPEC_EXTR(src);
410 SPEC_ABSA(dest) |= SPEC_ABSA(src);
411 SPEC_RENT(dest) |= SPEC_RENT(src);
412 SPEC_INTN(dest) |= SPEC_INTN(src);
413 SPEC_BANK(dest) |= SPEC_BANK(src);
414 SPEC_VOLATILE(dest) |= SPEC_VOLATILE(src);
415 SPEC_CRTCL(dest) |= SPEC_CRTCL(src);
416 SPEC_ADDR(dest) |= SPEC_ADDR(src);
417 SPEC_OCLS(dest) = SPEC_OCLS(src);
418 SPEC_BLEN(dest) |= SPEC_BLEN(src);
419 SPEC_BSTR(dest) |= SPEC_BSTR(src);
420 SPEC_TYPEDEF(dest) |= SPEC_TYPEDEF(src);
422 if ( IS_STRUCT(dest) && SPEC_STRUCT(dest) == NULL )
423 SPEC_STRUCT(dest) = SPEC_STRUCT(src);
428 /*------------------------------------------------------------------*/
429 /* cloneSpec - copies the entire spec and returns a new spec */
430 /*------------------------------------------------------------------*/
431 link *cloneSpec ( link *src )
435 /* go thru chain till we find the specifier */
436 while ( src && src->class != SPECIFIER )
440 memcpy (spec,src,sizeof(link));
444 /*------------------------------------------------------------------*/
445 /* genSymName - generates and returns a name used for anonymous vars*/
446 /*------------------------------------------------------------------*/
447 char *genSymName ( int level )
449 static int gCount = 0 ;
450 static char gname[SDCC_NAME_MAX+1] ;
452 sprintf (gname,"__%04d%04d",level,gCount++);
456 /*------------------------------------------------------------------*/
457 /* getSpec - returns the specifier part from a declaration chain */
458 /*------------------------------------------------------------------*/
459 link *getSpec ( link *p )
464 while ( p && ! (IS_SPEC(p)))
470 /*------------------------------------------------------------------*/
471 /* newCharLink() - creates an int type */
472 /*------------------------------------------------------------------*/
478 p->class = SPECIFIER ;
479 SPEC_NOUN(p) = V_CHAR ;
484 /*------------------------------------------------------------------*/
485 /* newFloatLink - a new Float type */
486 /*------------------------------------------------------------------*/
492 p->class = SPECIFIER ;
493 SPEC_NOUN(p) = V_FLOAT ;
498 /*------------------------------------------------------------------*/
499 /* newLongLink() - new long type */
500 /*------------------------------------------------------------------*/
506 p->class = SPECIFIER ;
507 SPEC_NOUN(p) = V_INT ;
513 /*------------------------------------------------------------------*/
514 /* newIntLink() - creates an int type */
515 /*------------------------------------------------------------------*/
521 p->class = SPECIFIER ;
522 SPEC_NOUN(p) = V_INT ;
527 /*------------------------------------------------------------------*/
528 /* getSize - returns size of a type chain in bits */
529 /*------------------------------------------------------------------*/
530 unsigned int getSize ( link *p )
532 /* if nothing return 0 */
535 if ( IS_SPEC(p) ) { /* if this is the specifier then */
536 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
538 return (IS_LONG(p) ? LONGSIZE : ( IS_SHORT(p) ? SHORTSIZE: INTSIZE)) ;
546 return SPEC_STRUCT(p)->size ;
552 return ((SPEC_BLEN(p) / 8) + (SPEC_BLEN(p) % 8 ? 1 : 0)) ;
558 /* this is a specifier */
559 switch (DCL_TYPE(p)) {
563 return DCL_ELEM(p) * getSize (p->next) ;
580 /*------------------------------------------------------------------*/
581 /* bitsForType - returns # of bits required to store this type */
582 /*------------------------------------------------------------------*/
583 unsigned int bitsForType ( link *p )
585 /* if nothing return 0 */
589 if ( IS_SPEC(p) ) { /* if this is the specifier then */
591 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
593 return (IS_LONG(p) ? LONGSIZE*8 : ( IS_SHORT(p) ? SHORTSIZE*8: INTSIZE*8)) ;
601 return SPEC_STRUCT(p)->size*8 ;
613 /* this is a specifier */
614 switch (DCL_TYPE(p)) {
618 return DCL_ELEM(p) * getSize (p->next) *8 ;
622 return ( PTRSIZE * 8) ;
626 return ( FPTRSIZE * 8);
628 return ( GPTRSIZE * 8);
635 /*------------------------------------------------------------------*/
636 /* copySymbolChain - copies a symbol chain */
637 /*------------------------------------------------------------------*/
638 symbol *copySymbolChain (symbol *src)
645 dest = copySymbol(src);
646 dest->next = copySymbolChain(src->next);
650 /*------------------------------------------------------------------*/
651 /* copySymbol - makes a copy of a symbol */
652 /*------------------------------------------------------------------*/
653 symbol *copySymbol (symbol *src)
660 dest = newSymbol( src->name, src->level );
661 memcpy(dest,src,sizeof(symbol));
662 dest->level = src->level ;
663 dest->block = src->block ;
664 dest->ival = copyIlist(src->ival);
665 dest->type = copyLinkChain(src->type);
666 dest->etype= getSpec(dest->type);
668 dest->args = copyValueChain (src->args);
669 dest->key = src->key;
670 dest->calleeSave = src->calleeSave;
671 dest->allocreq = src->allocreq;
675 /*------------------------------------------------------------------*/
676 /* reverseSyms - reverses the links for a symbol chain */
677 /*------------------------------------------------------------------*/
678 symbol *reverseSyms ( symbol *sym)
680 symbol *prev , *curr, *next ;
695 sym->next = (void *) NULL ;
699 /*------------------------------------------------------------------*/
700 /* reverseLink - reverses the links for a type chain */
701 /*------------------------------------------------------------------*/
702 link *reverseLink ( link *type)
704 link *prev , *curr, *next ;
719 type->next = (void *) NULL ;
723 /*------------------------------------------------------------------*/
724 /* addSymChain - adds a symbol chain to the symboltable */
725 /*------------------------------------------------------------------*/
726 void addSymChain ( symbol *symHead )
728 symbol *sym = symHead ;
729 symbol *csym = NULL ;
731 for (;sym != NULL ; sym = sym->next ) {
733 /* if already exists in the symbol table then check if
734 the previous was an extern definition if yes then
735 then check if the type match, if the types match then
736 delete the current entry and add the new entry */
737 if ((csym = findSymWithLevel (SymbolTab,sym)) &&
738 csym->level == sym->level) {
740 /* previous definition extern ? */
741 if ( IS_EXTERN(csym->etype) ) {
742 /* do types match ? */
743 if (checkType ( csym->type,sym->type) != 1)
745 werror (E_DUPLICATE,csym->name);
747 /* delete current entry */
748 deleteSym (SymbolTab, csym, csym->name );
750 addSym (SymbolTab, sym, sym->name, sym->level,sym->block);
751 } else /* not extern */
752 werror(E_DUPLICATE,sym->name) ;
756 /* check if previously defined */
757 if (csym && csym->level == sym->level ) {
758 /* if the previous one was declared as extern */
759 /* then check the type with the current one */
760 if ( IS_EXTERN(csym->etype) ) {
761 if ( checkType (csym->type, sym->type ) <= 0 )
762 werror (W_EXTERN_MISMATCH,csym->name);
766 addSym (SymbolTab,sym,sym->name,sym->level,sym->block) ;
771 /*------------------------------------------------------------------*/
772 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
773 /*------------------------------------------------------------------*/
774 int funcInChain (link *lnk)
784 /*------------------------------------------------------------------*/
785 /* structElemType - returns the type info of a sturct member */
786 /*------------------------------------------------------------------*/
787 link *structElemType (link *stype, value *id ,value **argsp)
789 symbol *fields = (SPEC_STRUCT(stype) ? SPEC_STRUCT(stype)->fields : NULL);
791 if ( ! fields || ! id)
794 /* look for the id */
796 if (strcmp(fields->rname,id->name) == 0) {
798 *argsp = fields->args;
800 return copyLinkChain (fields->type) ;
802 fields = fields->next ;
804 werror(E_NOT_MEMBER,id->name);
809 /*------------------------------------------------------------------*/
810 /* getStructElement - returns element of a tructure definition */
811 /*------------------------------------------------------------------*/
812 symbol *getStructElement ( structdef *sdef, symbol *sym)
816 for ( field = sdef->fields ; field ; field = field->next )
817 if ( strcmp(field->name,sym->name) == 0)
820 werror(E_NOT_MEMBER,sym->name);
822 return sdef->fields ;
825 /*------------------------------------------------------------------*/
826 /* compStructSize - computes the size of a structure */
827 /*------------------------------------------------------------------*/
828 int compStructSize (int su, structdef *sdef )
830 int sum = 0 , usum =0;
834 /* for the identifiers */
835 loop = sdef->fields ;
838 /* create the internal name for this variable */
839 sprintf (loop->rname,"_%s",loop->name);
840 loop->offset = ( su == UNION ? sum = 0 : sum ) ;
841 SPEC_VOLATILE(loop->etype) |= (su == UNION ? 1 : 0);
843 /* if this is a bit field */
846 /* change it to a unsigned bit */
847 SPEC_NOUN(loop->etype) = V_BIT ;
848 SPEC_USIGN(loop->etype) = 1 ;
849 /* check if this fit into the remaining */
850 /* bits of this byte else align it to the */
851 /* next byte boundary */
852 if ((SPEC_BLEN(loop->etype)=loop->bitVar) <= (8 - bitOffset)) {
853 SPEC_BSTR(loop->etype) = bitOffset ;
854 sum += (loop->bitVar / 8) ;
855 bitOffset += (loop->bitVar % 8);
857 else /* does not fit */
860 loop->offset++; /* go to the next byte */
862 SPEC_BSTR(loop->etype) = bitOffset ;
863 sum += (loop->bitVar / 8) ;
864 bitOffset += (loop->bitVar % 8);
866 /* if this is the last field then pad */
867 if (!loop->next && bitOffset) {
874 sum += getSize (loop->type) ;
877 /* if function then do the arguments for it */
878 if (funcInChain(loop->type)) {
879 processFuncArgs (loop, 1);
884 /* if this is not a bitfield but the */
885 /* previous one was and did not take */
886 /* the whole byte then pad the rest */
887 if ((loop && !loop->bitVar) && bitOffset) {
892 /* if union then size = sizeof larget field */
894 usum = max(usum,sum);
898 return (su == UNION ? usum : sum);
901 /*------------------------------------------------------------------*/
902 /* checkSClass - check the storage class specification */
903 /*------------------------------------------------------------------*/
904 static void checkSClass ( symbol *sym )
906 /* type is literal can happen foe enums change
908 if (SPEC_SCLS(sym->etype) == S_LITERAL && !SPEC_ENUM(sym->etype))
909 SPEC_SCLS(sym->etype) = S_AUTO;
911 /* if sfr or sbit then must also be */
912 /* volatile the initial value will be xlated */
913 /* to an absolute address */
914 if (SPEC_SCLS(sym->etype) == S_SBIT ||
915 SPEC_SCLS(sym->etype) == S_SFR ) {
916 SPEC_VOLATILE(sym->etype) = 1;
917 /* if initial value given */
919 SPEC_ABSA(sym->etype) = 1;
920 SPEC_ADDR(sym->etype) =
921 (int) list2int(sym->ival);
926 /* if absolute address given then it mark it as
928 if (IS_ABSOLUTE(sym->etype))
929 SPEC_VOLATILE(sym->etype) = 1;
931 /* global variables declared const put into code */
932 if (sym->level == 0 &&
933 SPEC_SCLS(sym->etype) == S_CONSTANT)
934 SPEC_SCLS(sym->etype) = S_CODE ;
937 /* global variable in code space is a constant */
938 if (sym->level == 0 &&
939 SPEC_SCLS(sym->etype) == S_CODE)
940 SPEC_CONST(sym->etype) = 1;
943 /* if bit variable then no storage class can be */
944 /* specified since bit is already a storage */
945 if ( IS_BITVAR(sym->etype) &&
946 ( SPEC_SCLS(sym->etype) != S_FIXED &&
947 SPEC_SCLS(sym->etype) != S_SBIT &&
948 SPEC_SCLS(sym->etype) != S_BIT )
950 werror (E_BITVAR_STORAGE,sym->name);
951 SPEC_SCLS(sym->etype) = S_FIXED ;
954 /* extern variables cannot be initialized */
955 if (IS_EXTERN(sym->etype) && sym->ival) {
956 werror(E_EXTERN_INIT,sym->name);
960 /* if this is an automatic symbol then */
961 /* storage class will be ignored and */
962 /* symbol will be allocated on stack/ */
963 /* data depending on flag */
965 (options.stackAuto || reentrant ) &&
966 ( SPEC_SCLS(sym->etype) != S_AUTO &&
967 SPEC_SCLS(sym->etype) != S_FIXED &&
968 SPEC_SCLS(sym->etype) != S_REGISTER &&
969 SPEC_SCLS(sym->etype) != S_STACK &&
970 SPEC_SCLS(sym->etype) != S_XSTACK &&
971 SPEC_SCLS(sym->etype) != S_CONSTANT )) {
973 werror(E_AUTO_ASSUMED,sym->name) ;
974 SPEC_SCLS(sym->etype) = S_AUTO ;
977 /* automatic symbols cannot be given */
978 /* an absolute address ignore it */
980 SPEC_ABSA(sym->etype) &&
981 (options.stackAuto || reentrant) ) {
982 werror(E_AUTO_ABSA,sym->name);
983 SPEC_ABSA(sym->etype) = 0 ;
986 /* arrays & pointers cannot be defined for bits */
987 /* SBITS or SFRs or BIT */
988 if ((IS_ARRAY(sym->type) || IS_PTR(sym->type)) &&
989 ( SPEC_NOUN(sym->etype) == V_BIT ||
990 SPEC_NOUN(sym->etype) == V_SBIT ||
991 SPEC_SCLS(sym->etype) == S_SFR ))
992 werror(E_BIT_ARRAY,sym->name);
994 /* if this is a bit|sbit then set length & start */
995 if (SPEC_NOUN(sym->etype) == V_BIT ||
996 SPEC_NOUN(sym->etype) == V_SBIT ) {
997 SPEC_BLEN(sym->etype) = 1 ;
998 SPEC_BSTR(sym->etype) = 0 ;
1001 /* variables declared in CODE space must have */
1002 /* initializers if not an extern */
1003 if (SPEC_SCLS(sym->etype) == S_CODE &&
1004 sym->ival == NULL &&
1006 !IS_EXTERN(sym->etype))
1007 werror(E_CODE_NO_INIT,sym->name);
1009 /* if parameter or local variable then change */
1010 /* the storage class to reflect where the var will go */
1011 if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) {
1012 if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype)))
1013 SPEC_SCLS(sym->etype) = (options.useXstack ?
1014 S_XSTACK : S_STACK ) ;
1016 SPEC_SCLS(sym->etype) = (options.useXstack ?
1021 /*------------------------------------------------------------------*/
1022 /* changePointer - change pointer to functions */
1023 /*------------------------------------------------------------------*/
1024 void changePointer (symbol *sym)
1028 /* go thru the chain of declarations */
1029 /* if we find a pointer to a function */
1030 /* unconditionally change it to a ptr */
1032 for ( p = sym->type ; p ; p = p->next) {
1033 if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER)
1034 DCL_TYPE(p) = GPOINTER ;
1035 if ( IS_PTR(p) && IS_FUNC(p->next))
1036 DCL_TYPE(p) = CPOINTER ;
1040 /*------------------------------------------------------------------*/
1041 /* checkDecl - does semantic validation of a declaration */
1042 /*------------------------------------------------------------------*/
1043 int checkDecl ( symbol *sym )
1046 checkSClass (sym); /* check the storage class */
1047 changePointer(sym); /* change pointers if required */
1049 /* if this is an array without any dimension
1050 then update the dimension from the initial value */
1051 if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type))
1052 DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival);
1057 /*------------------------------------------------------------------*/
1058 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1059 /*------------------------------------------------------------------*/
1060 link *copyLinkChain ( link *p)
1062 link *head, *curr , *loop;
1065 head = loop = ( curr ? newLink() : (void *) NULL) ;
1067 memcpy(loop,curr,sizeof(link)) ; /* copy it */
1068 loop->next = (curr->next ? newLink() : (void *) NULL) ;
1077 /*------------------------------------------------------------------*/
1078 /* cleanUpBlock - cleansup the symbol table specified for all the */
1079 /* symbols in the given block */
1080 /*------------------------------------------------------------------*/
1081 void cleanUpBlock ( bucket **table, int block)
1086 /* go thru the entire table */
1087 for ( i = 0 ; i < 256; i++ ) {
1088 for ( chain = table[i]; chain ; chain = chain->next ) {
1089 if (chain->block >= block) {
1090 deleteSym (table,chain->sym,chain->name);
1096 /*------------------------------------------------------------------*/
1097 /* cleanUpLevel - cleansup the symbol table specified for all the */
1098 /* symbols in the given level */
1099 /*------------------------------------------------------------------*/
1100 void cleanUpLevel (bucket **table, int level )
1105 /* go thru the entire table */
1106 for ( i = 0 ; i < 256; i++ ) {
1107 for ( chain = table[i]; chain ; chain = chain->next ) {
1108 if (chain->level >= level) {
1109 deleteSym (table,chain->sym,chain->name);
1115 /*------------------------------------------------------------------*/
1116 /* computeType - computes the resultant type from two types */
1117 /*------------------------------------------------------------------*/
1118 link *computeType ( link *type1, link *type2)
1122 link *etype1 = getSpec(type1);
1123 link *etype2 = getSpec(type2);
1125 /* if one of them is a float then result is a float */
1126 /* here we assume that the types passed are okay */
1127 /* and can be cast to one another */
1128 /* which ever is greater in size */
1129 if (IS_FLOAT(etype1) || IS_FLOAT(etype2))
1130 rType = newFloatLink();
1132 /* if only one of them is a bit variable
1133 then the other one prevails */
1134 if (IS_BITVAR(etype1) && !IS_BITVAR(etype2))
1135 rType = copyLinkChain(type2);
1137 if (IS_BITVAR(etype2) && !IS_BITVAR(etype1))
1138 rType = copyLinkChain(type1);
1140 /* if one of them is a pointer then that
1143 rType = copyLinkChain(type1);
1146 rType = copyLinkChain(type2);
1148 if (getSize (type1) > getSize(type2) )
1149 rType = copyLinkChain(type1);
1151 rType = copyLinkChain(type2);
1153 reType = getSpec(rType);
1155 /* if either of them unsigned then make this unsigned */
1156 if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType))
1157 SPEC_USIGN(reType) = 1;
1159 /* if result is a literal then make not so */
1160 if (IS_LITERAL(reType))
1161 SPEC_SCLS(reType) = S_REGISTER ;
1166 /*------------------------------------------------------------------*/
1167 /* checkType - will do type check return 1 if match */
1168 /*------------------------------------------------------------------*/
1169 int checkType ( link *dest, link *src )
1180 /* if dest is a declarator then */
1181 if (IS_DECL(dest)) {
1183 if (DCL_TYPE(src) == DCL_TYPE(dest))
1184 return checkType(dest->next,src->next);
1186 if (IS_PTR(src) && IS_PTR(dest))
1189 if (IS_PTR(dest) && IS_ARRAY(src))
1192 if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src))
1193 return -1 * checkType (dest->next,src) ;
1198 if (IS_PTR(dest) && IS_INTEGRAL(src))
1204 /* if one of them is a void then ok */
1205 if (SPEC_NOUN(dest) == V_VOID &&
1206 SPEC_NOUN(src) != V_VOID )
1209 if (SPEC_NOUN(dest) != V_VOID &&
1210 SPEC_NOUN(src) == V_VOID )
1213 /* char === to short */
1214 if (SPEC_NOUN(dest) == V_CHAR &&
1215 SPEC_NOUN(src) == V_INT &&
1217 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1219 if (SPEC_NOUN(src) == V_CHAR &&
1220 SPEC_NOUN(dest) == V_INT &&
1222 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1224 /* if they are both bitfields then if the lengths
1225 and starts don't match */
1226 if (IS_BITFIELD(dest) && IS_BITFIELD(src) &&
1227 (SPEC_BLEN(dest) != SPEC_BLEN(src) ||
1228 SPEC_BSTR(dest) != SPEC_BSTR(src)))
1231 /* it is a specifier */
1232 if (SPEC_NOUN(dest) != SPEC_NOUN(src)) {
1233 if (SPEC_USIGN(dest) == SPEC_USIGN(src) &&
1234 IS_INTEGRAL(dest) && IS_INTEGRAL(src) &&
1235 getSize(dest) == getSize(src))
1238 if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src))
1244 if (IS_STRUCT(dest)) {
1245 if (SPEC_STRUCT(dest) != SPEC_STRUCT(src))
1250 if (SPEC_LONG(dest) != SPEC_LONG(src))
1253 if (SPEC_SHORT(dest) != SPEC_SHORT(src))
1256 if (SPEC_USIGN(dest) != SPEC_USIGN(src))
1262 /*------------------------------------------------------------------*/
1263 /* inCalleeSaveList - return 1 if found in calle save list */
1264 /*------------------------------------------------------------------*/
1265 bool inCalleeSaveList ( char *s)
1269 for (i = 0 ; options.calleeSaves[i] ; i++ )
1270 if (strcmp(options.calleeSaves[i],s) == 0)
1276 /*------------------------------------------------------------------*/
1277 /* checkFunction - does all kinds of check on a function */
1278 /*------------------------------------------------------------------*/
1279 int checkFunction (symbol *sym)
1282 value *exargs, *acargs ;
1285 /* if not type then some kind of error */
1289 /* if the function has no type then make it return int */
1290 if ( !sym->type->next )
1291 sym->type->next = sym->etype = newIntLink();
1293 /* function cannot return aggregate */
1294 if (IS_AGGREGATE(sym->type->next)) {
1295 werror(E_FUNC_AGGR,sym->name);
1299 /* function cannot return bit */
1300 if (IS_BITVAR(sym->type->next)) {
1301 werror(E_FUNC_BIT,sym->name);
1305 /* check if this function is defined as calleeSaves
1306 then mark it as such */
1307 sym->calleeSave = inCalleeSaveList(sym->name);
1309 /* if interrupt service routine */
1310 /* then it cannot have arguments */
1311 if ( sym->args && IS_ISR(sym->etype) && !IS_VOID(sym->args->type)) {
1312 werror(E_INT_ARGS,sym->name);
1316 if (!(csym = findSym (SymbolTab, sym, sym->name )))
1317 return 1 ; /* not defined nothing more to check */
1319 /* check if body already present */
1320 if ( csym && csym->fbody ) {
1321 werror(E_FUNC_BODY,sym->name);
1325 /* check the return value type */
1326 if (checkType (csym->type,sym->type) <= 0) {
1327 werror(E_PREV_DEF_CONFLICT,csym->name,"type") ;
1328 werror (E_CONTINUE,"previous defintion type ");
1329 printTypeChain(csym->type,stderr);fprintf(stderr,"\n");
1330 werror (E_CONTINUE,"current definition type ");
1331 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1335 if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) {
1336 werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt");
1340 if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) {
1341 werror (E_PREV_DEF_CONFLICT,csym->name,"using");
1345 /* compare expected agrs with actual args */
1346 exargs = csym->args ;
1347 acargs = sym->args ;
1349 /* for all the expected args do */
1352 exargs = exargs->next, acargs = acargs->next, argCnt++ ) {
1353 if ( checkType(exargs->type,acargs->type) <= 0) {
1354 werror(E_ARG_TYPE,argCnt);
1359 /* if one them ended we have a problem */
1360 if ((exargs && !acargs && !IS_VOID(exargs->type)) ||
1361 (!exargs && acargs && !IS_VOID(acargs->type)))
1362 werror(E_ARG_COUNT);
1364 /* replace with this defition */
1365 sym->cdef = csym->cdef;
1366 deleteSym (SymbolTab,csym,csym->name);
1367 addSym (SymbolTab,sym,sym->name,sym->level,sym->block);
1368 if (IS_EXTERN(csym->etype) && !
1369 IS_EXTERN(sym->etype))
1370 addSet(&publics,sym);
1374 /*-----------------------------------------------------------------*/
1375 /* processFuncArgs - does some processing with function args */
1376 /*-----------------------------------------------------------------*/
1377 void processFuncArgs (symbol *func, int ignoreName)
1383 /* if this function has variable argument list */
1384 /* then make the function a reentrant one */
1386 SPEC_RENT(func->etype) = 1;
1388 /* check if this function is defined as calleeSaves
1389 then mark it as such */
1390 func->calleeSave = inCalleeSaveList(func->name);
1392 val = func->args; /* loop thru all the arguments */
1394 /* if it is void then remove parameters */
1395 if (val && IS_VOID(val->type)) {
1400 /* reset regparm for the port */
1401 (*port->reset_regparms)();
1402 /* if any of the arguments is an aggregate */
1403 /* change it to pointer to the same type */
1406 /* mark it as a register parameter if
1407 the function does not have VA_ARG
1408 and as port dictates
1409 not inhibited by command line option or #pragma */
1410 if (!func->hasVargs &&
1411 !options.noregparms &&
1412 (*port->reg_parm)(val->type)) {
1414 SPEC_REGPARM(val->etype) = 1;
1417 if ( IS_AGGREGATE(val->type)) {
1418 /* if this is a structure */
1419 /* then we need to add a new link */
1420 if (IS_STRUCT(val->type)) {
1421 /* first lets add DECLARATOR type */
1422 link *p = val->type ;
1424 werror(W_STRUCT_AS_ARG,val->name);
1425 val->type = newLink();
1426 val->type->next = p ;
1429 /* change to a pointer depending on the */
1430 /* storage class specified */
1431 switch (SPEC_SCLS(val->etype)) {
1433 DCL_TYPE(val->type) = IPOINTER;
1436 DCL_TYPE(val->type) = PPOINTER;
1442 DCL_TYPE(val->type) = POINTER ;
1445 DCL_TYPE(val->type) = CPOINTER;
1448 DCL_TYPE(val->type) = FPOINTER;
1451 DCL_TYPE(val->type) = EEPPOINTER;
1454 DCL_TYPE(val->type) = GPOINTER;
1457 /* is there is a symbol associated then */
1458 /* change the type of the symbol as well*/
1460 val->sym->type = copyLinkChain(val->type);
1461 val->sym->etype = getSpec(val->sym->type);
1469 /* if this function is reentrant or */
1470 /* automatics r 2b stacked then nothing */
1471 if (IS_RENT(func->etype) || options.stackAuto )
1478 /* if a symbolname is not given */
1479 /* synthesize a variable name */
1482 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1483 val->sym = newSymbol(val->name,1);
1484 SPEC_OCLS(val->etype) = (options.model ? xdata : data);
1485 val->sym->type = copyLinkChain (val->type);
1486 val->sym->etype = getSpec (val->sym->type);
1487 val->sym->_isparm = 1;
1488 strcpy (val->sym->rname,val->name);
1489 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1490 SPEC_STAT(func->etype);
1491 addSymChain(val->sym);
1494 else /* symbol name given create synth name */ {
1496 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1497 strcpy (val->sym->rname,val->name);
1498 val->sym->_isparm = 1;
1499 SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) =
1500 (options.model ? xdata : data);
1501 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1502 SPEC_STAT(func->etype);
1508 /*-----------------------------------------------------------------*/
1509 /* isSymbolEqual - compares two symbols return 1 if they match */
1510 /*-----------------------------------------------------------------*/
1511 int isSymbolEqual (symbol *dest, symbol *src)
1513 /* if pointers match then equal */
1517 /* if one of them is null then don't match */
1521 /* if both of them have rname match on rname */
1522 if (dest->rname[0] && src->rname[0])
1523 return (!strcmp(dest->rname,src->rname));
1525 /* otherwise match on name */
1526 return (!strcmp(dest->name,src->name));
1529 /*-----------------------------------------------------------------*/
1530 /* printTypeChain - prints the type chain in human readable form */
1531 /*-----------------------------------------------------------------*/
1532 void printTypeChain (link *type, FILE *of)
1542 if (IS_DECL(type)) {
1543 switch (DCL_TYPE(type)) {
1545 fprintf (of,"function ");
1548 fprintf (of,"_generic * ");
1549 if (DCL_PTR_CONST(type))
1550 fprintf(of,"const ");
1553 fprintf (of,"_code * ");
1554 if (DCL_PTR_CONST(type))
1555 fprintf(of,"const ");
1558 fprintf (of,"_far * ");
1559 if (DCL_PTR_CONST(type))
1560 fprintf(of,"const ");
1563 fprintf (of,"_eeprom * ");
1564 if (DCL_PTR_CONST(type))
1565 fprintf(of,"const ");
1569 fprintf (of,"_near * ");
1570 if (DCL_PTR_CONST(type))
1571 fprintf(of,"const ");
1574 fprintf (of,"_idata *");
1575 if (DCL_PTR_CONST(type))
1576 fprintf(of,"const ");
1579 fprintf (of,"_pdata *");
1580 if (DCL_PTR_CONST(type))
1581 fprintf(of,"const ");
1584 fprintf (of," _unkown *");
1585 if (DCL_PTR_CONST(type))
1586 fprintf(of,"const ");
1590 fprintf (of,"array of ");
1594 if (SPEC_VOLATILE(type))
1595 fprintf (of,"volatile ");
1596 if (SPEC_USIGN(type))
1597 fprintf (of,"unsigned ");
1599 switch (SPEC_NOUN(type)) {
1602 fprintf (of,"long ");
1605 fprintf (of,"short ");
1607 fprintf (of,"int ");
1611 fprintf(of,"char ");
1615 fprintf(of,"void ");
1619 fprintf(of,"float ");
1623 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1627 fprintf(of,"sbit ");
1631 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1644 /*-----------------------------------------------------------------*/
1645 /* cdbTypeInfo - print the type information for debugger */
1646 /*-----------------------------------------------------------------*/
1647 void cdbTypeInfo (link *type,FILE *of)
1649 fprintf(of,"{%d}",getSize(type));
1651 if (IS_DECL(type)) {
1652 switch (DCL_TYPE(type)) {
1678 fprintf (of,"DA%d,",DCL_ELEM(type));
1684 switch (SPEC_NOUN(type)) {
1708 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1716 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1723 if (SPEC_USIGN(type))
1731 /*-----------------------------------------------------------------*/
1732 /* cdbSymbol - prints a symbol & its type information for debugger */
1733 /*-----------------------------------------------------------------*/
1734 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1746 fprintf(of,"S:"); /* symbol record */
1747 /* if this is not a structure symbol then
1748 we need to figure out the scope information */
1752 if (IS_STATIC(sym->etype))
1753 fprintf(of,"F%s$",moduleName); /* scope is file */
1755 fprintf(of,"G$"); /* scope is global */
1758 /* symbol is local */
1759 fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1761 fprintf(of,"S$"); /* scope is structure */
1763 /* print the name, & mangled name */
1764 fprintf(of,"%s$%d$%d(",sym->name,
1765 sym->level,sym->block);
1767 cdbTypeInfo(sym->type,of);
1770 /* print the address space */
1771 map = SPEC_OCLS(sym->etype);
1772 fprintf(of,"%c,%d,%d",
1773 (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1775 /* if assigned to registers then output register names */
1776 /* if this is a function then print
1777 if is it an interrupt routine & interrupt number
1778 and the register bank it is using */
1780 fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1781 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1782 /* alternate location to find this symbol @ : eg registers
1789 /*-----------------------------------------------------------------*/
1790 /* cdbStruct - print a structure for debugger */
1791 /*-----------------------------------------------------------------*/
1792 void cdbStruct ( structdef *sdef,int block,FILE *of,
1793 int inStruct, char *tag)
1798 /* if block # then must have function scope */
1799 fprintf(of,"F%s$",moduleName);
1800 fprintf(of,"%s[",(tag ? tag : sdef->tag));
1801 for (sym=sdef->fields ; sym ; sym = sym->next) {
1802 fprintf(of,"({%d}",sym->offset);
1803 cdbSymbol(sym,of,TRUE,FALSE);
1811 /*------------------------------------------------------------------*/
1812 /* cdbStructBlock - calls struct printing for a blcks */
1813 /*------------------------------------------------------------------*/
1814 void cdbStructBlock (int block , FILE *of)
1817 bucket **table = StructTab;
1820 /* go thru the entire table */
1821 for ( i = 0 ; i < 256; i++ ) {
1822 for ( chain = table[i]; chain ; chain = chain->next ) {
1823 if (chain->block >= block) {
1824 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1830 /*-----------------------------------------------------------------*/
1831 /* powof2 - returns power of two for the number if number is pow 2 */
1832 /*-----------------------------------------------------------------*/
1833 int powof2 (unsigned long num)
1839 if (num & 1) n1s++ ;
1844 if (n1s > 1 || nshifts == 0) return 0;
1845 return nshifts - 1 ;
1859 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
1860 symbol *__muldiv[3][3][2];
1861 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
1862 link *__multypes[3][2];
1863 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
1864 symbol *__conv[2][3][2];
1868 /*-----------------------------------------------------------------*/
1869 /* initCSupport - create functions for C support routines */
1870 /*-----------------------------------------------------------------*/
1871 void initCSupport ()
1873 const char *smuldivmod[] = {
1876 const char *sbwd[] = {
1877 "char", "int", "long"
1879 const char *ssu[] = {
1883 int bwd, su, muldivmod, tofrom;
1885 floatType= newFloatLink();
1887 for (bwd = 0; bwd < 3; bwd++) {
1902 __multypes[bwd][0] = l;
1903 __multypes[bwd][1] = copyLinkChain(l);
1904 SPEC_USIGN(__multypes[bwd][1]) = 1;
1907 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1908 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1909 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1910 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1911 __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
1912 __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
1913 __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
1914 __fslteq= funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
1915 __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
1916 __fsgteq= funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
1918 for (tofrom = 0; tofrom < 2; tofrom++) {
1919 for (bwd = 0; bwd < 3; bwd++) {
1920 for (su = 0; su < 2; su++) {
1922 sprintf(buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
1923 __conv[tofrom][bwd][su] = funcOfType(buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
1926 sprintf(buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
1927 __conv[tofrom][bwd][su] = funcOfType(buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
1933 for (muldivmod = 0; muldivmod < 3; muldivmod++) {
1934 for (bwd = 0; bwd < 3; bwd++) {
1935 for (su = 0; su < 2; su++) {
1936 sprintf(buffer, "_%s%s%s",
1937 smuldivmod[muldivmod],
1940 __muldiv[muldivmod][bwd][su] = funcOfType(buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);