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 */
536 if ( IS_SPEC(p) ) { /* if this is the specifier then */
538 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
540 return (IS_LONG(p) ? LONGSIZE : ( IS_SHORT(p) ? SHORTSIZE: INTSIZE)) ;
548 return SPEC_STRUCT(p)->size ;
554 return ((SPEC_BLEN(p) / 8) + (SPEC_BLEN(p) % 8 ? 1 : 0)) ;
560 /* this is a specifier */
561 switch (DCL_TYPE(p)) {
565 return DCL_ELEM(p) * getSize (p->next) ;
582 /*------------------------------------------------------------------*/
583 /* bitsForType - returns # of bits required to store this type */
584 /*------------------------------------------------------------------*/
585 unsigned int bitsForType ( link *p )
587 /* if nothing return 0 */
591 if ( IS_SPEC(p) ) { /* if this is the specifier then */
593 switch (SPEC_NOUN(p)) { /* depending on the specifier type */
595 return (IS_LONG(p) ? LONGSIZE*8 : ( IS_SHORT(p) ? SHORTSIZE*8: INTSIZE*8)) ;
603 return SPEC_STRUCT(p)->size*8 ;
615 /* this is a specifier */
616 switch (DCL_TYPE(p)) {
620 return DCL_ELEM(p) * getSize (p->next) *8 ;
624 return ( PTRSIZE * 8) ;
628 return ( FPTRSIZE * 8);
630 return ( GPTRSIZE * 8);
637 /*------------------------------------------------------------------*/
638 /* copySymbolChain - copies a symbol chain */
639 /*------------------------------------------------------------------*/
640 symbol *copySymbolChain (symbol *src)
647 dest = copySymbol(src);
648 dest->next = copySymbolChain(src->next);
652 /*------------------------------------------------------------------*/
653 /* copySymbol - makes a copy of a symbol */
654 /*------------------------------------------------------------------*/
655 symbol *copySymbol (symbol *src)
662 dest = newSymbol( src->name, src->level );
663 memcpy(dest,src,sizeof(symbol));
664 dest->level = src->level ;
665 dest->block = src->block ;
666 dest->ival = copyIlist(src->ival);
667 dest->type = copyLinkChain(src->type);
668 dest->etype= getSpec(dest->type);
670 dest->args = copyValueChain (src->args);
671 dest->key = src->key;
672 dest->calleeSave = src->calleeSave;
673 dest->allocreq = src->allocreq;
677 /*------------------------------------------------------------------*/
678 /* reverseSyms - reverses the links for a symbol chain */
679 /*------------------------------------------------------------------*/
680 symbol *reverseSyms ( symbol *sym)
682 symbol *prev , *curr, *next ;
697 sym->next = (void *) NULL ;
701 /*------------------------------------------------------------------*/
702 /* reverseLink - reverses the links for a type chain */
703 /*------------------------------------------------------------------*/
704 link *reverseLink ( link *type)
706 link *prev , *curr, *next ;
721 type->next = (void *) NULL ;
725 /*------------------------------------------------------------------*/
726 /* addSymChain - adds a symbol chain to the symboltable */
727 /*------------------------------------------------------------------*/
728 void addSymChain ( symbol *symHead )
730 symbol *sym = symHead ;
731 symbol *csym = NULL ;
733 for (;sym != NULL ; sym = sym->next ) {
735 /* if already exists in the symbol table then check if
736 the previous was an extern definition if yes then
737 then check if the type match, if the types match then
738 delete the current entry and add the new entry */
739 if ((csym = findSymWithLevel (SymbolTab,sym)) &&
740 csym->level == sym->level) {
742 /* previous definition extern ? */
743 if ( IS_EXTERN(csym->etype) ) {
744 /* do types match ? */
745 if (checkType ( csym->type,sym->type) != 1)
747 werror (E_DUPLICATE,csym->name);
749 /* delete current entry */
750 deleteSym (SymbolTab, csym, csym->name );
752 addSym (SymbolTab, sym, sym->name, sym->level,sym->block);
753 } else /* not extern */
754 werror(E_DUPLICATE,sym->name) ;
758 /* check if previously defined */
759 if (csym && csym->level == sym->level ) {
760 /* if the previous one was declared as extern */
761 /* then check the type with the current one */
762 if ( IS_EXTERN(csym->etype) ) {
763 if ( checkType (csym->type, sym->type ) <= 0 )
764 werror (W_EXTERN_MISMATCH,csym->name);
768 addSym (SymbolTab,sym,sym->name,sym->level,sym->block) ;
773 /*------------------------------------------------------------------*/
774 /* funcInChain - DCL Type 'FUNCTION' found in type chain */
775 /*------------------------------------------------------------------*/
776 int funcInChain (link *lnk)
786 /*------------------------------------------------------------------*/
787 /* structElemType - returns the type info of a sturct member */
788 /*------------------------------------------------------------------*/
789 link *structElemType (link *stype, value *id ,value **argsp)
791 symbol *fields = (SPEC_STRUCT(stype) ? SPEC_STRUCT(stype)->fields : NULL);
793 if ( ! fields || ! id)
796 /* look for the id */
798 if (strcmp(fields->rname,id->name) == 0) {
800 *argsp = fields->args;
802 return copyLinkChain (fields->type) ;
804 fields = fields->next ;
806 werror(E_NOT_MEMBER,id->name);
811 /*------------------------------------------------------------------*/
812 /* getStructElement - returns element of a tructure definition */
813 /*------------------------------------------------------------------*/
814 symbol *getStructElement ( structdef *sdef, symbol *sym)
818 for ( field = sdef->fields ; field ; field = field->next )
819 if ( strcmp(field->name,sym->name) == 0)
822 werror(E_NOT_MEMBER,sym->name);
824 return sdef->fields ;
827 /*------------------------------------------------------------------*/
828 /* compStructSize - computes the size of a structure */
829 /*------------------------------------------------------------------*/
830 int compStructSize (int su, structdef *sdef )
832 int sum = 0 , usum =0;
836 /* for the identifiers */
837 loop = sdef->fields ;
840 /* create the internal name for this variable */
841 sprintf (loop->rname,"_%s",loop->name);
842 loop->offset = ( su == UNION ? sum = 0 : sum ) ;
843 SPEC_VOLATILE(loop->etype) |= (su == UNION ? 1 : 0);
845 /* if this is a bit field */
848 /* change it to a unsigned bit */
849 SPEC_NOUN(loop->etype) = V_BIT ;
850 SPEC_USIGN(loop->etype) = 1 ;
851 /* check if this fit into the remaining */
852 /* bits of this byte else align it to the */
853 /* next byte boundary */
854 if ((SPEC_BLEN(loop->etype)=loop->bitVar) <= (8 - bitOffset)) {
855 SPEC_BSTR(loop->etype) = bitOffset ;
856 sum += (loop->bitVar / 8) ;
857 bitOffset += (loop->bitVar % 8);
859 else /* does not fit */
862 loop->offset++; /* go to the next byte */
864 SPEC_BSTR(loop->etype) = bitOffset ;
865 sum += (loop->bitVar / 8) ;
866 bitOffset += (loop->bitVar % 8);
868 /* if this is the last field then pad */
869 if (!loop->next && bitOffset) {
876 sum += getSize (loop->type) ;
879 /* if function then do the arguments for it */
880 if (funcInChain(loop->type)) {
881 processFuncArgs (loop, 1);
886 /* if this is not a bitfield but the */
887 /* previous one was and did not take */
888 /* the whole byte then pad the rest */
889 if ((loop && !loop->bitVar) && bitOffset) {
894 /* if union then size = sizeof larget field */
896 usum = max(usum,sum);
900 return (su == UNION ? usum : sum);
903 /*------------------------------------------------------------------*/
904 /* checkSClass - check the storage class specification */
905 /*------------------------------------------------------------------*/
906 static void checkSClass ( symbol *sym )
908 /* type is literal can happen foe enums change
910 if (SPEC_SCLS(sym->etype) == S_LITERAL && !SPEC_ENUM(sym->etype))
911 SPEC_SCLS(sym->etype) = S_AUTO;
913 /* if sfr or sbit then must also be */
914 /* volatile the initial value will be xlated */
915 /* to an absolute address */
916 if (SPEC_SCLS(sym->etype) == S_SBIT ||
917 SPEC_SCLS(sym->etype) == S_SFR ) {
918 SPEC_VOLATILE(sym->etype) = 1;
919 /* if initial value given */
921 SPEC_ABSA(sym->etype) = 1;
922 SPEC_ADDR(sym->etype) =
923 (int) list2int(sym->ival);
928 /* if absolute address given then it mark it as
930 if (IS_ABSOLUTE(sym->etype))
931 SPEC_VOLATILE(sym->etype) = 1;
933 /* global variables declared const put into code */
934 if (sym->level == 0 &&
935 SPEC_SCLS(sym->etype) == S_CONSTANT)
936 SPEC_SCLS(sym->etype) = S_CODE ;
939 /* global variable in code space is a constant */
940 if (sym->level == 0 &&
941 SPEC_SCLS(sym->etype) == S_CODE)
942 SPEC_CONST(sym->etype) = 1;
945 /* if bit variable then no storage class can be */
946 /* specified since bit is already a storage */
947 if ( IS_BITVAR(sym->etype) &&
948 ( SPEC_SCLS(sym->etype) != S_FIXED &&
949 SPEC_SCLS(sym->etype) != S_SBIT &&
950 SPEC_SCLS(sym->etype) != S_BIT )
952 werror (E_BITVAR_STORAGE,sym->name);
953 SPEC_SCLS(sym->etype) = S_FIXED ;
956 /* extern variables cannot be initialized */
957 if (IS_EXTERN(sym->etype) && sym->ival) {
958 werror(E_EXTERN_INIT,sym->name);
962 /* if this is an automatic symbol then */
963 /* storage class will be ignored and */
964 /* symbol will be allocated on stack/ */
965 /* data depending on flag */
967 (options.stackAuto || reentrant ) &&
968 ( SPEC_SCLS(sym->etype) != S_AUTO &&
969 SPEC_SCLS(sym->etype) != S_FIXED &&
970 SPEC_SCLS(sym->etype) != S_REGISTER &&
971 SPEC_SCLS(sym->etype) != S_STACK &&
972 SPEC_SCLS(sym->etype) != S_XSTACK &&
973 SPEC_SCLS(sym->etype) != S_CONSTANT )) {
975 werror(E_AUTO_ASSUMED,sym->name) ;
976 SPEC_SCLS(sym->etype) = S_AUTO ;
979 /* automatic symbols cannot be given */
980 /* an absolute address ignore it */
982 SPEC_ABSA(sym->etype) &&
983 (options.stackAuto || reentrant) ) {
984 werror(E_AUTO_ABSA,sym->name);
985 SPEC_ABSA(sym->etype) = 0 ;
988 /* arrays & pointers cannot be defined for bits */
989 /* SBITS or SFRs or BIT */
990 if ((IS_ARRAY(sym->type) || IS_PTR(sym->type)) &&
991 ( SPEC_NOUN(sym->etype) == V_BIT ||
992 SPEC_NOUN(sym->etype) == V_SBIT ||
993 SPEC_SCLS(sym->etype) == S_SFR ))
994 werror(E_BIT_ARRAY,sym->name);
996 /* if this is a bit|sbit then set length & start */
997 if (SPEC_NOUN(sym->etype) == V_BIT ||
998 SPEC_NOUN(sym->etype) == V_SBIT ) {
999 SPEC_BLEN(sym->etype) = 1 ;
1000 SPEC_BSTR(sym->etype) = 0 ;
1003 /* variables declared in CODE space must have */
1004 /* initializers if not an extern */
1005 if (SPEC_SCLS(sym->etype) == S_CODE &&
1006 sym->ival == NULL &&
1008 !IS_EXTERN(sym->etype))
1009 werror(E_CODE_NO_INIT,sym->name);
1011 /* if parameter or local variable then change */
1012 /* the storage class to reflect where the var will go */
1013 if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) {
1014 if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype)))
1015 SPEC_SCLS(sym->etype) = (options.useXstack ?
1016 S_XSTACK : S_STACK ) ;
1018 SPEC_SCLS(sym->etype) = (options.useXstack ?
1023 /*------------------------------------------------------------------*/
1024 /* changePointer - change pointer to functions */
1025 /*------------------------------------------------------------------*/
1026 void changePointer (symbol *sym)
1030 /* go thru the chain of declarations */
1031 /* if we find a pointer to a function */
1032 /* unconditionally change it to a ptr */
1034 for ( p = sym->type ; p ; p = p->next) {
1035 if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER)
1036 DCL_TYPE(p) = GPOINTER ;
1037 if ( IS_PTR(p) && IS_FUNC(p->next))
1038 DCL_TYPE(p) = CPOINTER ;
1042 /*------------------------------------------------------------------*/
1043 /* checkDecl - does semantic validation of a declaration */
1044 /*------------------------------------------------------------------*/
1045 int checkDecl ( symbol *sym )
1048 checkSClass (sym); /* check the storage class */
1049 changePointer(sym); /* change pointers if required */
1051 /* if this is an array without any dimension
1052 then update the dimension from the initial value */
1053 if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type))
1054 DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival);
1059 /*------------------------------------------------------------------*/
1060 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1061 /*------------------------------------------------------------------*/
1062 link *copyLinkChain ( link *p)
1064 link *head, *curr , *loop;
1067 head = loop = ( curr ? newLink() : (void *) NULL) ;
1069 memcpy(loop,curr,sizeof(link)) ; /* copy it */
1070 loop->next = (curr->next ? newLink() : (void *) NULL) ;
1079 /*------------------------------------------------------------------*/
1080 /* cleanUpBlock - cleansup the symbol table specified for all the */
1081 /* symbols in the given block */
1082 /*------------------------------------------------------------------*/
1083 void cleanUpBlock ( bucket **table, int block)
1088 /* go thru the entire table */
1089 for ( i = 0 ; i < 256; i++ ) {
1090 for ( chain = table[i]; chain ; chain = chain->next ) {
1091 if (chain->block >= block) {
1092 deleteSym (table,chain->sym,chain->name);
1098 /*------------------------------------------------------------------*/
1099 /* cleanUpLevel - cleansup the symbol table specified for all the */
1100 /* symbols in the given level */
1101 /*------------------------------------------------------------------*/
1102 void cleanUpLevel (bucket **table, int level )
1107 /* go thru the entire table */
1108 for ( i = 0 ; i < 256; i++ ) {
1109 for ( chain = table[i]; chain ; chain = chain->next ) {
1110 if (chain->level >= level) {
1111 deleteSym (table,chain->sym,chain->name);
1117 /*------------------------------------------------------------------*/
1118 /* computeType - computes the resultant type from two types */
1119 /*------------------------------------------------------------------*/
1120 link *computeType ( link *type1, link *type2)
1124 link *etype1 = getSpec(type1);
1125 link *etype2 = getSpec(type2);
1127 /* if one of them is a float then result is a float */
1128 /* here we assume that the types passed are okay */
1129 /* and can be cast to one another */
1130 /* which ever is greater in size */
1131 if (IS_FLOAT(etype1) || IS_FLOAT(etype2))
1132 rType = newFloatLink();
1134 /* if only one of them is a bit variable
1135 then the other one prevails */
1136 if (IS_BITVAR(etype1) && !IS_BITVAR(etype2))
1137 rType = copyLinkChain(type2);
1139 if (IS_BITVAR(etype2) && !IS_BITVAR(etype1))
1140 rType = copyLinkChain(type1);
1142 /* if one of them is a pointer then that
1145 rType = copyLinkChain(type1);
1148 rType = copyLinkChain(type2);
1150 if (getSize (type1) > getSize(type2) )
1151 rType = copyLinkChain(type1);
1153 rType = copyLinkChain(type2);
1155 reType = getSpec(rType);
1157 /* if either of them unsigned then make this unsigned */
1158 if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType))
1159 SPEC_USIGN(reType) = 1;
1161 /* if result is a literal then make not so */
1162 if (IS_LITERAL(reType))
1163 SPEC_SCLS(reType) = S_REGISTER ;
1168 /*------------------------------------------------------------------*/
1169 /* checkType - will do type check return 1 if match */
1170 /*------------------------------------------------------------------*/
1171 int checkType ( link *dest, link *src )
1182 /* if dest is a declarator then */
1183 if (IS_DECL(dest)) {
1185 if (DCL_TYPE(src) == DCL_TYPE(dest))
1186 return checkType(dest->next,src->next);
1188 if (IS_PTR(src) && IS_PTR(dest))
1191 if (IS_PTR(dest) && IS_ARRAY(src))
1194 if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src))
1195 return -1 * checkType (dest->next,src) ;
1200 if (IS_PTR(dest) && IS_INTEGRAL(src))
1206 /* if one of them is a void then ok */
1207 if (SPEC_NOUN(dest) == V_VOID &&
1208 SPEC_NOUN(src) != V_VOID )
1211 if (SPEC_NOUN(dest) != V_VOID &&
1212 SPEC_NOUN(src) == V_VOID )
1215 /* char === to short */
1216 if (SPEC_NOUN(dest) == V_CHAR &&
1217 SPEC_NOUN(src) == V_INT &&
1219 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1221 if (SPEC_NOUN(src) == V_CHAR &&
1222 SPEC_NOUN(dest) == V_INT &&
1224 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1226 /* if they are both bitfields then if the lengths
1227 and starts don't match */
1228 if (IS_BITFIELD(dest) && IS_BITFIELD(src) &&
1229 (SPEC_BLEN(dest) != SPEC_BLEN(src) ||
1230 SPEC_BSTR(dest) != SPEC_BSTR(src)))
1233 /* it is a specifier */
1234 if (SPEC_NOUN(dest) != SPEC_NOUN(src)) {
1235 if (SPEC_USIGN(dest) == SPEC_USIGN(src) &&
1236 IS_INTEGRAL(dest) && IS_INTEGRAL(src) &&
1237 getSize(dest) == getSize(src))
1240 if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src))
1246 if (IS_STRUCT(dest)) {
1247 if (SPEC_STRUCT(dest) != SPEC_STRUCT(src))
1252 if (SPEC_LONG(dest) != SPEC_LONG(src))
1255 if (SPEC_SHORT(dest) != SPEC_SHORT(src))
1258 if (SPEC_USIGN(dest) != SPEC_USIGN(src))
1264 /*------------------------------------------------------------------*/
1265 /* inCalleeSaveList - return 1 if found in calle save list */
1266 /*------------------------------------------------------------------*/
1267 bool inCalleeSaveList ( char *s)
1271 for (i = 0 ; options.calleeSaves[i] ; i++ )
1272 if (strcmp(options.calleeSaves[i],s) == 0)
1278 /*------------------------------------------------------------------*/
1279 /* checkFunction - does all kinds of check on a function */
1280 /*------------------------------------------------------------------*/
1281 int checkFunction (symbol *sym)
1284 value *exargs, *acargs ;
1287 /* if not type then some kind of error */
1291 /* if the function has no type then make it return int */
1292 if ( !sym->type->next )
1293 sym->type->next = sym->etype = newIntLink();
1295 /* function cannot return aggregate */
1296 if (IS_AGGREGATE(sym->type->next)) {
1297 werror(E_FUNC_AGGR,sym->name);
1301 /* function cannot return bit */
1302 if (IS_BITVAR(sym->type->next)) {
1303 werror(E_FUNC_BIT,sym->name);
1307 /* check if this function is defined as calleeSaves
1308 then mark it as such */
1309 sym->calleeSave = inCalleeSaveList(sym->name);
1311 /* if interrupt service routine */
1312 /* then it cannot have arguments */
1313 if ( sym->args && IS_ISR(sym->etype) && !IS_VOID(sym->args->type)) {
1314 werror(E_INT_ARGS,sym->name);
1318 if (!(csym = findSym (SymbolTab, sym, sym->name )))
1319 return 1 ; /* not defined nothing more to check */
1321 /* check if body already present */
1322 if ( csym && csym->fbody ) {
1323 werror(E_FUNC_BODY,sym->name);
1327 /* check the return value type */
1328 if (checkType (csym->type,sym->type) <= 0) {
1329 werror(E_PREV_DEF_CONFLICT,csym->name,"type") ;
1330 werror (E_CONTINUE,"previous defintion type ");
1331 printTypeChain(csym->type,stderr);fprintf(stderr,"\n");
1332 werror (E_CONTINUE,"current definition type ");
1333 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1337 if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) {
1338 werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt");
1342 if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) {
1343 werror (E_PREV_DEF_CONFLICT,csym->name,"using");
1347 /* compare expected agrs with actual args */
1348 exargs = csym->args ;
1349 acargs = sym->args ;
1351 /* for all the expected args do */
1354 exargs = exargs->next, acargs = acargs->next, argCnt++ ) {
1355 if ( checkType(exargs->type,acargs->type) <= 0) {
1356 werror(E_ARG_TYPE,argCnt);
1361 /* if one them ended we have a problem */
1362 if ((exargs && !acargs && !IS_VOID(exargs->type)) ||
1363 (!exargs && acargs && !IS_VOID(acargs->type)))
1364 werror(E_ARG_COUNT);
1366 /* replace with this defition */
1367 sym->cdef = csym->cdef;
1368 deleteSym (SymbolTab,csym,csym->name);
1369 addSym (SymbolTab,sym,sym->name,sym->level,sym->block);
1370 if (IS_EXTERN(csym->etype) && !
1371 IS_EXTERN(sym->etype))
1372 addSet(&publics,sym);
1376 /*-----------------------------------------------------------------*/
1377 /* processFuncArgs - does some processing with function args */
1378 /*-----------------------------------------------------------------*/
1379 void processFuncArgs (symbol *func, int ignoreName)
1384 /* if this function has variable argument list */
1385 /* then make the function a reentrant one */
1387 SPEC_RENT(func->etype) = 1;
1389 /* check if this function is defined as calleeSaves
1390 then mark it as such */
1391 func->calleeSave = inCalleeSaveList(func->name);
1393 val = func->args; /* loop thru all the arguments */
1395 /* if it is void then remove parameters */
1396 if (val && IS_VOID(val->type)) {
1401 /* if any of the arguments is an aggregate */
1402 /* change it to pointer to the same type */
1405 /* mark it as a register parameter if
1406 the function does nit have VA_ARG
1407 and MAX_REG_PARMS not exceeded &&
1408 not inhibited by command line option or #pragma */
1409 if (pNum <= MAX_REG_PARMS &&
1410 !options.noregparms &&
1412 SPEC_REGPARM(val->etype) = 1;
1414 if ( IS_AGGREGATE(val->type)) {
1415 /* if this is a structure */
1416 /* then we need to add a new link */
1417 if (IS_STRUCT(val->type)) {
1418 /* first lets add DECLARATOR type */
1419 link *p = val->type ;
1421 werror(W_STRUCT_AS_ARG,val->name);
1422 val->type = newLink();
1423 val->type->next = p ;
1426 /* change to a pointer depending on the */
1427 /* storage class specified */
1428 switch (SPEC_SCLS(val->etype)) {
1430 DCL_TYPE(val->type) = IPOINTER;
1433 DCL_TYPE(val->type) = PPOINTER;
1439 DCL_TYPE(val->type) = POINTER ;
1442 DCL_TYPE(val->type) = CPOINTER;
1445 DCL_TYPE(val->type) = FPOINTER;
1448 DCL_TYPE(val->type) = FLPOINTER;
1451 DCL_TYPE(val->type) = GPOINTER;
1454 /* is there is a symbol associated then */
1455 /* change the type of the symbol as well*/
1457 val->sym->type = copyLinkChain(val->type);
1458 val->sym->etype = getSpec(val->sym->type);
1466 /* if this function is reentrant or */
1467 /* automatics r 2b stacked then nothing */
1468 if (IS_RENT(func->etype) || options.stackAuto )
1475 /* if a symbolname is not given */
1476 /* synthesize a variable name */
1479 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1480 val->sym = newSymbol(val->name,1);
1481 SPEC_OCLS(val->etype) = (options.model ? xdata : data);
1482 val->sym->type = copyLinkChain (val->type);
1483 val->sym->etype = getSpec (val->sym->type);
1484 val->sym->_isparm = 1;
1485 strcpy (val->sym->rname,val->name);
1486 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1487 SPEC_STAT(func->etype);
1488 addSymChain(val->sym);
1491 else /* symbol name given create synth name */ {
1493 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1494 strcpy (val->sym->rname,val->name);
1495 val->sym->_isparm = 1;
1496 SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) =
1497 (options.model ? xdata : data);
1498 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1499 SPEC_STAT(func->etype);
1505 /*-----------------------------------------------------------------*/
1506 /* isSymbolEqual - compares two symbols return 1 if they match */
1507 /*-----------------------------------------------------------------*/
1508 int isSymbolEqual (symbol *dest, symbol *src)
1510 /* if pointers match then equal */
1514 /* if one of them is null then don't match */
1518 /* if both of them have rname match on rname */
1519 if (dest->rname[0] && src->rname[0])
1520 return (!strcmp(dest->rname,src->rname));
1522 /* otherwise match on name */
1523 return (!strcmp(dest->name,src->name));
1526 /*-----------------------------------------------------------------*/
1527 /* printTypeChain - prints the type chain in human readable form */
1528 /*-----------------------------------------------------------------*/
1529 void printTypeChain (link *type, FILE *of)
1539 if (IS_DECL(type)) {
1540 switch (DCL_TYPE(type)) {
1542 fprintf (of,"function ");
1545 fprintf (of,"_generic * ");
1546 if (DCL_PTR_CONST(type))
1547 fprintf(of,"const ");
1550 fprintf (of,"_code * ");
1551 if (DCL_PTR_CONST(type))
1552 fprintf(of,"const ");
1555 fprintf (of,"_far * ");
1556 if (DCL_PTR_CONST(type))
1557 fprintf(of,"const ");
1560 fprintf (of,"_flash * ");
1561 if (DCL_PTR_CONST(type))
1562 fprintf(of,"const ");
1566 fprintf (of,"_near * ");
1567 if (DCL_PTR_CONST(type))
1568 fprintf(of,"const ");
1571 fprintf (of,"_idata *");
1572 if (DCL_PTR_CONST(type))
1573 fprintf(of,"const ");
1576 fprintf (of,"_pdata *");
1577 if (DCL_PTR_CONST(type))
1578 fprintf(of,"const ");
1581 fprintf (of," _unkown *");
1582 if (DCL_PTR_CONST(type))
1583 fprintf(of,"const ");
1587 fprintf (of,"array of ");
1591 if (SPEC_VOLATILE(type))
1592 fprintf (of,"volatile ");
1593 if (SPEC_USIGN(type))
1594 fprintf (of,"unsigned ");
1596 switch (SPEC_NOUN(type)) {
1599 fprintf (of,"long ");
1602 fprintf (of,"short ");
1604 fprintf (of,"int ");
1608 fprintf(of,"char ");
1612 fprintf(of,"void ");
1616 fprintf(of,"float ");
1620 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1624 fprintf(of,"sbit ");
1628 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1638 /*-----------------------------------------------------------------*/
1639 /* cdbTypeInfo - print the type information for debugger */
1640 /*-----------------------------------------------------------------*/
1641 void cdbTypeInfo (link *type,FILE *of)
1643 fprintf(of,"{%d}",getSize(type));
1645 if (IS_DECL(type)) {
1646 switch (DCL_TYPE(type)) {
1672 fprintf (of,"DA%d,",DCL_ELEM(type));
1676 switch (SPEC_NOUN(type)) {
1700 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1708 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1712 if (SPEC_USIGN(type))
1720 /*-----------------------------------------------------------------*/
1721 /* cdbSymbol - prints a symbol & its type information for debugger */
1722 /*-----------------------------------------------------------------*/
1723 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1735 fprintf(of,"S:"); /* symbol record */
1736 /* if this is not a structure symbol then
1737 we need to figure out the scope information */
1741 if (IS_STATIC(sym->etype))
1742 fprintf(of,"F%s$",moduleName); /* scope is file */
1744 fprintf(of,"G$"); /* scope is global */
1747 /* symbol is local */
1748 fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1750 fprintf(of,"S$"); /* scope is structure */
1752 /* print the name, & mangled name */
1753 fprintf(of,"%s$%d$%d(",sym->name,
1754 sym->level,sym->block);
1756 cdbTypeInfo(sym->type,of);
1759 /* print the address space */
1760 map = SPEC_OCLS(sym->etype);
1761 fprintf(of,"%c,%d,%d",
1762 (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1764 /* if assigned to registers then output register names */
1765 /* if this is a function then print
1766 if is it an interrupt routine & interrupt number
1767 and the register bank it is using */
1769 fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1770 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1771 /* alternate location to find this symbol @ : eg registers
1778 /*-----------------------------------------------------------------*/
1779 /* cdbStruct - print a structure for debugger */
1780 /*-----------------------------------------------------------------*/
1781 void cdbStruct ( structdef *sdef,int block,FILE *of,
1782 int inStruct, char *tag)
1787 /* if block # then must have function scope */
1788 fprintf(of,"F%s$",moduleName);
1789 fprintf(of,"%s[",(tag ? tag : sdef->tag));
1790 for (sym=sdef->fields ; sym ; sym = sym->next) {
1791 fprintf(of,"({%d}",sym->offset);
1792 cdbSymbol(sym,of,TRUE,FALSE);
1800 /*------------------------------------------------------------------*/
1801 /* cdbStructBlock - calls struct printing for a blcks */
1802 /*------------------------------------------------------------------*/
1803 void cdbStructBlock (int block , FILE *of)
1806 bucket **table = StructTab;
1809 /* go thru the entire table */
1810 for ( i = 0 ; i < 256; i++ ) {
1811 for ( chain = table[i]; chain ; chain = chain->next ) {
1812 if (chain->block >= block) {
1813 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1819 /*-----------------------------------------------------------------*/
1820 /* powof2 - returns power of two for the number if number is pow 2 */
1821 /*-----------------------------------------------------------------*/
1822 int powof2 (unsigned long num)
1828 if (num & 1) n1s++ ;
1833 if (n1s > 1 || nshifts == 0) return 0;
1834 return nshifts - 1 ;
1880 /*-----------------------------------------------------------------*/
1881 /* initCSupport - create functions for C support routines */
1882 /*-----------------------------------------------------------------*/
1883 void initCSupport ()
1885 charType = newCharLink();
1886 intType = newIntLink();
1887 floatType= newFloatLink();
1888 longType = newLongLink();
1889 ucharType = copyLinkChain(charType);
1890 SPEC_USIGN(ucharType) = 1;
1891 ulongType = copyLinkChain(longType);
1892 SPEC_USIGN(ulongType) = 1;
1893 uintType = copyLinkChain(intType);
1894 SPEC_USIGN(uintType) = 1;
1897 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1898 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1899 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1900 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1901 __fseq = funcOfType ("__fseq", charType, floatType, 2, options.float_rent);
1902 __fsneq = funcOfType ("__fsneq", charType, floatType, 2, options.float_rent);
1903 __fslt = funcOfType ("__fslt", charType, floatType, 2, options.float_rent);
1904 __fslteq= funcOfType ("__fslteq", charType, floatType, 2, options.float_rent);
1905 __fsgt = funcOfType ("__fsgt", charType, floatType, 2, options.float_rent);
1906 __fsgteq= funcOfType ("__fsgteq", charType, floatType, 2, options.float_rent);
1908 __fs2uchar = funcOfType ("__fs2uchar",ucharType,floatType,1, options.float_rent);
1909 __fs2uint = funcOfType ("__fs2uint",uintType,floatType,1, options.float_rent);
1910 __fs2ulong = funcOfType ("__fs2ulong",ulongType,floatType,1, options.float_rent);
1911 __fs2char = funcOfType ("__fs2char",charType,floatType,1, options.float_rent);
1912 __fs2int = funcOfType ("__fs2int",intType,floatType,1, options.float_rent);
1913 __fs2long = funcOfType ("__fs2long",longType,floatType,1, options.float_rent);
1915 __long2fs = funcOfType ("__long2fs",floatType,longType,1, options.float_rent);
1916 __ulong2fs = funcOfType ("__ulong2fs",floatType,ulongType,1, options.float_rent);
1917 __int2fs = funcOfType ("__int2fs",floatType,intType,1, options.float_rent);
1918 __uint2fs = funcOfType ("__uint2fs",floatType,uintType,1, options.float_rent);
1919 __char2fs = funcOfType ("__char2fs",floatType,charType,1, options.float_rent);
1920 __uchar2fs = funcOfType ("__uchar2fs",floatType,ucharType,1, options.float_rent);
1922 __muluint = funcOfType ("_muluint",uintType,uintType,2,options.intlong_rent);
1923 __mulsint = funcOfType ("_mulsint",intType,intType,2,options.intlong_rent);
1924 __divuint = funcOfType ("_divuint",uintType,uintType,2,options.intlong_rent);
1925 __divsint = funcOfType ("_divsint",intType,intType,2,options.intlong_rent);
1926 __moduint = funcOfType ("_moduint",uintType,uintType,2,options.intlong_rent);
1927 __modsint = funcOfType ("_modsint",intType,intType,2,options.intlong_rent);
1929 __mululong = funcOfType ("_mululong",ulongType,ulongType,2,options.intlong_rent);
1930 __mulslong = funcOfType ("_mulslong",longType,longType,2,options.intlong_rent);
1931 __divulong = funcOfType ("_divulong",ulongType,ulongType,2,options.intlong_rent);
1932 __divslong = funcOfType ("_divslong",longType,longType,2,options.intlong_rent);
1933 __modulong = funcOfType ("_modulong",ulongType,ulongType,2,options.intlong_rent);
1934 __modslong = funcOfType ("_modslong",longType,longType,2,options.intlong_rent);