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) = FLPOINTER;
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)
1382 /* if this function has variable argument list */
1383 /* then make the function a reentrant one */
1385 SPEC_RENT(func->etype) = 1;
1387 /* check if this function is defined as calleeSaves
1388 then mark it as such */
1389 func->calleeSave = inCalleeSaveList(func->name);
1391 val = func->args; /* loop thru all the arguments */
1393 /* if it is void then remove parameters */
1394 if (val && IS_VOID(val->type)) {
1399 /* if any of the arguments is an aggregate */
1400 /* change it to pointer to the same type */
1403 /* mark it as a register parameter if
1404 the function does nit have VA_ARG
1405 and MAX_REG_PARMS not exceeded &&
1406 not inhibited by command line option or #pragma */
1407 if (pNum <= MAX_REG_PARMS &&
1408 !options.noregparms &&
1410 SPEC_REGPARM(val->etype) = 1;
1412 if ( IS_AGGREGATE(val->type)) {
1413 /* if this is a structure */
1414 /* then we need to add a new link */
1415 if (IS_STRUCT(val->type)) {
1416 /* first lets add DECLARATOR type */
1417 link *p = val->type ;
1419 werror(W_STRUCT_AS_ARG,val->name);
1420 val->type = newLink();
1421 val->type->next = p ;
1424 /* change to a pointer depending on the */
1425 /* storage class specified */
1426 switch (SPEC_SCLS(val->etype)) {
1428 DCL_TYPE(val->type) = IPOINTER;
1431 DCL_TYPE(val->type) = PPOINTER;
1437 DCL_TYPE(val->type) = POINTER ;
1440 DCL_TYPE(val->type) = CPOINTER;
1443 DCL_TYPE(val->type) = FPOINTER;
1446 DCL_TYPE(val->type) = FLPOINTER;
1449 DCL_TYPE(val->type) = GPOINTER;
1452 /* is there is a symbol associated then */
1453 /* change the type of the symbol as well*/
1455 val->sym->type = copyLinkChain(val->type);
1456 val->sym->etype = getSpec(val->sym->type);
1464 /* if this function is reentrant or */
1465 /* automatics r 2b stacked then nothing */
1466 if (IS_RENT(func->etype) || options.stackAuto )
1473 /* if a symbolname is not given */
1474 /* synthesize a variable name */
1477 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1478 val->sym = newSymbol(val->name,1);
1479 SPEC_OCLS(val->etype) = (options.model ? xdata : data);
1480 val->sym->type = copyLinkChain (val->type);
1481 val->sym->etype = getSpec (val->sym->type);
1482 val->sym->_isparm = 1;
1483 strcpy (val->sym->rname,val->name);
1484 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1485 SPEC_STAT(func->etype);
1486 addSymChain(val->sym);
1489 else /* symbol name given create synth name */ {
1491 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1492 strcpy (val->sym->rname,val->name);
1493 val->sym->_isparm = 1;
1494 SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) =
1495 (options.model ? xdata : data);
1496 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1497 SPEC_STAT(func->etype);
1503 /*-----------------------------------------------------------------*/
1504 /* isSymbolEqual - compares two symbols return 1 if they match */
1505 /*-----------------------------------------------------------------*/
1506 int isSymbolEqual (symbol *dest, symbol *src)
1508 /* if pointers match then equal */
1512 /* if one of them is null then don't match */
1516 /* if both of them have rname match on rname */
1517 if (dest->rname[0] && src->rname[0])
1518 return (!strcmp(dest->rname,src->rname));
1520 /* otherwise match on name */
1521 return (!strcmp(dest->name,src->name));
1524 /*-----------------------------------------------------------------*/
1525 /* printTypeChain - prints the type chain in human readable form */
1526 /*-----------------------------------------------------------------*/
1527 void printTypeChain (link *type, FILE *of)
1537 if (IS_DECL(type)) {
1538 switch (DCL_TYPE(type)) {
1540 fprintf (of,"function ");
1543 fprintf (of,"_generic * ");
1544 if (DCL_PTR_CONST(type))
1545 fprintf(of,"const ");
1548 fprintf (of,"_code * ");
1549 if (DCL_PTR_CONST(type))
1550 fprintf(of,"const ");
1553 fprintf (of,"_far * ");
1554 if (DCL_PTR_CONST(type))
1555 fprintf(of,"const ");
1558 fprintf (of,"_flash * ");
1559 if (DCL_PTR_CONST(type))
1560 fprintf(of,"const ");
1564 fprintf (of,"_near * ");
1565 if (DCL_PTR_CONST(type))
1566 fprintf(of,"const ");
1569 fprintf (of,"_idata *");
1570 if (DCL_PTR_CONST(type))
1571 fprintf(of,"const ");
1574 fprintf (of,"_pdata *");
1575 if (DCL_PTR_CONST(type))
1576 fprintf(of,"const ");
1579 fprintf (of," _unkown *");
1580 if (DCL_PTR_CONST(type))
1581 fprintf(of,"const ");
1585 fprintf (of,"array of ");
1589 if (SPEC_VOLATILE(type))
1590 fprintf (of,"volatile ");
1591 if (SPEC_USIGN(type))
1592 fprintf (of,"unsigned ");
1594 switch (SPEC_NOUN(type)) {
1597 fprintf (of,"long ");
1600 fprintf (of,"short ");
1602 fprintf (of,"int ");
1606 fprintf(of,"char ");
1610 fprintf(of,"void ");
1614 fprintf(of,"float ");
1618 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1622 fprintf(of,"sbit ");
1626 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1636 /*-----------------------------------------------------------------*/
1637 /* cdbTypeInfo - print the type information for debugger */
1638 /*-----------------------------------------------------------------*/
1639 void cdbTypeInfo (link *type,FILE *of)
1641 fprintf(of,"{%d}",getSize(type));
1643 if (IS_DECL(type)) {
1644 switch (DCL_TYPE(type)) {
1670 fprintf (of,"DA%d,",DCL_ELEM(type));
1674 switch (SPEC_NOUN(type)) {
1698 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1706 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1710 if (SPEC_USIGN(type))
1718 /*-----------------------------------------------------------------*/
1719 /* cdbSymbol - prints a symbol & its type information for debugger */
1720 /*-----------------------------------------------------------------*/
1721 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1733 fprintf(of,"S:"); /* symbol record */
1734 /* if this is not a structure symbol then
1735 we need to figure out the scope information */
1739 if (IS_STATIC(sym->etype))
1740 fprintf(of,"F%s$",moduleName); /* scope is file */
1742 fprintf(of,"G$"); /* scope is global */
1745 /* symbol is local */
1746 fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1748 fprintf(of,"S$"); /* scope is structure */
1750 /* print the name, & mangled name */
1751 fprintf(of,"%s$%d$%d(",sym->name,
1752 sym->level,sym->block);
1754 cdbTypeInfo(sym->type,of);
1757 /* print the address space */
1758 map = SPEC_OCLS(sym->etype);
1759 fprintf(of,"%c,%d,%d",
1760 (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1762 /* if assigned to registers then output register names */
1763 /* if this is a function then print
1764 if is it an interrupt routine & interrupt number
1765 and the register bank it is using */
1767 fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1768 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1769 /* alternate location to find this symbol @ : eg registers
1776 /*-----------------------------------------------------------------*/
1777 /* cdbStruct - print a structure for debugger */
1778 /*-----------------------------------------------------------------*/
1779 void cdbStruct ( structdef *sdef,int block,FILE *of,
1780 int inStruct, char *tag)
1785 /* if block # then must have function scope */
1786 fprintf(of,"F%s$",moduleName);
1787 fprintf(of,"%s[",(tag ? tag : sdef->tag));
1788 for (sym=sdef->fields ; sym ; sym = sym->next) {
1789 fprintf(of,"({%d}",sym->offset);
1790 cdbSymbol(sym,of,TRUE,FALSE);
1798 /*------------------------------------------------------------------*/
1799 /* cdbStructBlock - calls struct printing for a blcks */
1800 /*------------------------------------------------------------------*/
1801 void cdbStructBlock (int block , FILE *of)
1804 bucket **table = StructTab;
1807 /* go thru the entire table */
1808 for ( i = 0 ; i < 256; i++ ) {
1809 for ( chain = table[i]; chain ; chain = chain->next ) {
1810 if (chain->block >= block) {
1811 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1817 /*-----------------------------------------------------------------*/
1818 /* powof2 - returns power of two for the number if number is pow 2 */
1819 /*-----------------------------------------------------------------*/
1820 int powof2 (unsigned long num)
1826 if (num & 1) n1s++ ;
1831 if (n1s > 1 || nshifts == 0) return 0;
1832 return nshifts - 1 ;
1846 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
1847 symbol *__muldiv[3][3][2];
1848 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
1849 link *__multypes[3][2];
1850 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
1851 symbol *__conv[2][3][2];
1855 /*-----------------------------------------------------------------*/
1856 /* initCSupport - create functions for C support routines */
1857 /*-----------------------------------------------------------------*/
1858 void initCSupport ()
1860 const char *smuldivmod[] = {
1863 const char *sbwd[] = {
1864 "char", "int", "long"
1866 const char *ssu[] = {
1870 int bwd, su, muldivmod, tofrom;
1872 floatType= newFloatLink();
1874 for (bwd = 0; bwd < 3; bwd++) {
1889 __multypes[bwd][0] = l;
1890 __multypes[bwd][1] = copyLinkChain(l);
1891 SPEC_USIGN(__multypes[bwd][1]) = 1;
1894 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1895 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1896 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1897 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1898 __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
1899 __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
1900 __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
1901 __fslteq= funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
1902 __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
1903 __fsgteq= funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
1905 for (tofrom = 0; tofrom < 2; tofrom++) {
1906 for (bwd = 0; bwd < 3; bwd++) {
1907 for (su = 0; su < 2; su++) {
1909 sprintf(buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
1910 __conv[tofrom][bwd][su] = funcOfType(buffer, __multypes[bwd][su], floatType, 2, options.float_rent);
1913 sprintf(buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
1914 __conv[tofrom][bwd][su] = funcOfType(buffer, floatType, __multypes[bwd][su], 2, options.float_rent);
1920 for (muldivmod = 0; muldivmod < 3; muldivmod++) {
1921 for (bwd = 0; bwd < 3; bwd++) {
1922 for (su = 0; su < 2; su++) {
1923 sprintf(buffer, "_%s%s%s",
1924 smuldivmod[muldivmod],
1927 __muldiv[muldivmod][bwd][su] = funcOfType(buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);