Too much opposition against these range checks. It will only work now with --pedantic...
[fw/sdcc] / src / SDCCval.c
1 /*----------------------------------------------------------------------
2     SDCCval.c :- has routine to do all kinds of fun stuff with the
3                 value wrapper & with initialiser lists.
4
5     Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6
7     This program is free software; you can redistribute it and/or modify it
8     under the terms of the GNU General Public License as published by the
9     Free Software Foundation; either version 2, or (at your option) any
10     later version.
11
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21     In other words, you are welcome to use, share and improve this program.
22     You are forbidden to forbid anyone else to use, share and improve
23     what you give them.   Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
25
26 #include "common.h"
27 #include <math.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include "newalloc.h"
31
32 int cNestLevel;
33
34 /*-----------------------------------------------------------------*/
35 /* newValue - allocates and returns a new value        */
36 /*-----------------------------------------------------------------*/
37 value *
38 newValue ()
39 {
40   value *val;
41
42   val = Safe_calloc (1, sizeof (value));
43
44   return val;
45 }
46
47 /*-----------------------------------------------------------------*/
48 /* newiList - new initializer list                                 */
49 /*-----------------------------------------------------------------*/
50 initList *
51 newiList (int type, void *ilist)
52 {
53   initList *nilist;
54
55
56   nilist = Safe_calloc (1, sizeof (initList));
57
58   nilist->type = type;
59   nilist->lineno = yylineno;
60
61   switch (type)
62     {
63     case INIT_NODE:
64       nilist->init.node = (struct ast *) ilist;
65       break;
66
67     case INIT_DEEP:
68       nilist->init.deep = (struct initList *) ilist;
69       break;
70     }
71
72   return nilist;
73 }
74
75 /*------------------------------------------------------------------*/
76 /* revinit   - reverses the initial values for a value  chain        */
77 /*------------------------------------------------------------------*/
78 initList *
79 revinit (initList * val)
80 {
81   initList *prev, *curr, *next;
82
83   if (!val)
84     return NULL;
85
86   prev = val;
87   curr = val->next;
88
89   while (curr)
90     {
91       next = curr->next;
92       curr->next = prev;
93       prev = curr;
94       curr = next;
95     }
96   val->next = (void *) NULL;
97   return prev;
98 }
99
100 bool
101 convertIListToConstList(initList *src, literalList **lList)
102 {
103     initList    *iLoop;
104     literalList *head, *last, *newL;
105     
106     head = last = NULL;
107     
108     if (!src || src->type != INIT_DEEP)
109     {
110         return FALSE;
111     }
112     
113     iLoop =  src->init.deep;
114     
115     while (iLoop)
116     {
117         if (iLoop->type != INIT_NODE)
118         {
119             return FALSE;
120         }
121         
122         if (!IS_AST_LIT_VALUE(decorateType(resolveSymbols(iLoop->init.node))))
123         {
124             return FALSE;
125         }
126         iLoop = iLoop->next;
127     }
128     
129     // We've now established that the initializer list contains only literal values.
130     
131     iLoop = src->init.deep;
132     while (iLoop)
133     {
134         double val = AST_LIT_VALUE(iLoop->init.node);
135         
136         if (last && last->literalValue == val)
137         {
138             last->count++;
139         }
140         else
141         {
142             newL = Safe_malloc(sizeof(literalList));
143             newL->literalValue = val;
144             newL->count = 1;
145             newL->next = NULL;
146             
147             if (last)
148             {
149                 last->next = newL;
150             }
151             else
152             {
153                 head = newL;
154             }
155             last = newL;
156         }
157         iLoop = iLoop->next;
158     }
159     
160     if (!head)    
161     {
162         return FALSE;
163     }
164     
165     *lList = head;
166     return TRUE;
167 }
168
169 literalList *
170 copyLiteralList(literalList *src)
171 {
172     literalList *head, *prev, *newL;
173     
174     head = prev = NULL;
175     
176     while (src)
177     {
178         newL = Safe_malloc(sizeof(literalList));
179         
180         newL->literalValue = src->literalValue;
181         newL->count = src->count;
182         newL->next = NULL;
183         
184         if (prev)
185         {
186             prev->next = newL;
187         }
188         else
189         {
190             head = newL;
191         }
192         prev = newL;
193         src = src->next;
194     }
195     
196     return head;
197 }
198
199
200
201 /*------------------------------------------------------------------*/
202 /* copyIlist - copy initializer list            */
203 /*------------------------------------------------------------------*/
204 initList *
205 copyIlist (initList * src)
206 {
207   initList *dest = NULL;
208
209   if (!src)
210     return NULL;
211
212   switch (src->type)
213     {
214     case INIT_DEEP:
215       dest = newiList (INIT_DEEP, copyIlist (src->init.deep));
216       break;
217     case INIT_NODE:
218       dest = newiList (INIT_NODE, copyAst (src->init.node));
219       break;
220     }
221
222   if (src->next)
223     dest->next = copyIlist (src->next);
224
225   return dest;
226 }
227
228 /*------------------------------------------------------------------*/
229 /* list2int - converts the first element of the list to value       */
230 /*------------------------------------------------------------------*/
231 double 
232 list2int (initList * val)
233 {
234   initList *i = val;
235
236   if (i->type == INIT_DEEP)
237     return list2int (val->init.deep);
238
239   return floatFromVal (constExprValue (val->init.node, TRUE));
240 }
241
242 /*------------------------------------------------------------------*/
243 /* list2val - converts the first element of the list to value       */
244 /*------------------------------------------------------------------*/
245 value *
246 list2val (initList * val)
247 {
248   if (!val)
249     return NULL;
250
251   if (val->type == INIT_DEEP)
252     return list2val (val->init.deep);
253
254   return constExprValue (val->init.node, TRUE);
255 }
256
257 /*------------------------------------------------------------------*/
258 /* list2expr - returns the first expression in the initializer list */
259 /*------------------------------------------------------------------*/
260 ast *
261 list2expr (initList * ilist)
262 {
263   if (ilist->type == INIT_DEEP)
264     return list2expr (ilist->init.deep);
265   return ilist->init.node;
266 }
267
268 /*------------------------------------------------------------------*/
269 /* resolveIvalSym - resolve symbols in initial values               */
270 /*------------------------------------------------------------------*/
271 void 
272 resolveIvalSym (initList * ilist)
273 {
274   if (!ilist)
275     return;
276
277   if (ilist->type == INIT_NODE)
278     ilist->init.node = decorateType (resolveSymbols (ilist->init.node));
279
280   if (ilist->type == INIT_DEEP)
281     resolveIvalSym (ilist->init.deep);
282
283   resolveIvalSym (ilist->next);
284 }
285
286 /*-----------------------------------------------------------------*/
287 /* symbolVal - creates a value for a symbol              */
288 /*-----------------------------------------------------------------*/
289 value *
290 symbolVal (symbol * sym)
291 {
292   value *val;
293
294   if (!sym)
295     return NULL;
296
297   val = newValue ();
298   val->sym = sym;
299
300   if (sym->type)
301     {
302       val->type = sym->type;
303       val->etype = getSpec (val->type);
304     }
305
306   if (*sym->rname)
307     sprintf (val->name, "%s", sym->rname);
308   else
309     sprintf (val->name, "_%s", sym->name);
310
311
312   return val;
313 }
314
315 /*-----------------------------------------------------------------*/
316 /* valueFromLit - creates a value from a literal                   */
317 /*-----------------------------------------------------------------*/
318 value *
319 valueFromLit (double lit)
320 {
321   char buffer[50];
322
323   if ((((long) lit) - lit) == 0)
324     {
325       sprintf (buffer, "%ld", (long) lit);
326       return constVal (buffer);
327     }
328
329   sprintf (buffer, "%f", lit);
330   return constFloatVal (buffer);
331 }
332
333 /*-----------------------------------------------------------------*/
334 /* constFloatVal - converts a FLOAT constant to value              */
335 /*-----------------------------------------------------------------*/
336 value *
337 constFloatVal (char *s)
338 {
339   value *val = newValue ();
340   float sval;
341
342   if (sscanf (s, "%f", &sval) != 1)
343     {
344       werror (E_INVALID_FLOAT_CONST, s);
345       return constVal ("0");
346     }
347
348   val->type = val->etype = newLink ();
349   val->type->class = SPECIFIER;
350   SPEC_NOUN (val->type) = V_FLOAT;
351   SPEC_SCLS (val->type) = S_LITERAL;
352   SPEC_CVAL (val->type).v_float = sval;
353
354   return val;
355 }
356
357 /*-----------------------------------------------------------------*/
358 /* constVal - converts a INTEGER constant into a value       */
359 /*-----------------------------------------------------------------*/
360 value *
361 constVal (char *s)
362 {
363   value *val;
364   short hex = 0, octal = 0;
365   char scanFmt[10];
366   int scI = 0;
367   unsigned long sval;
368
369   val = newValue ();            /* alloc space for value   */
370
371   val->type = val->etype = newLink ();  /* create the spcifier */
372   val->type->class = SPECIFIER;
373   SPEC_NOUN (val->type) = V_INT;
374   SPEC_SCLS (val->type) = S_LITERAL;
375
376   /* set the _unsigned flag if 'uUoOxX' found */
377   if (strchr (s, 'u') || strchr (s, 'U') ||
378       strchr (s, 'o') || strchr (s, 'O') ||
379       strchr (s, 'x') || strchr (s, 'x'))
380     SPEC_USIGN (val->type) = 1;
381
382   /* set the _long flag if 'lL' is found */
383   if (strchr (s, 'l') || strchr (s, 'L'))
384     SPEC_LONG (val->type) = 1;
385
386   hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0);
387
388   /* set the octal flag   */
389   if (!hex && *s == '0' && *(s + 1))
390     octal = 1;
391
392   /* create the scan string */
393   scanFmt[scI++] = '%';
394
395   if (octal)
396     scanFmt[scI++] = 'o';
397   else if (hex)
398     scanFmt[scI++] = 'x';
399   else if (SPEC_USIGN (val->type))
400     scanFmt[scI++] = 'u';
401   else
402     scanFmt[scI++] = 'd';
403
404   scanFmt[scI++] = '\0';
405
406   /* if hex or octal then set the unsigned flag   */
407   if (hex || octal)
408     {
409       SPEC_USIGN (val->type) = 1;
410       sscanf (s, scanFmt, &sval);
411     }
412   else
413     sval = atol (s);
414
415   // check if we have to promote to long
416   if (SPEC_LONG (val->type) || 
417       (SPEC_USIGN(val->type) && sval>0xffff) ||
418       (!SPEC_USIGN(val->type) && ((long)sval>32767 || (long)sval<-32768))) {
419       if (SPEC_USIGN (val->type))
420         SPEC_CVAL (val->type).v_ulong = sval;
421       else
422         SPEC_CVAL (val->type).v_long = sval;
423       SPEC_LONG (val->type) = 1;
424       return val;
425     }
426   
427   if (SPEC_USIGN (val->type))
428     SPEC_CVAL (val->type).v_uint = sval;
429   else
430     SPEC_CVAL (val->type).v_int = sval;
431   
432   
433   // check if we can make it a char
434   if ((SPEC_USIGN(val->type) && sval < 256) ||
435       (!SPEC_USIGN(val->type) && ((long)sval<127 && (long)sval>-128))) {
436     SPEC_NOUN (val->etype) = V_CHAR;
437   }
438   return val;
439 }
440
441 /*! /fn char hexEscape(char **src)
442
443     /param src Pointer to 'x' from start of hex character value
444 */
445
446 char hexEscape(char **src)
447
448 {
449 char *s ;
450 unsigned long value ;
451
452 (*src)++ ;      /* Skip over the 'x' */
453 s = *src ;      /* Save for error detection */
454
455 value = strtol (*src, src, 16);
456
457 if (s == *src) 
458   {
459   // no valid hex found
460   werror(E_INVALID_HEX);
461   } 
462
463 else 
464   {
465   if (value > 255) 
466     {
467     werror(W_ESC_SEQ_OOR_FOR_CHAR);
468     }
469   }
470
471 return (char) value;
472 }
473 /*------------------------------------------------------------------*/
474 /* octalEscape - process an octal constant of max three digits      */
475 /* return the octal value, throw a warning for illegal octal        */
476 /* adjust src to point at the last proccesed char                   */
477 /*------------------------------------------------------------------*/
478
479 char octalEscape (char **str) {
480   int digits;
481   unsigned value=0;
482
483   for (digits=0; digits<3; digits++) {
484     if (**str>='0' && **str<='7') {
485       value = value*8 + (**str-'0');
486       (*str)++;
487     } else {
488       break;
489     }
490   }
491   if (digits) {
492     if (value > 255 /* || (**str>='0' && **str<='7') */ ) {
493       werror (W_ESC_SEQ_OOR_FOR_CHAR);
494     }
495   }
496   return value;
497 }
498
499 /*! 
500   /fn int copyStr (char *dest, char *src)
501   
502   Copies a source string to a dest buffer interpreting escape sequences
503   and special characters
504
505   /param dest Buffer to receive the resultant string
506   /param src  Buffer containing the source string with escape sequecnes
507   /return Number of characters in output string
508
509 */
510
511 int 
512 copyStr (char *dest, char *src)
513
514 {
515   char *OriginalDest = dest ;
516
517   while (*src)
518     {
519       if (*src == '\"')
520         src++;
521       else if (*src == '\\')
522         {
523           src++;
524           switch (*src)
525             {
526             case 'n':
527               *dest++ = '\n';
528               break;
529             case 't':
530               *dest++ = '\t';
531               break;
532             case 'v':
533               *dest++ = '\v';
534               break;
535             case 'b':
536               *dest++ = '\b';
537               break;
538             case 'r':
539               *dest++ = '\r';
540               break;
541             case 'f':
542               *dest++ = '\f';
543               break;
544             case 'a':
545               *dest++ = '\a';
546               break;
547
548             case '0':
549             case '1':
550             case '2':
551             case '3':
552             case '4':
553             case '5':
554             case '6':
555             case '7':
556               *dest++ = octalEscape(&src);
557               src-- ;
558               break;
559
560             case 'x': 
561               *dest++ = hexEscape(&src) ;
562               src-- ;
563               break ;
564
565             case '\\':
566               *dest++ = '\\';
567               break;
568             case '\?':
569               *dest++ = '\?';
570               break;
571             case '\'':
572               *dest++ = '\'';
573               break;
574             case '\"':
575               *dest++ = '\"';
576               break;
577             default:
578               *dest++ = *src;
579             }
580           src++;
581         }
582       else
583         *dest++ = *src++;
584     }
585
586   *dest++ = '\0';
587
588   return dest - OriginalDest ;
589 }
590
591 /*------------------------------------------------------------------*/
592 /* strVal - converts a string constant to a value       */
593 /*------------------------------------------------------------------*/
594 value *
595 strVal (char *s)
596 {
597   value *val;
598
599   val = newValue ();            /* get a new one */
600
601   /* get a declarator */
602   val->type = newLink ();
603   DCL_TYPE (val->type) = ARRAY;
604   val->type->next = val->etype = newLink ();
605   val->etype->class = SPECIFIER;
606   SPEC_NOUN (val->etype) = V_CHAR;
607   SPEC_SCLS (val->etype) = S_LITERAL;
608
609   SPEC_CVAL (val->etype).v_char = Safe_calloc (1, strlen (s) + 1);
610   DCL_ELEM (val->type) = copyStr (SPEC_CVAL (val->etype).v_char, s);
611
612   return val;
613 }
614
615
616 /*------------------------------------------------------------------*/
617 /* reverseValWithType - reverses value chain with type & etype      */
618 /*------------------------------------------------------------------*/
619 value *
620 reverseValWithType (value * val)
621 {
622   sym_link *type;
623   sym_link *etype;
624
625   if (!val)
626     return NULL;
627
628   /* save the type * etype chains */
629   type = val->type;
630   etype = val->etype;
631
632   /* set the current one 2b null */
633   val->type = val->etype = NULL;
634   val = reverseVal (val);
635
636   /* restore type & etype */
637   val->type = type;
638   val->etype = etype;
639
640   return val;
641 }
642
643 /*------------------------------------------------------------------*/
644 /* reverseVal - reverses the values for a value  chain        */
645 /*------------------------------------------------------------------*/
646 value *
647 reverseVal (value * val)
648 {
649   value *prev, *curr, *next;
650
651   if (!val)
652     return NULL;
653
654   prev = val;
655   curr = val->next;
656
657   while (curr)
658     {
659       next = curr->next;
660       curr->next = prev;
661       prev = curr;
662       curr = next;
663     }
664   val->next = (void *) NULL;
665   return prev;
666 }
667
668 /*------------------------------------------------------------------*/
669 /* copyValueChain - will copy a chain of values                     */
670 /*------------------------------------------------------------------*/
671 value *
672 copyValueChain (value * src)
673 {
674   value *dest;
675
676   if (!src)
677     return NULL;
678
679   dest = copyValue (src);
680   dest->next = copyValueChain (src->next);
681
682   return dest;
683 }
684
685 /*------------------------------------------------------------------*/
686 /* copyValue - copies contents of a vlue to a fresh one             */
687 /*------------------------------------------------------------------*/
688 value *
689 copyValue (value * src)
690 {
691   value *dest;
692
693   dest = newValue ();
694   dest->sym = copySymbol (src->sym);
695   strcpy (dest->name, src->name);
696   dest->type = (src->type ? copyLinkChain (src->type) : NULL);
697   dest->etype = (src->type ? getSpec (dest->type) : NULL);
698
699   return dest;
700 }
701
702 /*------------------------------------------------------------------*/
703 /* charVal - converts a character constant to a value       */
704 /*------------------------------------------------------------------*/
705 value *
706 charVal (char *s)
707 {
708   value *val;
709 //  unsigned uValue ;
710
711   val = newValue ();
712
713   val->type = val->etype = newLink ();
714   val->type->class = SPECIFIER;
715   SPEC_NOUN (val->type) = V_CHAR;
716   SPEC_USIGN(val->type) = 1;
717   SPEC_SCLS (val->type) = S_LITERAL;
718
719   s++;                          /* get rid of quotation */
720   /* if \ then special processing */
721   if (*s == '\\')
722     {
723       s++;                      /* go beyond the backslash  */
724       switch (*s)
725         {
726         case 'n':
727           SPEC_CVAL (val->type).v_int = '\n';
728           break;
729         case 't':
730           SPEC_CVAL (val->type).v_int = '\t';
731           break;
732         case 'v':
733           SPEC_CVAL (val->type).v_int = '\v';
734           break;
735         case 'b':
736           SPEC_CVAL (val->type).v_int = '\b';
737           break;
738         case 'r':
739           SPEC_CVAL (val->type).v_int = '\r';
740           break;
741         case 'f':
742           SPEC_CVAL (val->type).v_int = '\f';
743           break;
744         case 'a':
745           SPEC_CVAL (val->type).v_int = '\a';
746           break;
747         case '\\':
748           SPEC_CVAL (val->type).v_int = '\\';
749           break;
750         case '\?':
751           SPEC_CVAL (val->type).v_int = '\?';
752           break;
753         case '\'':
754           SPEC_CVAL (val->type).v_int = '\'';
755           break;
756         case '\"':
757           SPEC_CVAL (val->type).v_int = '\"';
758           break;
759
760         case '0' :
761         case '1' :
762         case '2' :
763         case '3' :
764         case '4' :
765         case '5' :
766         case '6' :
767         case '7' :
768           SPEC_CVAL (val->type).v_int = octalEscape(&s);
769           break;
770
771         case 'x':
772           SPEC_CVAL (val->type).v_int = hexEscape(&s) ;
773           break;
774
775         default:
776           SPEC_CVAL (val->type).v_int = *s;
777           break;
778         }
779     }
780   else                          /* not a backslash */
781     SPEC_CVAL (val->type).v_int = *s;
782
783   return val;
784 }
785
786 /*------------------------------------------------------------------*/
787 /* valFromType - creates a value from type given                    */
788 /*------------------------------------------------------------------*/
789 value *
790 valFromType (sym_link * type)
791 {
792   value *val = newValue ();
793   val->type = copyLinkChain (type);
794   val->etype = getSpec (val->type);
795   return val;
796 }
797
798 /*------------------------------------------------------------------*/
799 /* floatFromVal - value to unsinged integer conversion        */
800 /*------------------------------------------------------------------*/
801 double 
802 floatFromVal (value * val)
803 {
804   if (!val)
805     return 0;
806
807   if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL)
808     {
809       werror (E_CONST_EXPECTED, val->name);
810       return 0;
811     }
812
813   /* if it is not a specifier then we can assume that */
814   /* it will be an unsigned long                      */
815   if (!IS_SPEC (val->type))
816     return (double) SPEC_CVAL (val->etype).v_ulong;
817
818   if (SPEC_NOUN (val->etype) == V_FLOAT)
819     return (double) SPEC_CVAL (val->etype).v_float;
820   else
821     {
822       if (SPEC_LONG (val->etype))
823         {
824           if (SPEC_USIGN (val->etype))
825             return (double) SPEC_CVAL (val->etype).v_ulong;
826           else
827             return (double) SPEC_CVAL (val->etype).v_long;
828         }
829       else
830         {
831           if (SPEC_USIGN (val->etype))
832             return (double) SPEC_CVAL (val->etype).v_uint;
833           else
834             return (double) SPEC_CVAL (val->etype).v_int;
835         }
836     }
837 }
838
839
840 /*------------------------------------------------------------------*/
841 /* valUnaryPM - dones the unary +/- operation on a constant         */
842 /*------------------------------------------------------------------*/
843 value *
844 valUnaryPM (value * val)
845 {
846   /* depending on type */
847   if (SPEC_NOUN (val->etype) == V_FLOAT)
848     SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float;
849   else
850     {
851       if (SPEC_LONG (val->etype))
852         {
853           if (SPEC_USIGN (val->etype))
854             SPEC_CVAL (val->etype).v_ulong = 0-SPEC_CVAL (val->etype).v_ulong;
855           else
856             SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long;
857         }
858       else
859         {
860           if (SPEC_USIGN (val->etype))
861             SPEC_CVAL (val->etype).v_uint = 0-SPEC_CVAL (val->etype).v_uint;
862           else
863             SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int;
864         }
865     }
866   return val;
867
868 }
869
870 /*------------------------------------------------------------------*/
871 /* valueComplement - complements a constant                         */
872 /*------------------------------------------------------------------*/
873 value *
874 valComplement (value * val)
875 {
876   /* depending on type */
877   if (SPEC_LONG (val->etype))
878     {
879       if (SPEC_USIGN (val->etype))
880         SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong;
881       else
882         SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long;
883     }
884   else
885     {
886       if (SPEC_USIGN (val->etype))
887         SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint;
888       else
889         SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int;
890     }
891   return val;
892 }
893
894 /*------------------------------------------------------------------*/
895 /* valueNot - complements a constant                                */
896 /*------------------------------------------------------------------*/
897 value *
898 valNot (value * val)
899 {
900   /* depending on type */
901   if (SPEC_LONG (val->etype))
902     {
903       if (SPEC_USIGN (val->etype))
904         SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong;
905       else
906         SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long;
907     }
908   else
909     {
910       if (SPEC_USIGN (val->etype))
911         SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint;
912       else
913         SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int;
914     }
915   return val;
916 }
917
918 /*------------------------------------------------------------------*/
919 /* valMult - multiply constants                                     */
920 /*------------------------------------------------------------------*/
921 value *
922 valMult (value * lval, value * rval)
923 {
924   value *val;
925
926   /* create a new value */
927   val = newValue ();
928   val->type = val->etype = newLink ();
929   val->type->class = SPECIFIER;
930   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
931                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
932   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
933   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
934   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
935
936   if (IS_FLOAT (val->type))
937     SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval);
938   else
939     {
940       if (SPEC_LONG (val->type))
941         {
942           if (SPEC_USIGN (val->type))
943             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) *
944               (unsigned long) floatFromVal (rval);
945           else
946             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) *
947               (long) floatFromVal (rval);
948         }
949       else
950         {
951           if (SPEC_USIGN (val->type))
952             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) *
953               (unsigned) floatFromVal (rval);
954           else
955             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) *
956               (int) floatFromVal (rval);
957         }
958     }
959   return val;
960 }
961
962 /*------------------------------------------------------------------*/
963 /* valDiv  - Divide   constants                                     */
964 /*------------------------------------------------------------------*/
965 value *
966 valDiv (value * lval, value * rval)
967 {
968   value *val;
969
970   if (floatFromVal (rval) == 0)
971     {
972       werror (E_DIVIDE_BY_ZERO);
973       return rval;
974     }
975
976   /* create a new value */
977   val = newValue ();
978   val->type = val->etype = newLink();
979   val->type->class = SPECIFIER;
980   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
981                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
982   SPEC_SCLS (val->etype) = S_LITERAL;
983   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
984   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
985
986   if (IS_FLOAT (val->type))
987     SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval);
988   else
989     {
990       if (SPEC_LONG (val->type))
991         {
992           if (SPEC_USIGN (val->type))
993             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) /
994               (unsigned long) floatFromVal (rval);
995           else
996             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) /
997               (long) floatFromVal (rval);
998         }
999       else
1000         {
1001           if (SPEC_USIGN (val->type)) {
1002             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) /
1003               (unsigned) floatFromVal (rval);
1004             if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1005                 (SPEC_CVAL (val->type).v_uint <=255)) {
1006               SPEC_NOUN (val->type) = V_CHAR;
1007             }
1008           } else {
1009             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) /
1010               (int) floatFromVal (rval);
1011             if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1012                 (SPEC_CVAL (val->type).v_int >=-128) &&
1013                 (SPEC_CVAL (val->type).v_int <=127)) {
1014               SPEC_NOUN (val->type) = V_CHAR;
1015             }
1016           }
1017         }
1018     }
1019   return val;
1020 }
1021
1022 /*------------------------------------------------------------------*/
1023 /* valMod  - Modulus  constants                                     */
1024 /*------------------------------------------------------------------*/
1025 value *
1026 valMod (value * lval, value * rval)
1027 {
1028   value *val;
1029
1030   /* create a new value */
1031   val = newValue ();
1032   val->type = val->etype = newLink ();
1033   val->type->class = SPECIFIER;
1034   SPEC_NOUN (val->type) = V_INT;        /* type is int */
1035   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1036   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1037   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1038
1039   if (SPEC_LONG (val->type))
1040     {
1041       if (SPEC_USIGN (val->type))
1042         SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) %
1043           (unsigned long) floatFromVal (rval);
1044       else
1045         SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) %
1046           (unsigned long) floatFromVal (rval);
1047     }
1048   else
1049     {
1050       if (SPEC_USIGN (val->type)) {
1051         SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) %
1052           (unsigned) floatFromVal (rval);
1053         if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1054             (SPEC_CVAL (val->type).v_uint <=255)) {
1055           SPEC_NOUN (val->type) = V_CHAR;
1056         }
1057       } else {
1058         SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) %
1059           (unsigned) floatFromVal (rval);
1060         if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1061             (SPEC_CVAL (val->type).v_int >=-128) &&
1062             (SPEC_CVAL (val->type).v_int <=127)) {
1063           SPEC_NOUN (val->type) = V_CHAR;
1064         }
1065       }
1066     }
1067
1068   return val;
1069 }
1070
1071 /*------------------------------------------------------------------*/
1072 /* valPlus - Addition constants                                     */
1073 /*------------------------------------------------------------------*/
1074 value *
1075 valPlus (value * lval, value * rval)
1076 {
1077   value *val;
1078
1079   /* create a new value */
1080   val = newValue ();
1081   val->type = val->etype = newLink ();
1082   val->type->class = SPECIFIER;
1083   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1084                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1085   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1086   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1087   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1088
1089   if (IS_FLOAT (val->type))
1090     SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval);
1091   else
1092     {
1093       if (SPEC_LONG (val->type))
1094         {
1095           if (SPEC_USIGN (val->type))
1096             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) +
1097               (unsigned long) floatFromVal (rval);
1098           else
1099             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) +
1100               (long) floatFromVal (rval);
1101         }
1102       else
1103         {
1104           if (SPEC_USIGN (val->type)) {
1105             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) +
1106               (unsigned) floatFromVal (rval);
1107             if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1108                 (SPEC_CVAL (val->type).v_uint <=255)) {
1109               SPEC_NOUN (val->type) = V_CHAR;
1110             }
1111           } else {
1112             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) +
1113               (int) floatFromVal (rval);
1114             if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1115                 (SPEC_CVAL (val->type).v_int >=-128) &&
1116                 (SPEC_CVAL (val->type).v_int <=127)) {
1117               SPEC_NOUN (val->type) = V_CHAR;
1118             }
1119           }
1120         }
1121     }
1122   return val;
1123 }
1124
1125 /*------------------------------------------------------------------*/
1126 /* valMinus - Addition constants                                    */
1127 /*------------------------------------------------------------------*/
1128 value *
1129 valMinus (value * lval, value * rval)
1130 {
1131   value *val;
1132
1133   /* create a new value */
1134   val = newValue ();
1135   val->type = val->etype = newLink ();
1136   val->type->class = SPECIFIER;
1137   SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) ||
1138                            IS_FLOAT (rval->etype) ? V_FLOAT : V_INT);
1139   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1140   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1141   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1142
1143   if (IS_FLOAT (val->type))
1144     SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval);
1145   else
1146     {
1147       if (SPEC_LONG (val->type))
1148         {
1149           if (SPEC_USIGN (val->type)) {
1150             SPEC_CVAL (val->type).v_ulong = 
1151               (unsigned long) floatFromVal (lval) -
1152               (unsigned long) floatFromVal (rval);
1153           } else {
1154             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) -
1155               (long) floatFromVal (rval);
1156           }
1157         }
1158       else
1159         {
1160           if (SPEC_USIGN (val->type)) {
1161             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) -
1162               (unsigned) floatFromVal (rval);
1163             if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1164                 (SPEC_CVAL (val->type).v_uint <=255)) {
1165               SPEC_NOUN (val->type) = V_CHAR;
1166             }
1167           } else {
1168             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - (int) floatFromVal (rval);
1169             if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1170                 (SPEC_CVAL (val->type).v_int >=-128) &&
1171                 (SPEC_CVAL (val->type).v_int <=127)) {
1172               SPEC_NOUN (val->type) = V_CHAR;
1173             }
1174           }
1175         }
1176     }
1177   return val;
1178 }
1179
1180 /*------------------------------------------------------------------*/
1181 /* valShift - Shift left or right                                   */
1182 /*------------------------------------------------------------------*/
1183 value *
1184 valShift (value * lval, value * rval, int lr)
1185 {
1186   value *val;
1187
1188   /* create a new value */
1189   val = newValue ();
1190   val->type = val->etype = newIntLink ();
1191   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1192   SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype));
1193   SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype));
1194
1195   if (SPEC_LONG (val->type))
1196     {
1197       if (SPEC_USIGN (val->type))
1198         SPEC_CVAL (val->type).v_ulong = lr ? 
1199           (unsigned long) floatFromVal (lval) << (unsigned long) floatFromVal (rval) : \
1200           (unsigned long) floatFromVal (lval) >> (unsigned long) floatFromVal (rval);
1201       else
1202         SPEC_CVAL (val->type).v_long = lr ?
1203           (long) floatFromVal (lval) << (long) floatFromVal (rval) : \
1204           (long) floatFromVal (lval) >> (long) floatFromVal (rval);
1205     }
1206   else
1207     {
1208       if (SPEC_USIGN (val->type)) {
1209         SPEC_CVAL (val->type).v_uint = lr ? 
1210           (unsigned) floatFromVal (lval) << (unsigned) floatFromVal (rval) :\
1211           (unsigned) floatFromVal (lval) >> (unsigned) floatFromVal (rval);
1212         if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1213             (SPEC_CVAL (val->type).v_uint <=255)) {
1214           SPEC_NOUN (val->type) = V_CHAR;
1215         }
1216       } else {
1217         SPEC_CVAL (val->type).v_int = lr ?
1218           (int) floatFromVal (lval) << (int) floatFromVal (rval) : \
1219           (int) floatFromVal (lval) >> (int) floatFromVal (rval);
1220         if (/* IS_CHAR (lval->etype) && IS_CHAR (rval->etype) && */
1221             (SPEC_CVAL (val->type).v_int >=-128) &&
1222             (SPEC_CVAL (val->type).v_int <=127)) {
1223           SPEC_NOUN (val->type) = V_CHAR;
1224         }
1225       }
1226     }
1227
1228   return val;
1229 }
1230
1231 /*------------------------------------------------------------------*/
1232 /* valCompare- Compares two literal                                 */
1233 /*------------------------------------------------------------------*/
1234 value *
1235 valCompare (value * lval, value * rval, int ctype)
1236 {
1237   value *val;
1238
1239   /* create a new value */
1240   val = newValue ();
1241   val->type = val->etype = newCharLink ();
1242   val->type->class = SPECIFIER;
1243   SPEC_NOUN (val->type) = V_INT;        /* type is int */
1244   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1245
1246   switch (ctype)
1247     {
1248     case '<':
1249       SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
1250       break;
1251
1252     case '>':
1253       SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
1254       break;
1255
1256     case LE_OP:
1257       SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
1258       break;
1259
1260     case GE_OP:
1261       SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
1262       break;
1263
1264     case EQ_OP:
1265       SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
1266       break;
1267
1268     case NE_OP:
1269       SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
1270       break;
1271
1272     }
1273
1274   return val;
1275 }
1276
1277 /*------------------------------------------------------------------*/
1278 /* valBitwise - Bitwise operation                                   */
1279 /*------------------------------------------------------------------*/
1280 value *
1281 valBitwise (value * lval, value * rval, int op)
1282 {
1283   value *val;
1284
1285   /* create a new value */
1286   val = newValue ();
1287   val->type = copyLinkChain (lval->type);
1288   val->etype = getSpec (val->type);
1289
1290   switch (op)
1291     {
1292     case '&':
1293       if (SPEC_LONG (val->type))
1294         {
1295           if (SPEC_USIGN (val->type))
1296             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) &
1297               (unsigned long) floatFromVal (rval);
1298           else
1299             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) &
1300               (long) floatFromVal (rval);
1301         }
1302       else
1303         {
1304           if (SPEC_USIGN (val->type))
1305             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) &
1306               (unsigned) floatFromVal (rval);
1307           else
1308             SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval);
1309         }
1310       break;
1311
1312     case '|':
1313       if (SPEC_LONG (val->type))
1314         {
1315           if (SPEC_USIGN (val->type))
1316             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) |
1317               (unsigned long) floatFromVal (rval);
1318           else
1319             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) |
1320               (long) floatFromVal (rval);
1321         }
1322       else
1323         {
1324           if (SPEC_USIGN (val->type))
1325             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) |
1326               (unsigned) floatFromVal (rval);
1327           else
1328             SPEC_CVAL (val->type).v_int =
1329               (int) floatFromVal (lval) | (int) floatFromVal (rval);
1330         }
1331
1332       break;
1333
1334     case '^':
1335       if (SPEC_LONG (val->type))
1336         {
1337           if (SPEC_USIGN (val->type))
1338             SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^
1339               (unsigned long) floatFromVal (rval);
1340           else
1341             SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^
1342               (long) floatFromVal (rval);
1343         }
1344       else
1345         {
1346           if (SPEC_USIGN (val->type))
1347             SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^
1348               (unsigned) floatFromVal (rval);
1349           else
1350             SPEC_CVAL (val->type).v_int =
1351               (int) floatFromVal (lval) ^ (int) floatFromVal (rval);
1352         }
1353       break;
1354     }
1355
1356   return val;
1357 }
1358
1359 /*------------------------------------------------------------------*/
1360 /* valAndOr   - Generates code for and / or operation               */
1361 /*------------------------------------------------------------------*/
1362 value *
1363 valLogicAndOr (value * lval, value * rval, int op)
1364 {
1365   value *val;
1366
1367   /* create a new value */
1368   val = newValue ();
1369   val->type = val->etype = newCharLink ();
1370   val->type->class = SPECIFIER;
1371   SPEC_SCLS (val->type) = S_LITERAL;    /* will remain literal */
1372
1373   switch (op)
1374     {
1375     case AND_OP:
1376       SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval);
1377       break;
1378
1379     case OR_OP:
1380       SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval);
1381       break;
1382     }
1383
1384
1385   return val;
1386 }
1387
1388 /*------------------------------------------------------------------*/
1389 /* valCastLiteral - casts a literal value to another type           */
1390 /*------------------------------------------------------------------*/
1391 value *
1392 valCastLiteral (sym_link * dtype, double fval)
1393 {
1394   value *val;
1395
1396   if (!dtype)
1397     return NULL;
1398
1399   val = newValue ();
1400   val->etype = getSpec (val->type = copyLinkChain (dtype));
1401   SPEC_SCLS (val->etype) = S_LITERAL;
1402   /* if it is not a specifier then we can assume that */
1403   /* it will be an unsigned long                      */
1404   if (!IS_SPEC (val->type))
1405     {
1406       SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1407       return val;
1408     }
1409
1410   if (SPEC_NOUN (val->etype) == V_FLOAT)
1411     SPEC_CVAL (val->etype).v_float = fval;
1412   else
1413     {
1414       if (SPEC_LONG (val->etype))
1415         {
1416           if (SPEC_USIGN (val->etype))
1417             SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval;
1418           else
1419             SPEC_CVAL (val->etype).v_long = (long) fval;
1420         }
1421       else
1422         {
1423           if (SPEC_USIGN (val->etype))
1424             SPEC_CVAL (val->etype).v_uint = (unsigned int) fval;
1425           else
1426             SPEC_CVAL (val->etype).v_int = (int) fval;
1427         }
1428     }
1429   return val;
1430 }
1431
1432 /*------------------------------------------------------------------*/
1433 /* getNelements - determines # of elements from init list           */
1434 /*------------------------------------------------------------------*/
1435 int 
1436 getNelements (sym_link * type, initList * ilist)
1437 {
1438   sym_link *etype = getSpec (type);
1439   int i;
1440
1441   if (!ilist)
1442     return 0;
1443
1444   if (ilist->type == INIT_DEEP)
1445     ilist = ilist->init.deep;
1446
1447   /* if type is a character array and there is only one
1448      (string) initialiser then get the length of the string */
1449   if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next)
1450     {
1451       ast *iast = ilist->init.node;
1452       value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL);
1453       if (!v)
1454         {
1455           werror (W_INIT_WRONG);
1456           return 0;
1457         }
1458
1459       if (IS_ARRAY (v->type) && IS_CHAR (v->etype))
1460         // yep, it's a string
1461         {
1462           return DCL_ELEM (v->type);
1463         }
1464     }
1465
1466   i = 0;
1467   while (ilist)
1468     {
1469       i++;
1470       ilist = ilist->next;
1471     }
1472
1473   return i;
1474 }
1475
1476 /*-----------------------------------------------------------------*/
1477 /* valForArray - returns a value with name of array index          */
1478 /*-----------------------------------------------------------------*/
1479 value *
1480 valForArray (ast * arrExpr)
1481 {
1482   value *val, *lval = NULL;
1483   char buffer[128];
1484   int size = getSize (arrExpr->left->ftype->next);
1485   /* if the right or left is an array
1486      resolve it first */
1487   if (IS_AST_OP (arrExpr->left))
1488     {
1489       if (arrExpr->left->opval.op == '[')
1490         lval = valForArray (arrExpr->left);
1491       else if (arrExpr->left->opval.op == '.')
1492         lval = valForStructElem (arrExpr->left->left,
1493                                  arrExpr->left->right);
1494       else if (arrExpr->left->opval.op == PTR_OP &&
1495                IS_ADDRESS_OF_OP (arrExpr->left->left))
1496         lval = valForStructElem (arrExpr->left->left->left,
1497                                  arrExpr->left->right);
1498       else
1499         return NULL;
1500
1501     }
1502   else if (!IS_AST_SYM_VALUE (arrExpr->left))
1503     return NULL;
1504
1505   if (!IS_AST_LIT_VALUE (arrExpr->right))
1506     return NULL;
1507
1508   val = newValue ();
1509   if (!lval)
1510     sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname);
1511   else
1512     sprintf (buffer, "%s", lval->name);
1513
1514   sprintf (val->name, "(%s + %d)", buffer,
1515            (int) AST_LIT_VALUE (arrExpr->right) * size);
1516
1517   val->type = newLink ();
1518   if (SPEC_SCLS (arrExpr->left->etype) == S_CODE)
1519     {
1520       DCL_TYPE (val->type) = CPOINTER;
1521       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1522     }
1523   else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA)
1524     DCL_TYPE (val->type) = FPOINTER;
1525   else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK)
1526     DCL_TYPE (val->type) = PPOINTER;
1527   else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA)
1528     DCL_TYPE (val->type) = IPOINTER;
1529   else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM)
1530     DCL_TYPE (val->type) = EEPPOINTER;
1531   else
1532     DCL_TYPE (val->type) = POINTER;
1533   val->type->next = arrExpr->left->ftype;
1534   val->etype = getSpec (val->type);
1535   return val;
1536 }
1537
1538 /*-----------------------------------------------------------------*/
1539 /* valForStructElem - returns value with name of struct element    */
1540 /*-----------------------------------------------------------------*/
1541 value *
1542 valForStructElem (ast * structT, ast * elemT)
1543 {
1544   value *val, *lval = NULL;
1545   char buffer[128];
1546   symbol *sym;
1547
1548   /* left could be furthur derefed */
1549   if (IS_AST_OP (structT))
1550     {
1551       if (structT->opval.op == '[')
1552         lval = valForArray (structT);
1553       else if (structT->opval.op == '.')
1554         lval = valForStructElem (structT->left, structT->right);
1555       else if (structT->opval.op == PTR_OP &&
1556                IS_ADDRESS_OF_OP (structT->left))
1557         lval = valForStructElem (structT->left->left,
1558                                  structT->right);
1559       else
1560         return NULL;
1561     }
1562
1563   if (!IS_AST_SYM_VALUE (elemT))
1564     return NULL;
1565
1566   if (!IS_STRUCT (structT->etype))
1567     return NULL;
1568
1569   if ((sym = getStructElement (SPEC_STRUCT (structT->etype),
1570                                AST_SYMBOL (elemT))) == NULL)
1571     {
1572       return NULL;
1573     }
1574
1575   val = newValue ();
1576   if (!lval)
1577     sprintf (buffer, "%s", AST_SYMBOL (structT)->rname);
1578   else
1579     sprintf (buffer, "%s", lval->name);
1580
1581   sprintf (val->name, "(%s + %d)", buffer,
1582            (int) sym->offset);
1583
1584   val->type = newLink ();
1585   if (SPEC_SCLS (structT->etype) == S_CODE)
1586     {
1587       DCL_TYPE (val->type) = CPOINTER;
1588       DCL_PTR_CONST (val->type) = port->mem.code_ro;
1589     }
1590   else if (SPEC_SCLS (structT->etype) == S_XDATA)
1591     DCL_TYPE (val->type) = FPOINTER;
1592   else if (SPEC_SCLS (structT->etype) == S_XSTACK)
1593     DCL_TYPE (val->type) = PPOINTER;
1594   else if (SPEC_SCLS (structT->etype) == S_IDATA)
1595     DCL_TYPE (val->type) = IPOINTER;
1596   else if (SPEC_SCLS (structT->etype) == S_EEPROM)
1597     DCL_TYPE (val->type) = EEPPOINTER;
1598   else
1599     DCL_TYPE (val->type) = POINTER;
1600   val->type->next = sym->type;
1601   val->etype = getSpec (val->type);
1602   return val;
1603 }
1604
1605 /*-----------------------------------------------------------------*/
1606 /* valForCastAggr - will return value for a cast of an aggregate   */
1607 /*                  plus minus a constant                          */
1608 /*-----------------------------------------------------------------*/
1609 value *
1610 valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op)
1611 {
1612   value *val;
1613
1614   if (!IS_AST_SYM_VALUE (aexpr))
1615     return NULL;
1616   if (!IS_AST_LIT_VALUE (cnst))
1617     return NULL;
1618
1619   val = newValue ();
1620
1621   sprintf (val->name, "(%s %c %d)",
1622            AST_SYMBOL (aexpr)->rname, op,
1623            getSize (type->next) * (int) AST_LIT_VALUE (cnst));
1624
1625   val->type = type;
1626   val->etype = getSpec (val->type);
1627   return val;
1628 }
1629
1630 /*-----------------------------------------------------------------*/
1631 /* valForCastAggr - will return value for a cast of an aggregate   */
1632 /*                  with no constant                               */
1633 /*-----------------------------------------------------------------*/
1634 value *
1635 valForCastArr (ast * aexpr, sym_link * type)
1636 {
1637   value *val;
1638
1639   if (!IS_AST_SYM_VALUE (aexpr))
1640     return NULL;
1641
1642   val = newValue ();
1643
1644   sprintf (val->name, "(%s)",
1645            AST_SYMBOL (aexpr)->rname);
1646
1647   val->type = type;
1648   val->etype = getSpec (val->type);
1649   return val;
1650 }