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) = port->mem.code_ro;
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 ;
935 SPEC_CONST(sym->etype) = 1;
938 /* global variable in code space is a constant */
939 if (sym->level == 0 &&
940 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 port->mem.code_ro &&
1009 !IS_EXTERN(sym->etype))
1010 werror(E_CODE_NO_INIT,sym->name);
1012 /* if parameter or local variable then change */
1013 /* the storage class to reflect where the var will go */
1014 if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) {
1015 if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype)))
1016 SPEC_SCLS(sym->etype) = (options.useXstack ?
1017 S_XSTACK : S_STACK ) ;
1019 SPEC_SCLS(sym->etype) = (options.useXstack ?
1024 /*------------------------------------------------------------------*/
1025 /* changePointer - change pointer to functions */
1026 /*------------------------------------------------------------------*/
1027 void changePointer (symbol *sym)
1031 /* go thru the chain of declarations */
1032 /* if we find a pointer to a function */
1033 /* unconditionally change it to a ptr */
1035 for ( p = sym->type ; p ; p = p->next) {
1036 if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER)
1037 DCL_TYPE(p) = GPOINTER ;
1038 if ( IS_PTR(p) && IS_FUNC(p->next))
1039 DCL_TYPE(p) = CPOINTER ;
1043 /*------------------------------------------------------------------*/
1044 /* checkDecl - does semantic validation of a declaration */
1045 /*------------------------------------------------------------------*/
1046 int checkDecl ( symbol *sym )
1049 checkSClass (sym); /* check the storage class */
1050 changePointer(sym); /* change pointers if required */
1052 /* if this is an array without any dimension
1053 then update the dimension from the initial value */
1054 if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type))
1055 DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival);
1060 /*------------------------------------------------------------------*/
1061 /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */
1062 /*------------------------------------------------------------------*/
1063 link *copyLinkChain ( link *p)
1065 link *head, *curr , *loop;
1068 head = loop = ( curr ? newLink() : (void *) NULL) ;
1070 memcpy(loop,curr,sizeof(link)) ; /* copy it */
1071 loop->next = (curr->next ? newLink() : (void *) NULL) ;
1080 /*------------------------------------------------------------------*/
1081 /* cleanUpBlock - cleansup the symbol table specified for all the */
1082 /* symbols in the given block */
1083 /*------------------------------------------------------------------*/
1084 void cleanUpBlock ( bucket **table, int block)
1089 /* go thru the entire table */
1090 for ( i = 0 ; i < 256; i++ ) {
1091 for ( chain = table[i]; chain ; chain = chain->next ) {
1092 if (chain->block >= block) {
1093 deleteSym (table,chain->sym,chain->name);
1099 /*------------------------------------------------------------------*/
1100 /* cleanUpLevel - cleansup the symbol table specified for all the */
1101 /* symbols in the given level */
1102 /*------------------------------------------------------------------*/
1103 void cleanUpLevel (bucket **table, int level )
1108 /* go thru the entire table */
1109 for ( i = 0 ; i < 256; i++ ) {
1110 for ( chain = table[i]; chain ; chain = chain->next ) {
1111 if (chain->level >= level) {
1112 deleteSym (table,chain->sym,chain->name);
1118 /*------------------------------------------------------------------*/
1119 /* computeType - computes the resultant type from two types */
1120 /*------------------------------------------------------------------*/
1121 link *computeType ( link *type1, link *type2)
1125 link *etype1 = getSpec(type1);
1126 link *etype2 = getSpec(type2);
1128 /* if one of them is a float then result is a float */
1129 /* here we assume that the types passed are okay */
1130 /* and can be cast to one another */
1131 /* which ever is greater in size */
1132 if (IS_FLOAT(etype1) || IS_FLOAT(etype2))
1133 rType = newFloatLink();
1135 /* if only one of them is a bit variable
1136 then the other one prevails */
1137 if (IS_BITVAR(etype1) && !IS_BITVAR(etype2))
1138 rType = copyLinkChain(type2);
1140 if (IS_BITVAR(etype2) && !IS_BITVAR(etype1))
1141 rType = copyLinkChain(type1);
1143 /* if one of them is a pointer then that
1146 rType = copyLinkChain(type1);
1149 rType = copyLinkChain(type2);
1151 if (getSize (type1) > getSize(type2) )
1152 rType = copyLinkChain(type1);
1154 rType = copyLinkChain(type2);
1156 reType = getSpec(rType);
1158 /* if either of them unsigned then make this unsigned */
1159 if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType))
1160 SPEC_USIGN(reType) = 1;
1162 /* if result is a literal then make not so */
1163 if (IS_LITERAL(reType))
1164 SPEC_SCLS(reType) = S_REGISTER ;
1169 /*------------------------------------------------------------------*/
1170 /* checkType - will do type check return 1 if match */
1171 /*------------------------------------------------------------------*/
1172 int checkType ( link *dest, link *src )
1183 /* if dest is a declarator then */
1184 if (IS_DECL(dest)) {
1186 if (DCL_TYPE(src) == DCL_TYPE(dest))
1187 return checkType(dest->next,src->next);
1189 if (IS_PTR(src) && IS_PTR(dest))
1192 if (IS_PTR(dest) && IS_ARRAY(src))
1195 if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src))
1196 return -1 * checkType (dest->next,src) ;
1201 if (IS_PTR(dest) && IS_INTEGRAL(src))
1207 /* if one of them is a void then ok */
1208 if (SPEC_NOUN(dest) == V_VOID &&
1209 SPEC_NOUN(src) != V_VOID )
1212 if (SPEC_NOUN(dest) != V_VOID &&
1213 SPEC_NOUN(src) == V_VOID )
1216 /* char === to short */
1217 if (SPEC_NOUN(dest) == V_CHAR &&
1218 SPEC_NOUN(src) == V_INT &&
1220 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1222 if (SPEC_NOUN(src) == V_CHAR &&
1223 SPEC_NOUN(dest) == V_INT &&
1225 return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2);
1227 /* if they are both bitfields then if the lengths
1228 and starts don't match */
1229 if (IS_BITFIELD(dest) && IS_BITFIELD(src) &&
1230 (SPEC_BLEN(dest) != SPEC_BLEN(src) ||
1231 SPEC_BSTR(dest) != SPEC_BSTR(src)))
1234 /* it is a specifier */
1235 if (SPEC_NOUN(dest) != SPEC_NOUN(src)) {
1236 if (SPEC_USIGN(dest) == SPEC_USIGN(src) &&
1237 IS_INTEGRAL(dest) && IS_INTEGRAL(src) &&
1238 getSize(dest) == getSize(src))
1241 if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src))
1247 if (IS_STRUCT(dest)) {
1248 if (SPEC_STRUCT(dest) != SPEC_STRUCT(src))
1253 if (SPEC_LONG(dest) != SPEC_LONG(src))
1256 if (SPEC_SHORT(dest) != SPEC_SHORT(src))
1259 if (SPEC_USIGN(dest) != SPEC_USIGN(src))
1265 /*------------------------------------------------------------------*/
1266 /* inCalleeSaveList - return 1 if found in calle save list */
1267 /*------------------------------------------------------------------*/
1268 bool inCalleeSaveList ( char *s)
1272 for (i = 0 ; options.calleeSaves[i] ; i++ )
1273 if (strcmp(options.calleeSaves[i],s) == 0)
1279 /*------------------------------------------------------------------*/
1280 /* checkFunction - does all kinds of check on a function */
1281 /*------------------------------------------------------------------*/
1282 int checkFunction (symbol *sym)
1285 value *exargs, *acargs ;
1288 /* if not type then some kind of error */
1292 /* if the function has no type then make it return int */
1293 if ( !sym->type->next )
1294 sym->type->next = sym->etype = newIntLink();
1296 /* function cannot return aggregate */
1297 if (IS_AGGREGATE(sym->type->next)) {
1298 werror(E_FUNC_AGGR,sym->name);
1302 /* function cannot return bit */
1303 if (IS_BITVAR(sym->type->next)) {
1304 werror(E_FUNC_BIT,sym->name);
1308 /* check if this function is defined as calleeSaves
1309 then mark it as such */
1310 sym->calleeSave = inCalleeSaveList(sym->name);
1312 /* if interrupt service routine */
1313 /* then it cannot have arguments */
1314 if ( sym->args && IS_ISR(sym->etype) && !IS_VOID(sym->args->type)) {
1315 werror(E_INT_ARGS,sym->name);
1319 if (!(csym = findSym (SymbolTab, sym, sym->name )))
1320 return 1 ; /* not defined nothing more to check */
1322 /* check if body already present */
1323 if ( csym && csym->fbody ) {
1324 werror(E_FUNC_BODY,sym->name);
1328 /* check the return value type */
1329 if (checkType (csym->type,sym->type) <= 0) {
1330 werror(E_PREV_DEF_CONFLICT,csym->name,"type") ;
1331 werror (E_CONTINUE,"previous defintion type ");
1332 printTypeChain(csym->type,stderr);fprintf(stderr,"\n");
1333 werror (E_CONTINUE,"current definition type ");
1334 printTypeChain(sym->type,stderr);fprintf(stderr,"\n");
1338 if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) {
1339 werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt");
1343 if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) {
1344 werror (E_PREV_DEF_CONFLICT,csym->name,"using");
1348 /* compare expected agrs with actual args */
1349 exargs = csym->args ;
1350 acargs = sym->args ;
1352 /* for all the expected args do */
1355 exargs = exargs->next, acargs = acargs->next, argCnt++ ) {
1356 if ( checkType(exargs->type,acargs->type) <= 0) {
1357 werror(E_ARG_TYPE,argCnt);
1362 /* if one them ended we have a problem */
1363 if ((exargs && !acargs && !IS_VOID(exargs->type)) ||
1364 (!exargs && acargs && !IS_VOID(acargs->type)))
1365 werror(E_ARG_COUNT);
1367 /* replace with this defition */
1368 sym->cdef = csym->cdef;
1369 deleteSym (SymbolTab,csym,csym->name);
1370 addSym (SymbolTab,sym,sym->name,sym->level,sym->block);
1371 if (IS_EXTERN(csym->etype) && !
1372 IS_EXTERN(sym->etype))
1373 addSet(&publics,sym);
1377 /*-----------------------------------------------------------------*/
1378 /* processFuncArgs - does some processing with function args */
1379 /*-----------------------------------------------------------------*/
1380 void processFuncArgs (symbol *func, int ignoreName)
1386 /* if this function has variable argument list */
1387 /* then make the function a reentrant one */
1389 SPEC_RENT(func->etype) = 1;
1391 /* check if this function is defined as calleeSaves
1392 then mark it as such */
1393 func->calleeSave = inCalleeSaveList(func->name);
1395 val = func->args; /* loop thru all the arguments */
1397 /* if it is void then remove parameters */
1398 if (val && IS_VOID(val->type)) {
1403 /* reset regparm for the port */
1404 (*port->reset_regparms)();
1405 /* if any of the arguments is an aggregate */
1406 /* change it to pointer to the same type */
1409 /* mark it as a register parameter if
1410 the function does not have VA_ARG
1411 and as port dictates
1412 not inhibited by command line option or #pragma */
1413 if (!func->hasVargs &&
1414 !options.noregparms &&
1415 (*port->reg_parm)(val->type)) {
1417 SPEC_REGPARM(val->etype) = 1;
1420 if ( IS_AGGREGATE(val->type)) {
1421 /* if this is a structure */
1422 /* then we need to add a new link */
1423 if (IS_STRUCT(val->type)) {
1424 /* first lets add DECLARATOR type */
1425 link *p = val->type ;
1427 werror(W_STRUCT_AS_ARG,val->name);
1428 val->type = newLink();
1429 val->type->next = p ;
1432 /* change to a pointer depending on the */
1433 /* storage class specified */
1434 switch (SPEC_SCLS(val->etype)) {
1436 DCL_TYPE(val->type) = IPOINTER;
1439 DCL_TYPE(val->type) = PPOINTER;
1445 DCL_TYPE(val->type) = POINTER ;
1448 DCL_TYPE(val->type) = CPOINTER;
1451 DCL_TYPE(val->type) = FPOINTER;
1454 DCL_TYPE(val->type) = EEPPOINTER;
1457 DCL_TYPE(val->type) = GPOINTER;
1460 /* is there is a symbol associated then */
1461 /* change the type of the symbol as well*/
1463 val->sym->type = copyLinkChain(val->type);
1464 val->sym->etype = getSpec(val->sym->type);
1472 /* if this function is reentrant or */
1473 /* automatics r 2b stacked then nothing */
1474 if (IS_RENT(func->etype) || options.stackAuto )
1481 /* if a symbolname is not given */
1482 /* synthesize a variable name */
1485 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1486 val->sym = newSymbol(val->name,1);
1487 SPEC_OCLS(val->etype) = (options.model ? xdata : data);
1488 val->sym->type = copyLinkChain (val->type);
1489 val->sym->etype = getSpec (val->sym->type);
1490 val->sym->_isparm = 1;
1491 strcpy (val->sym->rname,val->name);
1492 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1493 SPEC_STAT(func->etype);
1494 addSymChain(val->sym);
1497 else /* symbol name given create synth name */ {
1499 sprintf(val->name,"_%s_PARM_%d",func->name,pNum++);
1500 strcpy (val->sym->rname,val->name);
1501 val->sym->_isparm = 1;
1502 SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) =
1503 (options.model ? xdata : data);
1504 SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) =
1505 SPEC_STAT(func->etype);
1511 /*-----------------------------------------------------------------*/
1512 /* isSymbolEqual - compares two symbols return 1 if they match */
1513 /*-----------------------------------------------------------------*/
1514 int isSymbolEqual (symbol *dest, symbol *src)
1516 /* if pointers match then equal */
1520 /* if one of them is null then don't match */
1524 /* if both of them have rname match on rname */
1525 if (dest->rname[0] && src->rname[0])
1526 return (!strcmp(dest->rname,src->rname));
1528 /* otherwise match on name */
1529 return (!strcmp(dest->name,src->name));
1532 /*-----------------------------------------------------------------*/
1533 /* printTypeChain - prints the type chain in human readable form */
1534 /*-----------------------------------------------------------------*/
1535 void printTypeChain (link *type, FILE *of)
1545 if (IS_DECL(type)) {
1546 switch (DCL_TYPE(type)) {
1548 fprintf (of,"function ");
1551 fprintf (of,"_generic * ");
1552 if (DCL_PTR_CONST(type))
1553 fprintf(of,"const ");
1556 fprintf (of,"_code * ");
1557 if (DCL_PTR_CONST(type))
1558 fprintf(of,"const ");
1561 fprintf (of,"_far * ");
1562 if (DCL_PTR_CONST(type))
1563 fprintf(of,"const ");
1566 fprintf (of,"_eeprom * ");
1567 if (DCL_PTR_CONST(type))
1568 fprintf(of,"const ");
1572 fprintf (of,"_near * ");
1573 if (DCL_PTR_CONST(type))
1574 fprintf(of,"const ");
1577 fprintf (of,"_idata *");
1578 if (DCL_PTR_CONST(type))
1579 fprintf(of,"const ");
1582 fprintf (of,"_pdata *");
1583 if (DCL_PTR_CONST(type))
1584 fprintf(of,"const ");
1587 fprintf (of," _unkown *");
1588 if (DCL_PTR_CONST(type))
1589 fprintf(of,"const ");
1593 fprintf (of,"array of ");
1597 if (SPEC_VOLATILE(type))
1598 fprintf (of,"volatile ");
1599 if (SPEC_USIGN(type))
1600 fprintf (of,"unsigned ");
1602 switch (SPEC_NOUN(type)) {
1605 fprintf (of,"long ");
1608 fprintf (of,"short ");
1610 fprintf (of,"int ");
1614 fprintf(of,"char ");
1618 fprintf(of,"void ");
1622 fprintf(of,"float ");
1626 fprintf(of,"struct %s",SPEC_STRUCT(type)->tag);
1630 fprintf(of,"sbit ");
1634 fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type));
1647 /*-----------------------------------------------------------------*/
1648 /* cdbTypeInfo - print the type information for debugger */
1649 /*-----------------------------------------------------------------*/
1650 void cdbTypeInfo (link *type,FILE *of)
1652 fprintf(of,"{%d}",getSize(type));
1654 if (IS_DECL(type)) {
1655 switch (DCL_TYPE(type)) {
1681 fprintf (of,"DA%d,",DCL_ELEM(type));
1687 switch (SPEC_NOUN(type)) {
1711 fprintf(of,"ST%s",SPEC_STRUCT(type)->tag);
1719 fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type));
1726 if (SPEC_USIGN(type))
1734 /*-----------------------------------------------------------------*/
1735 /* cdbSymbol - prints a symbol & its type information for debugger */
1736 /*-----------------------------------------------------------------*/
1737 void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc)
1749 fprintf(of,"S:"); /* symbol record */
1750 /* if this is not a structure symbol then
1751 we need to figure out the scope information */
1755 if (IS_STATIC(sym->etype))
1756 fprintf(of,"F%s$",moduleName); /* scope is file */
1758 fprintf(of,"G$"); /* scope is global */
1761 /* symbol is local */
1762 fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
1764 fprintf(of,"S$"); /* scope is structure */
1766 /* print the name, & mangled name */
1767 fprintf(of,"%s$%d$%d(",sym->name,
1768 sym->level,sym->block);
1770 cdbTypeInfo(sym->type,of);
1773 /* print the address space */
1774 map = SPEC_OCLS(sym->etype);
1775 fprintf(of,"%c,%d,%d",
1776 (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype));
1778 /* if assigned to registers then output register names */
1779 /* if this is a function then print
1780 if is it an interrupt routine & interrupt number
1781 and the register bank it is using */
1783 fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype),
1784 SPEC_INTN(sym->etype),SPEC_BANK(sym->etype));
1785 /* alternate location to find this symbol @ : eg registers
1792 /*-----------------------------------------------------------------*/
1793 /* cdbStruct - print a structure for debugger */
1794 /*-----------------------------------------------------------------*/
1795 void cdbStruct ( structdef *sdef,int block,FILE *of,
1796 int inStruct, char *tag)
1801 /* if block # then must have function scope */
1802 fprintf(of,"F%s$",moduleName);
1803 fprintf(of,"%s[",(tag ? tag : sdef->tag));
1804 for (sym=sdef->fields ; sym ; sym = sym->next) {
1805 fprintf(of,"({%d}",sym->offset);
1806 cdbSymbol(sym,of,TRUE,FALSE);
1814 /*------------------------------------------------------------------*/
1815 /* cdbStructBlock - calls struct printing for a blcks */
1816 /*------------------------------------------------------------------*/
1817 void cdbStructBlock (int block , FILE *of)
1820 bucket **table = StructTab;
1823 /* go thru the entire table */
1824 for ( i = 0 ; i < 256; i++ ) {
1825 for ( chain = table[i]; chain ; chain = chain->next ) {
1826 if (chain->block >= block) {
1827 cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL);
1833 /*-----------------------------------------------------------------*/
1834 /* powof2 - returns power of two for the number if number is pow 2 */
1835 /*-----------------------------------------------------------------*/
1836 int powof2 (unsigned long num)
1842 if (num & 1) n1s++ ;
1847 if (n1s > 1 || nshifts == 0) return 0;
1848 return nshifts - 1 ;
1862 /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
1863 symbol *__muldiv[3][3][2];
1864 /* Dims: BYTE/WORD/DWORD SIGNED/UNSIGNED */
1865 link *__multypes[3][2];
1866 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
1867 symbol *__conv[2][3][2];
1871 /*-----------------------------------------------------------------*/
1872 /* initCSupport - create functions for C support routines */
1873 /*-----------------------------------------------------------------*/
1874 void initCSupport ()
1876 const char *smuldivmod[] = {
1879 const char *sbwd[] = {
1880 "char", "int", "long"
1882 const char *ssu[] = {
1886 int bwd, su, muldivmod, tofrom;
1888 floatType= newFloatLink();
1890 for (bwd = 0; bwd < 3; bwd++) {
1905 __multypes[bwd][0] = l;
1906 __multypes[bwd][1] = copyLinkChain(l);
1907 SPEC_USIGN(__multypes[bwd][1]) = 1;
1910 __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent);
1911 __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent);
1912 __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent);
1913 __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent);
1914 __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent);
1915 __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent);
1916 __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent);
1917 __fslteq= funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent);
1918 __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent);
1919 __fsgteq= funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent);
1921 for (tofrom = 0; tofrom < 2; tofrom++) {
1922 for (bwd = 0; bwd < 3; bwd++) {
1923 for (su = 0; su < 2; su++) {
1925 sprintf(buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
1926 __conv[tofrom][bwd][su] = funcOfType(buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
1929 sprintf(buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
1930 __conv[tofrom][bwd][su] = funcOfType(buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
1936 for (muldivmod = 0; muldivmod < 3; muldivmod++) {
1937 for (bwd = 0; bwd < 3; bwd++) {
1938 for (su = 0; su < 2; su++) {
1939 sprintf(buffer, "_%s%s%s",
1940 smuldivmod[muldivmod],
1943 __muldiv[muldivmod][bwd][su] = funcOfType(buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);